老师 这里的circlie[i].y的取值有点看不懂

来源:9-3 完成案例动画部分

吾怯二日

2020-07-25 18:27:55

HTML


<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>canvas绘制明信片</title>

<link rel="stylesheet" href="./cs/index.css">

</head>

<body>


<div class="container">


<div class="userInfo">

<div class="line">

<input type="text" id="username"  placeholder="姓名">

</div>

<div class="line">

<input type="text" id="address" placeholder="地址">

</div>

<div class="line">

<input type="text" id="job" placeholder="职业">

</div>

<div class="line">

<input type="text" id="slogan"  placeholder="口号">

</div>

<div class="line">

<button id="btn">生成名片</button>

</div>

</div>


<div class="userCard">

<canvas id="cardCanvas" style="display: none;">

您的浏览器不支持canvas

</canvas>

<canvas id="animCanvas">

您的浏览器不支持canvas

</canvas>

</div>


</div>

<script type="text/javascript" src="./js/index.js"></script>

</body>

</html>


CSS


 

* {


margin: 0;

padding: 0;


}

body,html {

overflow-x: hidden;

overflow-y: hidden;

min-width:1100px;


}


.container {

width: 80%;

height: 400px;

margin:0 auto;

margin-top: 140px;

}


.userInfo {


width: 30%;

height: 300px;

float: left;

background: #a4a296;


}


.userInfo .line {


margin-top: 20px;

text-align: center;


}


.userInfo .line input {


display: block;

height: 30px;

width: 80%;

margin: 0 auto;

border-radius: 15px;

text-indent: 10px;

border: none;

outline: none;


}


.line:first-child{


margin-top: 40px;


}


.line button {

display: block;

width: 100px;

height: 30px;

line-height: 30px;

outline: none;

border: none;

border-radius: 15px;

background: #222;

color: #ddd;

margin: 0 auto;

margin-top: 20px;

position: relative;


}


.line button:hover {


cursor: pointer;

left: 1px;

top: 1px;

}


.line button:active {


left: 1px;

top: 1px;

}


.userCard {


width: 70%;

height: 300px;

float: left;

background: #eee9d3;

position: relative;


}


.userCard #animCanvas {

height: 100px;

position: absolute;

top:80px;

left: 50%;

margin-left: -300px;


}


JS



//alert(1);

var cardCanvas = document.getElementById("cardCanvas"),

cardContext = cardCanvas.getContext("2d");


cardCanvas.width = 600;

cardCanvas.height = 100;




var myImg = new Image();

myImg.src = "./img/logo.png";

myImg.onload = function(){


cardContext.drawImage(myImg,10,10);


}


var btn = document.getElementById("btn");



btn.onclick = function(){


cardContext.clearRect(0,0,600,100);


//背景渐变

var linearGradient = cardContext.createLinearGradient(0,0,600,100);

linearGradient.addColorStop(0.5,"rgb(0,0,0)");

linearGradient.addColorStop(1,"rgb(133,133,133)");

cardContext.fillStyle = linearGradient;

cardContext.fillRect(0,0,600,100);


//logo绘制

cardContext.drawImage(myImg,10,10);


var name = document.getElementById("username").value || "请输入姓名";

var address = document.getElementById("address").value || "请输入地址";

var job = document.getElementById("job").value || "请输入工作";


//获取三条信息文字的长度  得到最长的长度 以确定口面口号的位置

var nameWidth,addressWidth,jobWidth,maxWidth=0;


cardContext.font = "bold 30px sans-serif";

cardContext.fillStyle = "#fff";

cardContext.fillText(name,105,35);

nameWidth = cardContext.measureText(name).width;

cardContext.font = "bold 20px sans-serif";

cardContext.fillText(address,105,60);

addressWidth = cardContext.measureText(address).width;

cardContext.fillText(job,105,85);

jobWidth = cardContext.measureText(job).width;


//获取最长信息的文字宽度


if(maxWidth<nameWidth){


maxWidth = nameWidth;

}


if(maxWidth<addressWidth){


maxWidth = addressWidth;

}


if(maxWidth<jobWidth){


maxWidth = jobWidth;


}


//绘制口号


var slogan = document.getElementById("slogan").value || "请输入口号";


cardContext.save();

//图形变换

cardContext.rotate(-0.1);

cardContext.translate(0,50);


// 阴影

  cardContext.shadowOffsetX = 10;

  cardContext.shadowOffsetY = 10;

  cardContext.shadowColor = 'rgba(0, 0, 0, 0.5)';

  cardContext.shadowBlur = 1.5;

  cardContext.fillStyle = "#ddd";


  //计算口号位置

  var sloganWidth;

  sloganWidth = cardContext.measureText(slogan).width;

  var offset = ( cardContext.canvas.width - 115 - maxWidth - sloganWidth)/2;

  var sloganX = 115 + maxWidth + offset;

  cardContext.fillText( slogan , sloganX , 50 );


  //绘制曲线

  cardContext.beginPath();

  cardContext.moveTo(sloganX , 70);

  cardContext.quadraticCurveTo( sloganX , 50 , sloganX + sloganWidth ,60);

  cardContext.strokeStyle = "#ffffff";

  cardContext.stroke();

  cardContext.restore();


}


btn.click(); 




/*

思路


一共同时填充10个圆 这些圆的半径范围1-5 Math.floor(Math.random()*5)+1 


通过循环 给circle 添加这10个对象  


在第一次循环中 添加了10个对象 我们需要在单个对象绘制到animCanvas底部时重新绘制一个新的圆


所以 依据circle中是否存在要绘制的单个对象来判断是否重制这个圆 或者只是增加它的Y坐标值达到动画效果



初始不存在 创建这个对象 所以if中判断的是这个对象是否存在 


如果存在 进行if后的语句  通过vx递增它的绘制圆心Y值 


如果其绘制点Y方向值大于animCanvas的height+圆的直径(同样为了使圆自然的滑出animCanvas画布) 设置其值为undefined/null


重新在绘制该索引对应的圆



为了达到单个圆自然的进出animCanva 它真实的运动范围是一个animCanvas宽+圆半径*2  animCanvas高+圆半径*2 的矩形


创建单个圆对象的过程


通过循环  为其添加 绘制点X坐标值 Y坐标值 半径值 达到动画效果的Vx递增值


*/

//获取animCanvas 动画绘制的canvas


var animCanvas = document.getElementById("animCanvas"),

animContext = animCanvas.getContext("2d");

animCanvas.width = 600;

animCanvas.height = 100;




var circle = [];//用来存放所有绘制的动态圆


setInterval(function(){


animContext.clearRect(0,0,animCanvas.width,animCanvas.height);

animContext.drawImage(cardCanvas,0,0,animCanvas.width,animCanvas.height,0,0,cardCanvas.width,cardCanvas.height);


for(let i=0;i<=10;i++){


if(!circle[i]){

circle[i] = {};

circle[i].r = Math.floor(Math.random()*5) + 1;//半径取值范围1-5

circle[i].x = 60*i + Math.floor(Math.random()*10) - 5;

circle[i].y = -circle[i].r - Math.floor(Math.random()*10);//circle[i].y = -circle[i].r;

circle[i].vx = Math.floor(Math.random()*5) + 1;//圆递y方向递增取值范围1-5

}

//console.log(circle[i]);

animContext.beginPath();

animContext.arc(circle[i].x, circle[i].y, circle[i].r, 0, Math.PI*2, true);

animContext.fillStyle = "rgba(255,255,255,0.5)";

animContext.fill();

circle[i].y = circle[i].y + circle[i].vx;

if(circle[i].y > animCanvas.height + circle[i].r*2){

circle[i] = null;

}

}

},100)




问题: 这里关于circle[i].y的取值 好像只要是小于-5的任意值都可以 或者是-圆半径也可以  老师这里写的是什么意思呢 距离写的这么远是为什么呀

http://img.mukewang.com/climg/5f1c089c0998227207920321.jpg

写回答

1回答

好帮手慕慕子

2020-07-26

同学你好,同学的想法直接设置circle[i].y = -circle[i].r也是可以实现效果的,老师这种写法是为了单独计算一个随机数,距离写的稍微远一点,方便更加容易看到效果。

同学重点是了解下实现思路就可以了,实际开始用在结合实际应用场景灵活运用所学知识就可以了。

祝学习愉快~

0

0 学习 · 6815 问题

查看课程