/** * 爆破动画 */ import { generateSimilarColors } from "../base/utils"; /** * 爆破微粒 */ class Particle { ctx: CanvasRenderingContext2D; x: number; y: number; r: number; dx: number; dy: number; color: string; a: number; /** * * @param ctx * @param x 初始坐标x * @param y 初始坐标y * @param r 颗粒大小半径 * @param dx 每帧移动x坐标距离 * @param dy 每帧移动y坐标距离 * @param color 颜色 */ constructor(ctx: CanvasRenderingContext2D, x: number, y: number, r: number, dx: number, dy: number, color: string) { this.x = x; this.y = y; this.r = r; this.dx = dx; this.dy = dy; this.color = color; this.a = 1; this.ctx = ctx; } draw() { let ctx = this.ctx; ctx.save(); ctx.globalAlpha = this.a; ctx.fillStyle = this.color; ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false); ctx.fill(); ctx.restore(); } update() { this.draw(); this.a -= 1 / 120; this.x += this.dx; this.y += this.dy; } } export default class Explosion { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D; onend: Function; particles: Particle[] = []; constructor(canvas: HTMLCanvasElement, color: string, particleNum: number, onend: Function) { this.canvas = canvas; this.canvas.width = Math.floor(this.canvas.offsetWidth * window.devicePixelRatio); this.canvas.height = Math.floor(this.canvas.offsetHeight * window.devicePixelRatio); this.ctx = this.canvas.getContext("2d")!; this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.initParticles(color, particleNum); this.onend = onend; } /** * 用requestAnimationFrame试试==>果然效果好多了,而且在低端机上效果明显 */ explode() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.particles.forEach((particle, i) => { if (particle.a <= 0) { this.particles.splice(i, 1); } else { particle.update(); } }) if (this.particles.length == 0) { this.onend && this.onend(); return; } requestAnimationFrame(this.explode.bind(this)); } private initParticles(color: string, particleNum: number) { let colors = generateSimilarColors(color, particleNum); for (let i = 0; i < particleNum; i++) { let x = this.canvas.width / 2 + (Math.random() - 0.5) * (Math.random() * 10); let y = this.canvas.height / 2 + (Math.random() - 0.5) * (Math.random() * 10); let r = (Math.floor(Math.random() * 4) + 1) * window.devicePixelRatio; let dx = (Math.random() - 0.5) * (Math.random() * 8) * window.devicePixelRatio; let dy = (Math.random() - 0.5) * (Math.random() * 6) * window.devicePixelRatio; let c = colors[i]; let particle = new Particle(this.ctx, x, y, r, dx, dy, c); this.particles.push(particle); } } }