需求: 用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視屏效果,可下載觀看
感謝閱讀