my-app-802 / assets /js /fireworks.js
AnkhLP's picture
Upload folder using huggingface_hub
3e266bd verified
class Fireworks {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.particles = [];
this.rockets = [];
this.isActive = false;
this.resize();
window.addEventListener('resize', () => this.resize());
}
resize() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
createRocket() {
this.rockets.push({
x: Math.random() * this.canvas.width,
y: this.canvas.height,
vx: (Math.random() - 0.5) * 2,
vy: -Math.random() * 3 - 12,
trail: []
});
}
createExplosion(x, y) {
const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#f9ca24', '#f0932b', '#eb4d4b', '#6ab04c', '#130f40'];
const color = colors[Math.floor(Math.random() * colors.length)];
const particleCount = 50 + Math.random() * 50;
for (let i = 0; i < particleCount; i++) {
const angle = (Math.PI * 2 * i) / particleCount;
const velocity = 2 + Math.random() * 4;
this.particles.push({
x: x,
y: y,
vx: Math.cos(angle) * velocity,
vy: Math.sin(angle) * velocity,
alpha: 1,
color: color,
size: 2 + Math.random() * 2
});
}
}
update() {
// Update rockets
for (let i = this.rockets.length - 1; i >= 0; i--) {
const rocket = this.rockets[i];
rocket.trail.push({ x: rocket.x, y: rocket.y });
if (rocket.trail.length > 10) rocket.trail.shift();
rocket.x += rocket.vx;
rocket.y += rocket.vy;
rocket.vy += 0.1;
if (rocket.vy >= 0) {
this.createExplosion(rocket.x, rocket.y);
this.rockets.splice(i, 1);
}
}
// Update particles
for (let i = this.particles.length - 1; i >= 0; i--) {
const p = this.particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += 0.05;
p.vx *= 0.99;
p.alpha -= 0.01;
if (p.alpha <= 0) {
this.particles.splice(i, 1);
}
}
}
draw() {
this.ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
// Draw rockets
this.rockets.forEach(rocket => {
this.ctx.beginPath();
rocket.trail.forEach((point, index) => {
if (index === 0) {
this.ctx.moveTo(point.x, point.y);
} else {
this.ctx.lineTo(point.x, point.y);
}
});
this.ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
this.ctx.lineWidth = 2;
this.ctx.stroke();
});
// Draw particles
this.particles.forEach(p => {
this.ctx.globalAlpha = p.alpha;
this.ctx.fillStyle = p.color;
this.ctx.beginPath();
this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
this.ctx.fill();
// Add glow effect
this.ctx.shadowBlur = 10;
this.ctx.shadowColor = p.color;
this.ctx.fill();
this.ctx.shadowBlur = 0;
});
this.ctx.globalAlpha = 1;
}
animate() {
if (!this.isActive) return;
this.update();
this.draw();
if (Math.random() < 0.05) {
this.createRocket();
}
requestAnimationFrame(() => this.animate());
}
start() {
this.isActive = true;
this.particles = [];
this.rockets = [];
this.animate();
// Stop after 3 seconds
setTimeout(() => {
this.stop();
}, 3000);
}
stop() {
this.isActive = false;
setTimeout(() => {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.particles = [];
this.rockets = [];
}, 1000);
}
}