# Animation runtimes HyperFrames seeks each frame on its own, so motion must be a function of time, never of the previous frame. Full GSAP reference: `npx hyperframes docs gsap`. ## GSAP facts that bite - Register the timeline last. Building inside `document.fonts.ready.then(…)` or another async callback is fine if you register at the end of it; registering first renders blank (`gsap_timeline_registered_before_async_build`). - Place tweens at absolute seconds (`tl.to(el, {…}, 2.4)`). Set start states in the tween (`fromTo`), not in CSS. - Measure layout once before building tweens, never inside `onUpdate`. - Finite repeats only: `repeat: Math.max(0, Math.floor(duration / cycle) - 1)`. - Seed randomness with a small PRNG (mulberry32). - A scene's timeline can't reach elements outside its file, and two timelines must not animate the same property of one element. - Transforms on a `` need `display: inline-block` or `block`. - Text that must fit a width: `window.__hyperframes.fitTextFontSize(text, { fontFamily, fontWeight, maxWidth })` returns `{ fontSize }`; `window.__hyperframes.pretext` measures text without a reflow. ## Other runtimes | Runtime | Use for | How HyperFrames drives it | | ---------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------ | | CSS `@keyframes` | Simple loops and decoration | Found automatically; finite iterations, `animation-fill-mode: both`, `data-start` on the element | | WAAPI | Native keyframes | `element.animate(…, { fill: "both" })` then `pause()`; times are document time, so use `delay` | | Lottie / dotLottie | After Effects exports, characters | `autoplay: false`, always set `loop`, push the instance to `window.__hfLottie` | | anime.js v4 | Existing anime code | `autoplay: false`, push to `window.__hfAnime`, `anime.createSeededRandom` | | Three.js, WebGPU, p5, canvas | 3D and generative | Draw from `e.detail.time` in an `hf-seek` listener; set `data-duration` on the root | Charts and map overlays: drive them from a GSAP tween's `onUpdate`, not the library's own transitions. A real place is shown on baked imagery, not drawn (`film.md` "Maps and real places"). Heavy setup (big meshes, shader compiles) registers a `window.__hf.buildReady[""]` promise. ## The seek protocol ```html ``` No `requestAnimationFrame` loop or timer as the clock.