← all topics

Particle Systems

Canvas

A 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.

Controls
120
2
3
0.05

concepts

game loop

requestAnimationFrame fires before each browser paint (~60 fps). The entire simulation — physics, state update, and draw — runs inside one tick function.

state in refs

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.

trail effect

Instead of clearRect, painting a semi-transparent black fill each frame leaves a fading echo of past positions — a cheap motion-blur effect.

gravity

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