| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /**
- * 爆破动画
- */
- 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);
- }
- }
- }
|