TypeScript · Canvas 2D · no framework
Flow field
A few thousand particles walking a field of value noise, each one drawing where it has been. Nothing here is random once it has started — the whole image is a function of one seed, which is what makes it testable rather than merely pretty.
Move the pointer over it to push the particles away; hold the primary button to pull them in.
The field
You have asked for reduced motion, so this is composed as a still rather than animated. Step advances it; Play animates it if you would rather.
How it is built
The simulation is a pure module — a seeded generator, a value-noise lattice, and a step function over plain numbers, with no reference to a canvas or a clock anywhere in it. That split is the point of the piece rather than tidiness: it means “no particle ever leaves the canvas”and “the same seed gives the same run” are properties a test asserts over a thousand steps, instead of things you squint at.
Each particle remembers where it was, and the renderer strokes a segment from there to where it is now. The catch is the wrap: a particle leaving the right-hand edge reappears on the left, and joining those two points draws a line straight across the picture. It looks like a deliberate effect until you notice every streak is horizontal. The simulation raises a flag on any step that teleports, and the renderer skips those segments.
The pointer steers rather than shoves, and that is a correctness decision. Adding displacement on top of the step would let a particle move further in one tick than a normal step — which is precisely the condition the renderer reads as “this was a wrap”. So a strong enough pointer would have started painting the very streaks the flag exists to prevent. Biasing the angle instead keeps every step exactly one speed long, and every existing invariant survives the feature untouched.
Reduced motion gets a still, not a faster animation.The setting is a vestibular accommodation, so speeding the same movement up is worse for the person asking. The field is composed to completion and handed over with a Step control — and since the interesting thing about a flow field is the shape of the paths, the still shows it in full. Animating stays available as an explicit choice.