DEV Community

Lucian (LKB)
Lucian (LKB)

Posted on Originally published at lkforge.com

I built 12 chaos & physics simulations that run entirely in the browser (no backend, no libraries)

Over the last few weeks I built a small rack of physics simulations — 12 of them — that all run client-side in a single HTML file each. No backend, no WebGL frameworks, no build step you can't read. Just <canvas>, requestAnimationFrame, and the actual equations.

Here's the whole rack if you want to click around first: lkforge.com/tools/physics. Below I'll walk through the two I'm happiest with — reaction-diffusion and the Lorenz attractor — because they show two very different flavors of "simple local rule → surprising global behavior."

1. Reaction-diffusion: Turing patterns from two numbers per cell

The reaction-diffusion lab runs the Gray-Scott model: two virtual chemicals U and V sit on a grid, diffuse at different rates, and react via U + 2V → 3V. U is fed in; V is killed off. That's the entire model, and it reproduces spots, stripes, mazes, dividing cells and coral — the same short-range-activation / long-range-inhibition idea Alan Turing proposed in 1952 to explain animal coat patterns.

The core update, on a toroidal grid with a 9-point Laplacian:

var uu = u[c], vv = v[c];
var lapU = (u[W] + u[E] + u[N] + u[S]) * 0.2 +
           (u[NW] + u[NE] + u[SW] + u[SE]) * 0.05 - uu;
var lapV = (v[W] + v[E] + v[N] + v[S]) * 0.2 +
           (v[NW] + v[NE] + v[SW] + v[SE]) * 0.05 - vv;
var uvv = uu * vv * vv;
un[c] = uu + (Du * lapU - uvv + f * (1 - uu)) * dt;   // U: diffuse, react away, feed
vn[c] = vv + (Dv * lapV + uvv - (f + k) * vv) * dt;   // V: diffuse, react in, kill
Enter fullscreen mode Exit fullscreen mode

Two things I learned the hard way:

  • The feed/kill pair (f, k) is everything. Small changes switch the whole regime — coral at (0.0545, 0.062), mitosis near (0.046, 0.063), spots at (0.030, 0.062). I ship these as presets so people don't land on a dead grid.
  • Seed with a noisy patch, not a solid disk. A solid blob tends to bloom once and then die back to uniform grey. Random speckle lets the pattern nucleate across an area and reach a stable steady state.

Rendering is a createImageData grid mapped through a small color lookup table, drawn to an offscreen canvas and scaled up with drawImage — cheap enough to run a 200×200 grid at 60fps with ~10 solver steps per frame.

2. The Lorenz attractor: determinism without predictability

The Lorenz lab integrates the 1963 Lorenz equations with fourth-order Runge-Kutta and draws the trajectory as a rotating, fading 3-D trail:

function lorenzDeriv(s) {
  var x = s[0], y = s[1], z = s[2];
  return [SIG * (y - x), x * (rho - z) - y, x * y - BETA * z];
}
Enter fullscreen mode Exit fullscreen mode

The fun part is the butterfly effect made visible: start a second point 1e-3 away from the first, integrate both under the identical rule, and show the separation climbing. The two paths track together, then peel apart onto opposite wings of the attractor — neither ever leaving the shape, neither ever repeating. That's the whole point Edward Lorenz made when a rounded weather-model input (0.506127 → 0.506) sent his forecast somewhere unrecognizable.

A couple of implementation notes:

  • RK4, not Euler. Euler visibly distorts the attractor as the path stretches and folds; RK4 with a small dt keeps it honest.
  • Orthographic projection + one yaw/pitch rotation is enough — no full 3-D pipeline. Drag updates yaw/pitch; an auto-spin adds a constant yaw increment per frame.
  • The same engine also renders Rössler and Aizawa attractors by swapping the derivative function.

Why single-file, client-side?

Three reasons that turned out to matter:

  1. Longevity. No server means nothing to keep alive; these will still run in five years.
  2. Embeddable. Because each sim mounts on one canvas id and wires to controls by id, the exact same script drives the tool page and an /embed/ widget — drop it into a blog post with one iframe.
  3. Readable. Anyone can view-source and see the actual physics, which is kind of the point for teaching material.

If you want to poke at the rest — falling sand, a double pendulum, the double-slit experiment, charged particles in a magnetic field, Conway's Game of Life — they're all here: lkforge.com/tools/physics.

Happy to answer questions about any of the models in the comments.

Top comments (0)