import React, { useEffect, useRef } from 'react'; import { COLORS } from '../constants'; export const Confetti: React.FC = () => { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; // Set dimensions canvas.width = window.innerWidth; canvas.height = window.innerHeight; const particles: any[] = []; // Bright celebratory colors const colors = [COLORS.grass, COLORS.bridge, COLORS.character, '#ef4444', '#3b82f6', '#8b5cf6', '#ec4899']; // Create particles for (let i = 0; i < 200; i++) { particles.push({ x: canvas.width / 2, y: canvas.height * 0.3, vx: (Math.random() - 0.5) * 25, vy: (Math.random() - 0.5) * 25 - 5, size: Math.random() * 8 + 4, color: colors[Math.floor(Math.random() * colors.length)], rotation: Math.random() * 360, rotationSpeed: (Math.random() - 0.5) * 15, gravity: 0.6, drag: 0.95 }); } let animationId: number; const animate = () => { ctx.clearRect(0, 0, canvas.width, canvas.height); let activeParticles = 0; particles.forEach((p) => { if (p.y < canvas.height + 20) { activeParticles++; p.x += p.vx; p.y += p.vy; p.vy += p.gravity; p.vx *= p.drag; p.y *= 1.0; p.rotation += p.rotationSpeed; ctx.save(); ctx.translate(p.x, p.y); ctx.rotate((p.rotation * Math.PI) / 180); ctx.fillStyle = p.color; ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size); ctx.restore(); } }); if (activeParticles > 0) { animationId = requestAnimationFrame(animate); } }; animate(); return () => cancelAnimationFrame(animationId); }, []); return ; };