#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);
});