Movement & Light
Kaleidoscope
Stand in front of the camera and you become the kaleidoscope. MediaPipe Pose tracks twelve joints; everything on screen is driven by how you move. Move faster and the color saturates and the spin picks up. Open your arms and the petals stretch. Crouch and the whole form grows.
The graphics are the easy part. The real problem is that pose tracking and rendering run on different clocks. MediaPipe fires whenever it has a new pose, which is irregular and slower than the display refresh, so anything drawn directly from those callbacks steps at the camera's rate and looks stuttery. The two are decoupled instead: pose results write into a shared state object, and a requestAnimationFrame loop reads from it every frame whether or not new pose data arrived.
The second half is easing. Nothing is ever drawn from a raw pose value. Each frame the pose produces targets (target hue, target radius, target petal stretch) and every drawn value interpolates a fraction of the way toward its target. That is the whole difference between visuals that glide and visuals that snap. The interpolation rate itself scales with velocity, so fast movement both moves the target and speeds up the chase toward it. Velocity is deliberately asymmetric: it rises quickly and decays slowly, which gives the image momentum. A burst of movement spikes immediately and then settles, rather than dropping out the instant you stop.
Four renderers share that same eased state: Prism, Bloom, Ripple, and Stars. A live control panel exposes slice count, hue drift, motion, petal size, smoothing, saturation, and trails, plus per-joint toggles so you can drop the legs out and drive the whole thing from the arms alone. Settings persist between sessions.
Vanilla ES modules, no framework and no build step: roughly 1,200 lines of JavaScript across ten modules, with the leaf module holding pure landmark math and a single shared state object as the only thing both halves touch.