--- name: hyperframes-waapi description: Web Animations API adapter patterns for HyperFrames. Use when authoring element.animate() motion, Animation currentTime seeking, document.getAnimations(), KeyframeEffect timing, fill modes, or native browser animations that must render deterministically in HyperFrames. --- # Web Animations API for HyperFrames HyperFrames can seek Web Animations API animations through its `waapi` runtime adapter. WAAPI is useful when you want native browser keyframes with JavaScript-created timing and no GSAP dependency. ## Contract - Create animations synchronously during composition initialization. - Use `element.animate(...)` with finite `duration` and `iterations`. - Use `fill: "both"` so seeked states persist. - Pause animations after creation or let the adapter pause them on first seek. - Avoid callbacks and promises for render-critical state. The adapter calls `document.getAnimations()`, sets each animation's `currentTime` to HyperFrames time in milliseconds, then pauses it. ## Basic Pattern ```html
``` ## Stagger Pattern ```js document.querySelectorAll(".token").forEach((token, index) => { const animation = token.animate( [ { transform: "translateY(24px)", opacity: 0 }, { transform: "translateY(0)", opacity: 1 }, ], { duration: 620, delay: index * 80, easing: "cubic-bezier(0.2, 0, 0, 1)", fill: "both", iterations: 1, }, ); animation.pause(); }); ``` ## Good Uses - Lightweight DOM motion where CSS keyframes are too rigid and GSAP is unnecessary. - Generated animations from structured data. - Simple timelines that can be represented as keyframes, delays, and offsets. ## Composition Duration The render engine needs the composition's total length to know how many frames to capture. GSAP timelines report duration automatically; a WAAPI-only composition has no timeline object, so the runtime infers duration from every animation's `effect.getComputedTiming().endTime` (offset by when the animation was created relative to composition start). `data-duration` on the root element is optional as long as every `element.animate()` call uses finite `duration` and `iterations` — which the contract above already requires. Infinite `iterations` has no finite `endTime`, so it can't be auto-inferred — that's one more reason to avoid it (see Avoid below). If you must use it, add `data-duration="