#particles { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none; } .particle { position: absolute; background: white; border-radius: 50%; pointer-events: none; transition: opacity 0.8s ease-in-out; } function createParticle() { const particles = document.getElementById('particles'); const particle = document.createElement('div'); particle.className = 'particle'; // Size between 2-6px const size = Math.random() * 4 + 2; particle.style.width = size + 'px'; particle.style.height = size + 'px'; // Start from center const centerX = window.innerWidth / 2; const centerY = window.innerHeight / 2; // Initial position at center let x = centerX; let y = centerY; const angle = Math.random() * Math.PI * 2; const speed = Math.random() * 10 + 6; let vx = Math.cos(angle) * speed; let vy = Math.sin(angle) * speed; // Start with very low opacity particle.style.opacity = 0.05; // Set initial position particle.style.left = x + 'px'; particle.style.top = y + 'px'; particles.appendChild(particle); let age = 0; let stuckCount = 0; function animate() { age++; // Move particle x += vx; y += vy; // Gradually reduce speed vx *= 0.995; vy *= 0.995; // Add random movement vx += (Math.random() - 0.5) * 0.2; vy += (Math.random() - 0.5) * 0.2; // Boundary handling if (x = window.innerWidth) { x = window.innerWidth; vx = -Math.abs(vx) * 0.8; stuckCount++; } if (y = window.innerHeight) { y = window.innerHeight; vy = -Math.abs(vy) * 0.8; stuckCount++; } // If particle gets stuck, give it a random boost if (stuckCount > 5) { vx += (Math.random() - 0.5) * 2; vy += (Math.random() - 0.5) * 2; stuckCount = 0; } // Update position particle.style.left = x + 'px'; particle.style.top = y + 'px'; // Calculate opacity based on distance and age const distanceFromCenter = Math.sqrt( Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2) ); // Base opacity calculation let targetOpacity = Math.min( (distanceFromCenter / (window.innerWidth * 0.15)) * 0.3, 0.3 ); // Initial fade in if (age 25 && Math.random() < 0.02) { particle.style.opacity = targetOpacity * (Math.random() * 0.5 + 0.5); } requestAnimationFrame(animate); } requestAnimationFrame(animate); } // Initialize particles on load window.addEventListener('load', function() { // Start particles immediately with shorter delays for(let i = 0; i createParticle(), i * 10); } // Continuously create new particles setInterval(() => { if (document.getElementById('particles').children.length < 80) { createParticle(); } }, 500); });
Days
Hours
Minutes
Seconds