Open jtwang7 opened 3 years ago
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>雪花飘路特效</title> </head> <body> <canvas id="catkins"></canvas> <script src="./index.js"></script> </body> </html>
// ./index.js function rand(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } class Catkins { constructor(x, y) { this.x = x; this.y = y; // 飘动加速度 this.acceleration = rand(this.OPT.acceleration[0], this.OPT.acceleration[1]); // 颜色 this.color = this.OPT.randColor ? rand(0, 255) + "," + rand(0, 255) + "," + rand(0, 255) : this.OPT.color; // 透明度 this.opacity = Math.random(); // 方向 this.direction = this.getDirection(); // 粒子半径 this.radius = rand(this.OPT.radius[0], this.OPT.radius[1]); } OPT = { selector: "#catkins", // <canvas> 的 id amount: 10, // 粒子数量 speed: 0.1, // pixels per frame color: "rgb(255, 255, 255)", // 粒子颜色 randColor: false, // 是否随机颜色 acceleration: [2, 100], // 加速度范围 radius: [1, 2], // 粒子半径范围 }; // 随机初始粒子移动方向 getDirection() { return { x: Math.random(), y: Math.random(), } } // 移动粒子,结合 requestAnimation 实现移动效果 go() { this.x += this.OPT.speed * this.direction.x * this.acceleration / 2; this.y += this.OPT.speed * this.direction.y * this.acceleration / 2; } } class CatkinsCanvas extends Catkins { // 画布对象 ctx = null; // 点数组 store = []; // 创建画布 createCanvas() { let node = document.querySelector(this.OPT.selector); this.ctx = node.getContext("2d"); window.addEventListener('resize', function () { this.setCanvasSize(); }) } // 设置画布大小 setCanvasSize() { try { if (this.ctx) { this.ctx.canvas.width = window.innerWidth; this.ctx.canvas.height = window.innerHeight; } else { throw new Error('canvas 对象不存在') } } catch (err) { console.log(err); } } // 添加粒子 addCatkins() { let x = rand(-200, window.innerWidth + 200); let y = 0 this.store.push(new Catkins(x, y)); } draw() { // 清除画布 this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height) this.store.forEach((item, i, array) => { // 若粒子飘出可视范围,则从数组中移除 if (Math.abs(item.x) > this.ctx.canvas.width || (Math.abs(item.y) > this.ctx.canvas.height)) { array.splice(i, 1); } else { this.drawCircle(item); } }); window.requestAnimationFrame(() => this.draw()); } // 绘制粒子 drawCircle(item) { item.go(); this.ctx.beginPath(); this.ctx.arc(item.x, item.y, this.radius, 0, 2 * Math.PI, false); this.ctx.fillStyle = this.color; this.ctx.fill(); } // 开启动画 init() { this.createCanvas(); this.setCanvasSize(); // 画布背景 this.ctx.fillStyle = 'rgba(0, 0, 0, 0)'; this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height); // 添加粒子 window.setInterval(() => { if (this.store.length < this.OPT.amount) { this.addCatkins(); } }, 1000 / this.OPT.amount); window.requestAnimationFrame(() => this.draw()); // 开启第一次动画帧 } } export default CatkinsCanvas;
基于 canvas 的雪花飘落效果
代码