用canvas實現簡易的雪花飄落效果

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

感謝閱讀

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章