Make real animation in HTML Canvas 2D with code: direct motion with timing and easing craft, prototype timing on hard stepped frames first, run a clean fixed-timestep engine, and export a working MP4 through the browser (captureStream + MediaRecorder with a frame-perfect stepping path and ffmpeg fallback). Use when someone wants programmatic 2D animation, motion graphics from code, bouncing/flying/squashing motion, or recording a canvas animation to a video file.
./install.sh procedural-animation-canvasname: procedural_animation_canvas description: Make real animation in HTML Canvas 2D with code: direct motion with timing and easing craft, prototype timing on hard stepped frames first, run a clean fixed-timestep engine, and export a working MP4 through the browser (captureStream + MediaRecorder with a frame-perfect stepping path and ffmpeg fallback). Use when someone wants programmatic 2D animation, motion graphics from code, bouncing/flying/squashing motion, or recording a canvas animation to a video file.
Teach an agent to make Canvas 2D animation that feels directed, not generated: motion with deliberate timing and easing, a cheap prototype loop for judging timing before smoothing, a small engine that keeps simulation deterministic, and an export path that produces a real, playable MP4. The engine lives in assets/engine.js; the craft lives in the references.
makeTimeline().add('x', {from, to, duration, delay, ease}). Duration is the feeling; set it before anything else. See references/direction-guide.md for how to choose timings, easings, and where anticipation/squash/arcs belong.stepPlayback({fps: 6, duration, render}) or swap the real easing for steps(6). Fix durations and delays while motion is still cheap. If the stepped version reads, smoothing will work; if it does not, no curve will save it.drawScene(t, ctx) function. It takes seconds, draws the whole frame, and touches nothing else. The timeline gives you values; drawScene turns them into pixels. This same function drives the live preview, the step preview, and the export, so they can never drift apart.startLoop({canvas, update, render}) runs simulation on a fixed timestep (accumulator, spiral-of-death clamp) with interpolated rendering, so motion is deterministic at any display refresh rate.requestFrame(). If that is unavailable, recordLive(canvas, {fps, duration}) records the live canvas. Both negotiate codecs via pickMime(): native MP4 on Chrome/Edge 126+ and Safari 14.1+, WebM on Firefox. WebM output gets transcoded with the ffmpeg command in references/export-pipeline.md. Open assets/demo.html (a working bounce: live, step, and record buttons) to see the whole loop end to end.drawScene(t, ctx); live preview and export share that function, never two parallel implementations.x += 1). Every move is a tween with a duration and an easing. Increments make motion frame-rate dependent and undirectable.linear is for machines (wheels, conveyors), never for starts and stops.backOut and easeOutElastic fight each other if you stack them.pickMime() decides; Firefox exports WebM, and that is correct behavior, not a failure.assets/engine.js has zero DOM dependencies and is covered by assets/test-engine.js (node test-engine.js); run it after any change.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.