近期在学习Canvas的相关知识,偶然想起,在之前的校招面试过程中,面试官有让我手写过雪花飘落的代码。参考了网上的代码(见最下方源码),自己理解了一下~
雪花创建的过程和雪花飘动的过程,让我想起之前同事聊到关于canvas绘制的问题。
1.避免重复绘制
按钮—点击花瓣
按钮会被多次点击,一次点击假设会生成40个花瓣,连续多次点击,页面花瓣生成数量就会变得很多,同事引入一个回收机制,当生成的花瓣生命值为0的时候,将其初始位置再次随机,控制页面的花瓣数量不会超过100个。
首页-花瓣
2.控制方向
如上方的gif示意,想要模拟被风吹下的效果,要控制方向,同事将横坐标和纵坐标分别设置加速度,纵向的加速度较大于横坐标,使其成抛物线运动即可。
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>雪花飘落</title>
</head>
<body>
<canvas id="cvsSnow">
This device is not support Canvas.
</canvas>
</body>
<script>
let cvSN = document.getElementById("cvsSnow");
let snCtx = cvSN.getContext('2d');
let snW = window.innerWidth, snH = window.innerHeight;
cvSN.width = snW;
cvSN.height = snH;
let snNum = 100;
let snRadius = [];
for(let i = 0; i < snNum; i++) {
snRadius.push({
x: Math.random() * snW,
y: Math.random() * snH,
r: Math.random() * 7
});
}
function DrawSnow(){
snCtx.clearRect(0, 0, snW, snH);
snCtx.beginPath();
for(let i = 0; i < snNum; i++){
let p = snRadius[i];
snCtx.moveTo(p.x, p.y);
// context.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
// x/y——圆弧横/纵坐标,radius——圆弧半径,startAngle/endAngle——开始/结束弧度(2π为完整圆),anticlockwise——顺时针逆时针
snCtx.arc(p.x, p.y, p.r, 0, 2 * Math.PI, false);
snCtx.fillStyle = "pink";
}
snCtx.fill();
snCtx.stroke();
SnowFall();
snCtx.closePath();
}
// 雪花飘落
function SnowFall(){
for(let i = 0; i < snNum; i++){
let p = snRadius[i];
p.y += Math.random() * 50 + 1;
if(p.y > snH){
p.y = 0;
}
p.x += Math.random() * 50 + 1;
if(p.x > snW){
p.x = 0;
}
}
}
setInterval(DrawSnow, 100);
</script>
</html>










网友评论