Spaces:
Sleeping
Sleeping
// ===== MOLECULAR PARTICLE ANIMATION ===== | |
// Create a canvas background | |
const canvas = document.createElement('canvas'); | |
canvas.id = 'moleculeCanvas'; | |
document.body.appendChild(canvas); | |
const ctx = canvas.getContext('2d'); | |
// Resize canvas to full window | |
function resizeCanvas() { | |
canvas.width = window.innerWidth; | |
canvas.height = window.innerHeight; | |
} | |
window.addEventListener('resize', resizeCanvas); | |
resizeCanvas(); | |
// Create particles | |
let particles = []; | |
const numParticles = 80; | |
for (let i = 0; i < numParticles; i++) { | |
particles.push({ | |
x: Math.random() * canvas.width, | |
y: Math.random() * canvas.height, | |
radius: Math.random() * 4 + 1, | |
color: Math.random() > 0.5 ? '#00ff88' : '#ffaa00', | |
speedX: (Math.random() - 0.5) * 1.5, | |
speedY: (Math.random() - 0.5) * 1.5 | |
}); | |
} | |
// Animation loop | |
function animate() { | |
ctx.clearRect(0, 0, canvas.width, canvas.height); | |
// Draw and move particles | |
particles.forEach((p, index) => { | |
p.x += p.speedX; | |
p.y += p.speedY; | |
// Bounce off edges | |
if (p.x < 0 || p.x > canvas.width) p.speedX *= -1; | |
if (p.y < 0 || p.y > canvas.height) p.speedY *= -1; | |
// Draw particle | |
ctx.beginPath(); | |
ctx.arc(p.x, p.y, p.radius, 0, Math.PI * 2); | |
ctx.fillStyle = p.color; | |
ctx.fill(); | |
// Connect lines if particles are close | |
for (let j = index + 1; j < particles.length; j++) { | |
let dx = particles[j].x - p.x; | |
let dy = particles[j].y - p.y; | |
let distance = Math.sqrt(dx * dx + dy * dy); | |
if (distance < 120) { | |
ctx.beginPath(); | |
ctx.moveTo(p.x, p.y); | |
ctx.lineTo(particles[j].x, particles[j].y); | |
ctx.strokeStyle = p.color === '#00ff88' ? '#00ff88aa' : '#ffaa00aa'; | |
ctx.lineWidth = 0.5; | |
ctx.stroke(); | |
} | |
} | |
}); | |
requestAnimationFrame(animate); | |
} | |
animate(); | |