Interaction, motion, and coordinate transforms in p5.js
Learning objectives
- learner can capture mouse, keyboard, and event input to make a sketch interactive
- learner can animate with easing, frame-count timing, and motion-blur trails
- learner can compose transforms with translate/rotate/scale and isolate them with push/pop matrix stacks
Capstone — one whole task that evidences the objectives
Produce an interactive kinetic sketch where mouse and keyboard input steer eased, looping motion of transformed shapes, using push/pop so local transforms and motion trails compose cleanly.
Prerequisite modules
This module is where a static sketch becomes an instrument. In a live-visuals or VJ context — p5.js projected behind a set, reacting to the performer at the keyboard — the difference between a demo and a performance is exactly this trio: input you can play, motion that feels alive rather than teleported, and transforms that stay local so one gesture never corrupts the rest of the scene.
Start supported: wire the cursor to a single shape using the current-versus-previous mouse position idiom, then add one key command via the event functions that fire once per press instead of every frame. Next, replace direct position-setting with easing — move a fraction of the remaining distance each frame — so the shape chases the cursor organically, and let frame-count-modulo drive a seamlessly looping sweep. Swap the full-canvas clear for the semi-transparent-rectangle fade to earn motion trails. Finally, rebuild the shape as a locally transformed object: translate to its center, rotate and scale there, and wrap the whole thing in push/pop so trails and multiple shapes compose without transform drift.
Every required atom gates the capstone directly: without event handling the sketch is not steerable, without easing and the fade technique the motion reads as mechanical, and without matrix isolation the composed scene falls apart the moment a second shape appears. The supporting atoms widen the craft — mapping input ranges onto rotation angles, arrays for scaling one shape into a swarm, the WEBGL center-origin gotcha when you later go 3D, and Bret Victor’s gesture-recording idea as a lens on why performed motion beats keyframed motion. Drill easing updates, push/pop pairing, and modulo looping until they are reflexes; on stage there is no time to derive them.
Runnable examples
Generated from the context/ instrument corpus by concept (redistributable idioms only). Do not edit — regenerate with gen-module-examples.mjs.
rotation-animation
uv = rot(u_time * 0.3) * uv;
glsl-0029 · public-domain
osc(10).rotate(() => time * 0.2).out()
hydra-0006 · CC0-1.0
oscillation
let y = height/2 + sin(frameCount * 0.05) * 100
p5live-0004 · CC0-1.0
float rings = abs(sin(length(uv)*20.0 - u_time*2.0));
glsl-0039 · public-domain
easing-curve
x = lerp(x, targetX, 0.1)
p5live-0032 · CC0-1.0
noise-drift
let x = noise(frameCount*0.002)*width, y = noise(frameCount*0.003)*height
p5live-0007 · CC0-1.0
Atoms in this module
Required — these gate the capstone
Supporting — enrichment, not gating
Part of curricula
- Live Visualist — zero to performing live-coded & generative visuals — Generative canvas — colour, motion, and Hydra live-coding required
- VJ — visual performance with projection, light & video — Generate & compose: build your own look recommended
Unlocks — modules that require this one