需求: 用canvas实现一个简易的雪花飘落的效果
思路: 利用视觉短暂停留的原理,通过requestAnimationFrame() 每秒60次刷新屏幕,每次刷新都改变雪花的位置,从而构成雪花在移动的 错觉
上代码!
HTML
<canvas id="canvas" width="100" height="100"></canvas>
JS
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
let dots = [];
let snowsLen = 100
canvas.style.width = window.innerWidth;
canvas.style.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 初始化100个雪花
(function getDot(){
for(let i = 0; i < snowsLen; i++) {
dots.push({
x: Math.random()*canvas.width,
y: 0,
r: 5,
speedX: ~~(Math.random()*2) == 0 ? Math.random()*1.5 : -(Math.random()*1.5),
speedY: Math.random()*1.5,
add: false
})
}
})()
// 增加一个雪花
function addSnow() {
dots.push({
x: Math.random()*canvas.width,
y: 0,
r: 5,
speedX: ~~(Math.random()*2) == 0 ? Math.random()*1.5 : -(Math.random()*1.5),
speedY: Math.random()*1.5,
add: false
})
}
function animate(){
function tick(){
// 拖尾效果
// ctx.fillStyle = 'rgba(0,0,0,.1)';
// ctx.fillRect(0, 0, canvas.width, canvas.height)
// 无拖尾效果
ctx.clearRect(0, 0, canvas.width, canvas.height);
dots.forEach((e, i) => { // 雪花的位置变化
e.x = e.y >= canvas.height ? e.x : e.x + e.speedX;
e.y = e.y >= canvas.height ? canvas.height : e.y + e.speedY;
if(e.y >= canvas.height && !e.add) { //当一个雪花落地就新增一个雪花
e.add = true
addSnow()
} else if (e.x >= canvas.width) {
e.x = Math.random()*canvas.width
}
})
dots.forEach(e => {
ctx.beginPath();
ctx.arc(e.x, e.y, e.r, 0, Math.PI * 2);
ctx.fillStyle = '#eee';
ctx.fill();
ctx.closePath();
})
requestAnimationFrame(tick); // 浏览器重绘前继续执行动画
}
requestAnimationFrame(tick); // 浏览器重绘时执行
}
animate();
github地址:https://github.com/PZYYY/snow_fall,内附mp4视屏效果,可下载观看
感谢阅读