130 lines
3.3 KiB
JavaScript
130 lines
3.3 KiB
JavaScript
import { Particle } from './particles.js';
|
|
|
|
// Fireworks variables
|
|
let context;
|
|
let fireworks = [];
|
|
let particles = [];
|
|
let fireworksActive = false;
|
|
let canvas;
|
|
let body;
|
|
|
|
// Canvas setup
|
|
function setupCanvas() {
|
|
if (!canvas) return;
|
|
|
|
context = canvas.getContext('2d');
|
|
canvas.width = window.innerWidth;
|
|
canvas.height = window.innerHeight;
|
|
|
|
// Event to resize canvas when window resizes
|
|
window.addEventListener('resize', () => {
|
|
canvas.width = window.innerWidth;
|
|
canvas.height = window.innerHeight;
|
|
});
|
|
}
|
|
|
|
// Firework class
|
|
class Firework {
|
|
constructor() {
|
|
this.x = Math.random() * canvas.width;
|
|
this.y = canvas.height;
|
|
this.targetX = Math.random() * canvas.width;
|
|
this.targetY = Math.random() * canvas.height / 2;
|
|
this.speed = 2 + Math.random() * 3;
|
|
this.angle = Math.atan2(this.targetY - this.y, this.targetX - this.x);
|
|
this.velocityX = Math.cos(this.angle) * this.speed;
|
|
this.velocityY = Math.sin(this.angle) * this.speed;
|
|
this.size = 2;
|
|
this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
|
|
this.particleCount = 80 + Math.floor(Math.random() * 40);
|
|
}
|
|
|
|
update() {
|
|
this.x += this.velocityX;
|
|
this.y += this.velocityY;
|
|
|
|
// Check if firework reached its target
|
|
if (Math.abs(this.x - this.targetX) < 10 && Math.abs(this.y - this.targetY) < 10) {
|
|
this.explode();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
explode() {
|
|
for (let i = 0; i < this.particleCount; i++) {
|
|
particles.push(new Particle(this.x, this.y, this.color));
|
|
}
|
|
}
|
|
|
|
draw() {
|
|
context.fillStyle = this.color;
|
|
context.beginPath();
|
|
context.arc(this.x, this.y, this.size, 0, Math.PI * 2);
|
|
context.fill();
|
|
}
|
|
}
|
|
|
|
// Animation loop for fireworks
|
|
function animateFireworks() {
|
|
if (!fireworksActive) return;
|
|
|
|
requestAnimationFrame(animateFireworks);
|
|
|
|
// Clear canvas with semi-transparent black for trail effect
|
|
context.fillStyle = 'rgba(0, 0, 0, 0.1)';
|
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
|
// Random chance to create a new firework
|
|
if (fireworks.length < 5 && Math.random() < 0.03) {
|
|
fireworks.push(new Firework());
|
|
}
|
|
|
|
// Update and draw fireworks
|
|
fireworks = fireworks.filter(firework => {
|
|
firework.draw();
|
|
return firework.update();
|
|
});
|
|
|
|
// Update and draw particles
|
|
particles = particles.filter(particle => {
|
|
particle.draw(context);
|
|
return particle.update();
|
|
});
|
|
}
|
|
|
|
// Start fireworks
|
|
function startFireworks() {
|
|
if (fireworksActive) return;
|
|
|
|
setupCanvas();
|
|
fireworksActive = true;
|
|
body.classList.add('fireworks-active');
|
|
canvas.style.display = 'block';
|
|
|
|
// Create initial fireworks
|
|
for (let i = 0; i < 3; i++) {
|
|
fireworks.push(new Firework());
|
|
}
|
|
|
|
animateFireworks();
|
|
console.log("Fireworks started");
|
|
}
|
|
|
|
// Reset fireworks
|
|
function resetFireworks() {
|
|
if (!fireworksActive) return;
|
|
|
|
fireworksActive = false;
|
|
body.classList.remove('fireworks-active');
|
|
fireworks = [];
|
|
particles = [];
|
|
}
|
|
|
|
// Initialize fireworks with DOM elements
|
|
function initFireworks(canvasElement, bodyElement) {
|
|
canvas = canvasElement;
|
|
body = bodyElement;
|
|
}
|
|
|
|
export { startFireworks, resetFireworks, initFireworks };
|