Changed around line 1
+ class ConfettiParticle {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ this.size = Math.random() * 10 + 5;
+ this.speedX = Math.random() * 6 - 3;
+ this.speedY = Math.random() * -15 - 5;
+ this.gravity = 0.5;
+ this.rotation = Math.random() * 360;
+ this.rotationSpeed = Math.random() * 10 - 5;
+ this.color = `hsl(${Math.random() * 360}, 80%, 60%)`;
+ this.opacity = 1;
+ }
+
+ update() {
+ this.x += this.speedX;
+ this.speedY += this.gravity;
+ this.y += this.speedY;
+ this.rotation += this.rotationSpeed;
+ this.opacity -= 0.01;
+ }
+
+ draw(ctx) {
+ ctx.save();
+ ctx.translate(this.x, this.y);
+ ctx.rotate((this.rotation * Math.PI) / 180);
+ ctx.fillStyle = this.color;
+ ctx.globalAlpha = this.opacity;
+ ctx.fillRect(-this.size / 2, -this.size / 2, this.size, this.size);
+ ctx.restore();
+ }
+ }
+
+ class ConfettiSystem {
+ constructor() {
+ this.canvas = document.createElement('canvas');
+ this.ctx = this.canvas.getContext('2d');
+ this.particles = [];
+ this.mode = 'burst';
+
+ document.body.appendChild(this.canvas);
+ this.resize();
+ this.setupEventListeners();
+ this.animate();
+ }
+
+ resize() {
+ this.canvas.width = window.innerWidth;
+ this.canvas.height = window.innerHeight;
+ this.canvas.style.position = 'fixed';
+ this.canvas.style.top = '0';
+ this.canvas.style.left = '0';
+ this.canvas.style.pointerEvents = 'none';
+ this.canvas.style.zIndex = '1000';
+ }
+
+ createConfetti(x, y, amount = 50) {
+ for (let i = 0; i < amount; i++) {
+ this.particles.push(new ConfettiParticle(x, y));
+ }
+ }
+
+ setupEventListeners() {
+ window.addEventListener('resize', () => this.resize());
+ window.addEventListener('click', (e) => {
+ if (this.mode === 'burst') {
+ this.createConfetti(e.clientX, e.clientY);
+ }
+ });
+
+ let lastScroll = window.scrollY;
+ window.addEventListener('scroll', () => {
+ if (this.mode === 'rain') {
+ const diff = Math.abs(window.scrollY - lastScroll);
+ const amount = Math.floor(diff / 10);
+ for (let i = 0; i < amount; i++) {
+ const x = Math.random() * window.innerWidth;
+ this.createConfetti(x, -20, 1);
+ }
+ lastScroll = window.scrollY;
+ }
+ });
+
+ document.getElementById('burstBtn').addEventListener('click', () => this.setMode('burst'));
+ document.getElementById('rainBtn').addEventListener('click', () => this.setMode('rain'));
+ document.getElementById('rainbowBtn').addEventListener('click', () => this.setMode('rainbow'));
+ }
+
+ setMode(mode) {
+ this.mode = mode;
+ document.querySelectorAll('.control-btn').forEach(btn => btn.classList.remove('active'));
+ document.getElementById(`${mode}Btn`).classList.add('active');
+ }
+
+ animate() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ if (this.mode === 'rainbow') {
+ this.createConfetti(Math.random() * this.canvas.width, -20, 1);
+ }
+
+ this.particles = this.particles.filter(particle => {
+ particle.update();
+ particle.draw(this.ctx);
+ return particle.opacity > 0 && particle.y < this.canvas.height;
+ });
+
+ requestAnimationFrame(() => this.animate());
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ new ConfettiSystem();
+ });