animation-describer
v0.3.0
Published
Capture web animations in a real browser and hand your coding agent a measured spec — durations, easings, sequencing — to recreate them faithfully.
Maintainers
Readme
animation-describer
Capture any web animation and hand your coding agent a measured spec — real durations, real easing curves, real choreography — so it can recreate the animation faithfully instead of guessing from pixels.
Other video-to-animation tools send pixels to a vision model and hope it guesses the timing right. animation-describer opens the page in an instrumented browser and reads the ground truth: Web Animations API timings, CSS transition events, and per-frame sampling of JS-driven motion (GSAP, anime.js, hand-rolled tweens) with cubic-bezier curves fitted from the measured velocity profile.
### 3. `div.card:nth-child(1)` — transform
- **Starts at:** 295ms (trigger: page-load)
- **Duration:** 600ms
- **Easing:** `cubic-bezier(0.22, 1, 0.36, 1)`
- **Value:** translateY(24px) → translateY(0px)
- **Part of stagger group #2** (5 elements, 80ms interval)
- **Measurement source:** Web Animations API (declared values, exact)Quickstart
One command registers the MCP server with every AI coding tool it finds on your machine (Cursor, Claude Code, Codex, Windsurf, Kiro, VS Code):
npx animation-describer connectOr target one client, or just print the config to paste anywhere:
npx animation-describer connect cursor # cursor | claude | codex | windsurf | kiro | vscode | all
npx animation-describer connect --print # show config snippets, write nothingThen just ask your agent:
"Capture the hero animation on stripe.com and recreate it in my project."
A browser window opens with a record button. Optionally click Select area — then click an element or drag a rectangle to scope the capture to just that region — then click Record, trigger the animation (hover, click, scroll), click Stop. Your agent receives a compact measured summary, retrieves exact tracks on demand, recreates the animation, and then verifies its recreation against the original — measured deltas, not vibes. No API keys, no cloud, nothing leaves your machine.
MCP tools
| Tool | What it does |
|---|---|
| capture_page | Opens an instrumented browser; user records (or mode: "scan" auto-scrolls the whole page headlessly and catalogs every animation by section). Optional scope selector limits capture to one element |
| verify_recreation | Captures the agent's recreation and diffs it against the reference: per-track duration/easing/travel/loop deltas + motion-energy similarity. Iterate until it passes |
| analyze_video | Pixel-only fallback for local video files (screen recordings, clips) |
| get_session | Returns the compact summary for a session (defaults to latest) |
| get_tracks | Exact filtered tracks with pagination, without flooding model context |
| get_frames | Paths to curated keyframe screenshots at motion peaks |
| list_sessions | Recent captures |
CLI usage (no agent required)
npx animation-describer capture https://example.com # record live
npx animation-describer capture https://example.com --scope ".hero" # only one element
npx animation-describer capture https://example.com --scan # whole-page scan
npx animation-describer analyze recording.mp4 # analyze a video file
npx animation-describer verify http://localhost:3000 --against <id> # diff recreation vs referenceWhat gets measured
- CSS animations & transitions — exact durations, delays, easings, keyframes, iteration counts, read from the browser's animation model (not estimated).
- JS-driven animation (GSAP, anime.js, rAF tweens) — element positions sampled every frame; durations measured, easing recovered by fitting a cubic-bezier to the velocity profile, with a confidence score.
- Choreography — stagger groups with measured intervals, trigger inference (hover / click / scroll / page-load), loop detection.
- Context — the page's own
@keyframesrules (CSSOM), detected animation libraries, and curated keyframe screenshots picked at motion-energy peaks. - Recreation fidelity —
verifyre-measures your implementation with the same pipeline and diffs every track against the reference, so "matches the original" is a measured claim.
How it compares
| | animation-describer | pixel/video tools (AnimSpec, etc.) | |---|---|---| | Timing & easing | Measured from the DOM | Estimated by a vision model | | JS-driven animations | Sampled + curve-fitted | Estimated | | User interaction (hover, scroll) | Yes — you drive the browser | Only what's in the video | | Recreation verified | Yes — measured diff loop | No | | Inference cost | None (your agent's model) | Per-analysis credits | | Runs | 100% local | Cloud |
A video fallback (analyze_video) is included for animations you can't visit live — it's honest about being an estimate.
Session format
Sessions live in ~/.animation-describer/sessions/<id>/:
spec.md— compact, context-safe animation summaryspec.full.md— complete archival report; do not load wholesale into an AI contexttimeline.json— machine-readable tracks (start/duration/easing/trigger per element per property)frames/key-*.jpg— curated keyframes (timestamps in filenames)video.webm— the full recordingverification.md— per-track fidelity report (on sessions created byverify)telemetry.json— raw collector output
Requirements
- Node 18+
- Chromium for Playwright (installed automatically on first capture)
- Desktop OS (macOS / Linux / Windows)
Limitations
- Canvas/WebGL animations have no DOM telemetry — use
analyze_videofor those. - Cross-origin stylesheets can't be read (their
@keyframeswon't be listed; the animations themselves are still measured via WAAPI). - Hard page navigation during a recording ends the session.
License
MIT
