返回

用 Canvas 绽放烟花,燃爆新年气氛!

前端

在这个年味渐浓的时刻,即使城市的街道上少了烟花爆竹的喧嚣,但科技让我们足不出户就能欣赏到一场绚烂的烟花盛宴。借助 Canvas 的魔力,我们将在网页上点燃一束束虚拟烟花,让新年气氛瞬间嗨翻天!

烟花,一场视觉的盛宴

烟花,承载着人们对新年的祝福和期盼,在夜空中绽放出夺目的光彩。而 Canvas,作为 HTML5 中强大的绘图工具,可以完美再现烟花的绚烂。通过巧妙运用粒子系统和动画技术,我们可以模拟烟花的上升、爆炸以及拖尾效果,营造出令人叹为观止的视觉盛宴。

两种拖尾效果,点亮夜空

为了让烟花更加逼真,我们将实现两种拖尾效果:

  • 闪光拖尾: 模拟烟花上升时的闪亮尾迹,为夜空增添灵动的气息。
  • 烟雾拖尾: 重现烟花爆炸后的烟雾弥漫效果,让烟花更加丰满真实。

步骤详解,逐一拆解

要实现烟花效果,我们将其拆解为两个阶段:

1. 烟花上升过程

在这一阶段,我们将使用 Canvas 绘制一条曲线,模拟烟花从发射点上升的过程。曲线的起点为发射点,终点为烟花爆炸的位置。

2. 烟花爆炸过程

当烟花上升到某个点时,它将爆炸并产生粒子效果。我们将使用粒子系统来模拟这些粒子,让它们四散开来,形成烟花绽放的美丽图景。

代码实现,打造绚烂

以下是实现烟花效果的 JavaScript 代码:

// 烟花对象
class Firework {
  constructor(x, y, color) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.vx = 0;
    this.vy = 0;
    this.gravity = 0.05;
    this.radius = 5;
    this.life = 100;
  }

  update() {
    this.vx += this.gravity;
    this.vy += this.gravity;
    this.x += this.vx;
    this.y += this.vy;
    this.life -= 1;
  }

  draw(ctx) {
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
    ctx.fill();
  }
}

// 粒子对象
class Particle {
  constructor(x, y, color, size) {
    this.x = x;
    this.y = y;
    this.color = color;
    this.size = size;
    this.vx = (Math.random() - 0.5) * 10;
    this.vy = (Math.random() - 0.5) * 10;
    this.gravity = 0.01;
    this.life = 100;
  }

  update() {
    this.vx += this.gravity;
    this.vy += this.gravity;
    this.x += this.vx;
    this.y += this.vy;
    this.life -= 1;
  }

  draw(ctx) {
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
    ctx.fill();
  }
}

// 创建烟花和粒子列表
let fireworks = [];
let particles = [];

// 创建画布
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// 设置画布大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// 添加鼠标事件侦听器,在点击时发射烟花
canvas.addEventListener("click", (e) => {
  const x = e.clientX;
  const y = e.clientY;
  const color = "#" + Math.floor(Math.random() * 16777215).toString(16);
  fireworks.push(new Firework(x, y, color));
});

// 动画循环,更新和绘制烟花和粒子
function animate() {
  requestAnimationFrame(animate);

  // 清除画布
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 更新和绘制烟花
  for (let i = 0; i < fireworks.length; i++) {
    fireworks[i].update();
    fireworks[i].draw(ctx);

    // 当烟花爆炸时,产生粒子
    if (fireworks[i].life <= 0) {
      for (let j = 0; j < 100; j++) {
        particles.push(new Particle(fireworks[i].x, fireworks[i].y, fireworks[i].color, 3));
      }
      fireworks.splice(i, 1);
    }
  }

  // 更新和绘制粒子
  for (let i = 0; i < particles.length; i++) {
    particles[i].update();
    particles[i].draw(ctx);

    // 当粒子生命周期结束时,将其从列表中删除
    if (particles[i].life <= 0) {
      particles.splice(i, 1);
    }
  }
}

// 启动动画循环
animate();

结语

借助 Canvas 和 JavaScript 的强大功能,我们成功地实现了两种拖尾效果的烟花。在即将到来的新年里,让我们用这份代码点亮夜空,燃爆节日气氛,祝愿大家在新的一年里幸福安康,心想事成!