Particle Systems
CanvasA canvas-based particle simulation. Enable attract mode and move your mouse to pull particles toward the cursor. Trails leave a motion blur by painting a semi-transparent overlay each frame.
concepts
requestAnimationFrame fires before each browser paint (~60 fps). The entire simulation — physics, state update, and draw — runs inside one tick function.
Particle data lives in a mutable ref, not React state. Updating a ref never triggers a re-render, so the animation loop runs without React involvement.
Instead of clearRect, painting a semi-transparent black fill each frame leaves a fading echo of past positions — a cheap motion-blur effect.
Each tick, vy += gravity accumulates downward acceleration. This compounds over time, making particles arc and fall like real objects.
core pattern
function tick() {
// Semi-transparent fill = motion-blur trail
ctx.fillStyle = "rgba(0, 0, 0, 0.18)";
ctx.fillRect(0, 0, w, h);
for (const p of particles) {
p.vy += gravity; // accumulate downward force
p.x += p.vx; // integrate velocity → position
p.y += p.vy;
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(tick);
}