Files
ditto.site/examples/motion/RESULTS.md
T
2026-06-29 15:11:48 -07:00

3.5 KiB
Raw Blame History

Stage 5 — motion / animation results

Stage 5 reproduces the motion (not just the settled frame) behind a deterministic motion gate, on by default (--no-motion). Declarative allowlist + fixed templates; freeze anything not confidently reproducible. The clone replays motion on load; the validator cancels animations to grade the settled frame, so Gates 06 + perceptual are untouched (no motion regression). The current architecture overview is in the root README.md.

The motion gate's accuracy contract: reproduced + frozen === captured — every captured animation is either reproduced-and-verified (running in the built clone) or honestly frozen (its keyframes weren't capturable, e.g. a cross-origin sheet). Never ship broken motion.

Fixtures (deterministic)

fixture motion motion gate gates 06 score
fixtures/motion.html finite entrance + infinite spin + pulse + card stagger (CSS @keyframes) CSS 7/7 reproduced & running 100
fixtures/motion2.html WAAPI orbit (∞) + WAAPI fade-in + rotating word WAAPI 2/2, rotators 1/1 99.9

Motion benchmark tier (benchmarks/motion.json) — npm run bench -- --tier=motion

6 / 6 pass gates 06 + Stage-2 + the motion gate, average 99.8, zero failing gates. Real declarative motion is reproduced where present; sites whose only motion is canvas/finished-entrance are honestly N/A (frozen), with no regression.

id site score gates 06 motion gate
motion-001 rauno.me 100 CSS 7/7 running (were frozen pre-Stage-5)
motion-002 sive.rs 100 N/A (static)
motion-003 emilkowal.ski 100 N/A (entrance WAAPI finishes pre-capture)
motion-004 leerob.io 99.9 N/A (static)
motion-005 joshwcomeau.com 99.5 CSS 9/11 + scroll-reveals 13/13 (2 CSS frozen; hero canvas out of scope)
motion-006 framer.com 99.6 CSS 16/16 + WAAPI 2/2 (Framer Motion showcase)

Four declarative families are reproduced & gate-verified: CSS @keyframes, WAAPI, rotating text, scroll-triggered reveals. Visual evidence (timeline filmstrips + webms, built from the existing clones with runner/motionFilmstrip.ts) lives in evidence/: CSS spinner/pulse, WAAPI orbit + rotating word, scroll-reveal cards fading in, and framer.com.

No regression (easy tier, motion ON by default)

site score gates 06 motion
michaelcole.me 100 N/A (static)
f.inc 99.8 CSS 2/2
arkli.io 100 N/A (static)
gist-quiz.com 100 N/A (static)

The static set is unaffected: where there's no motion the gate is N/A (and no browser is launched); where there is, it reproduces — and either way the cancel-before-grade step means the base gates measure the same settled frame the static clone always did.

Limitations (by contract)

  • Scroll-scrubbed motion (frame = f(scrollY)) and entrance WAAPI that finishes before capture are left frozen (not observable as a stable declarative spec).
  • Canvas/WebGL is out of scope (frozen, as before).
  • Some heavy SaaS marketing sites (linear.app) serve a degenerate JS-shell to headless capture — a capture/bot-wall limit (like warbyparker in stage 2), orthogonal to motion.

Reproduce: serve compiler/fixtures/ and npm run clone -- http://127.0.0.1:PORT/motion.html, then npx tsx src/runner/validateOne.ts <runDir>; or npm run bench -- --tier=motion.