js实现烟花
使用Canvas实现烟花效果
通过HTML5的Canvas元素结合JavaScript可以创建动态烟花效果。以下是一个基础实现方案:
<canvas id="fireworksCanvas"></canvas>
const canvas = document.getElementById('fireworksCanvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const particles = [];
const colors = ['#ff0000', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#ff00ff'];
function createFirework(x, y) {
const particleCount = 100;
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 5 + 2;
particles.push({
x,
y,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
color: colors[Math.floor(Math.random() * colors.length)],
radius: Math.random() * 3 + 1,
alpha: 1,
decay: Math.random() * 0.015 + 0.01
});
}
}
function updateParticles() {
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += 0.05;
p.alpha -= p.decay;
if (p.alpha <= 0) {
particles.splice(i, 1);
}
}
}
function drawParticles() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const p of particles) {
ctx.globalAlpha = p.alpha;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2);
ctx.fill();
}
}
function animate() {
updateParticles();
drawParticles();
requestAnimationFrame(animate);
}
canvas.addEventListener('click', (e) => {
createFirework(e.clientX, e.clientY);
});
animate();
优化烟花效果的技巧
增加重力效果和随机性可以使烟花更逼真。修改粒子创建逻辑:
function createFirework(x, y) {
const particleCount = 150;
const hue = Math.floor(Math.random() * 360);
for (let i = 0; i < particleCount; i++) {
const angle = Math.random() * Math.PI * 2;
const speed = Math.random() * 6 + 1;
const saturation = 100 - Math.random() * 20;
const lightness = 50 + Math.random() * 10;
particles.push({
x,
y,
vx: Math.cos(angle) * speed * (0.6 + Math.random() * 0.4),
vy: Math.sin(angle) * speed * (0.6 + Math.random() * 0.4),
color: `hsl(${hue}, ${saturation}%, ${lightness}%)`,
radius: Math.random() * 4 + 1,
alpha: 1,
decay: Math.random() * 0.02 + 0.01,
gravity: 0.05 + Math.random() * 0.03
});
}
}
自动发射烟花功能
添加定时自动发射功能,使烟花无需点击也能自动展示:
function autoFire() {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height * 0.5;
createFirework(x, y);
setTimeout(autoFire, Math.random() * 2000 + 1000);
}
autoFire();
性能优化建议
对于大量粒子,使用对象池技术可以提升性能:

const particlePool = [];
const maxParticles = 5000;
function getParticle() {
if (particlePool.length > 0) {
return particlePool.pop();
}
return {};
}
function recycleParticle(p) {
if (particlePool.length < maxParticles) {
particlePool.push(p);
}
}
// 在updateParticles中修改回收逻辑
if (p.alpha <= 0) {
recycleParticle(p);
particles.splice(i, 1);
}
这些代码组合起来可以创建一个视觉效果丰富的烟花演示,支持点击触发和自动播放两种模式,并且考虑了性能优化。






