Grid Particle Attraction
Home
Snippets
Grid Particle Attraction
HTML
CSS
JS
<canvas id="particles"></canvas>
body { margin: 0; height: 100vh; background: #0a0a0a; display: flex; justify-content: center; align-items: center; overflow: hidden; } canvas { display: block; }
const canvas = document.getElementById("particles"); const ctx = canvas.getContext("2d"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; const spacing = 40; // distance between particles const size = 12; // particle size (10-15px) const particles = []; for (let x = spacing; x < canvas.width; x += spacing) { for (let y = spacing; y < canvas.height; y += spacing) { particles.push({ x, y, originalX: x, originalY: y, size, color: "#15e1a1", }); } } let mouse = { x: null, y: null }; canvas.addEventListener("mousemove", (e) => { mouse.x = e.x; mouse.y = e.y; }); canvas.addEventListener("mouseleave", () => { mouse.x = null; mouse.y = null; }); function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); particles.forEach((p) => { if (mouse.x && mouse.y) { let dx = mouse.x - p.x; let dy = mouse.y - p.y; let dist = Math.sqrt(dx * dx + dy * dy); if (dist < spacing * 1.2) { p.x += dx * 0.05; p.y += dy * 0.05; } else { p.x += (p.originalX - p.x) * 0.05; p.y += (p.originalY - p.y) * 0.05; } } else { p.x += (p.originalX - p.x) * 0.05; p.y += (p.originalY - p.y) * 0.05; } ctx.beginPath(); ctx.arc(p.x, p.y, p.size / 2, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.fill(); }); requestAnimationFrame(animate); } animate();
Ad #1
Ad #2
Scroll to Top