Files
hyperframes/skills/remotion-to-hyperframes/references/lottie.md
T
James 890f305cd1 feat(skills): remotion-to-hyperframes references (6/7)
Adds 11 progressively-disclosed reference files that the skill loads on
demand during translation. Total ~1500 LOC, every file under 200 lines
(skill-creator's progressive-disclosure budget).

  api-map.md         the comprehensive Remotion -> HF translation table
                     (the index; loaded at start of translation)
  timing.md          interpolate, spring (validated configs), easing,
                     count-up, stagger
  sequencing.md      Sequence, Series, Loop, Freeze, AbsoluteFill,
                     Composition root
  media.md           Audio, Video, Img, IFrame, OffthreadVideo,
                     staticFile, asset paths
  transitions.md     @remotion/transitions presentations -> manual GSAP
                     crossfades or HF shader-transitions
  lottie.md          @remotion/lottie -> HF lottie adapter (incl. AE
                     feature limitations note)
  fonts.md           Google Fonts loading, local @font-face, system
                     fallback noise floor
  parameters.md      Zod schemas, defaultProps, sync vs async
                     calculateMetadata
  escape-hatch.md    when to bow out + the runtime interop pattern
                     from PR #214
  limitations.md     known caveat patterns (volume ramps, Loop with
                     state, custom presentations, code-split components)
  eval.md            how to run the validation harness, threshold rule
                     of thumb, what the noise floor looks like

The references are evidence-driven rather than speculative: every spring
config, easing curve, and SSIM threshold is documented from the
validated T1/T2/T3 calibration runs (mean 0.974 / 0.985 / 0.953). The
escape-hatch boundaries match the lint blockers in PR 2 and the T4
fixtures in PR 5.

Replaces the placeholder .gitkeep from PR 1.
2026-04-27 23:55:51 +00:00

4.1 KiB

Lottie translation: @remotion/lottie → HF lottie adapter

Lottie animations are a clean translation case — HF has a built-in Lottie adapter that supports both lottie-web and @lottiefiles/dotlottie-web. The adapter auto-discovers animations registered on window.__hfLottie and seeks them per-frame via goToAndStop.

Pattern

import { Lottie } from "@remotion/lottie";
import animationData from "./hello.json";

export const MyComp = () => (
  <AbsoluteFill>
    <Lottie animationData={animationData} loop={false} />
  </AbsoluteFill>
);

Translates to:

<div id="stage" ...>
  <div id="lottie-anim" style="width:100%;height:100%"></div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.12.2/lottie.min.js"></script>
  <script>
    const anim = lottie.loadAnimation({
      container: document.getElementById("lottie-anim"),
      renderer: "svg",
      loop: false,
      autoplay: false,
      path: "assets/hello.json",
    });
    window.__hfLottie = window.__hfLottie || [];
    window.__hfLottie.push(anim);
  </script>
</div>

Key differences from a typical Lottie embed:

  • autoplay: false — HF drives playback by seeking
  • loop: false typically (unless Remotion's loop={true})
  • window.__hfLottie.push(anim) is what hooks the animation into HF's per-frame seek

Asset handling

Remotion bundles the animation JSON via webpack import. HF needs the JSON on disk under assets/ and references it via path:

  1. Copy hello.json from the Remotion project into hf-src/assets/.
  2. Reference as path: "assets/hello.json" in loadAnimation.

For dotlottie (binary) format, swap in @lottiefiles/dotlottie-web:

<script src="https://unpkg.com/@lottiefiles/dotlottie-web"></script>
<canvas id="anim" style="width:100%;height:100%"></canvas>
<script>
  const player = new DotLottie({
    canvas: document.getElementById("anim"),
    src: "assets/hello.lottie",
    autoplay: false,
  });
  window.__hfLottie = window.__hfLottie || [];
  window.__hfLottie.push(player);
</script>

The HF adapter handles both player APIs (it duck-types goToAndStop vs setCurrentRawFrameValue / seek).

Multiple Lottie animations

Multiple <Lottie> instances in one composition work — push each one onto window.__hfLottie and the adapter will seek all of them in sync:

window.__hfLottie.push(anim1);
window.__hfLottie.push(anim2);
window.__hfLottie.push(anim3);

Lottie source isn't actually translation-blocking

Lottie animations encode their own deterministic timeline. They're the easiest part of a Remotion composition to translate because the animation logic is already self-contained — neither Remotion nor HF "animate" them, both just seek them. Translation cost is near-zero.

After Effects → Lottie limitations

Lottie supports a subset of After Effects features. Expressions, most Effects (drop shadow, color overlay), all blend modes beyond Normal/Add/ Multiply, luma mattes, and most 3D parameters are not supported. If the Remotion composition uses a Lottie file that depends on these, the animation will break in BOTH Remotion and HF — this isn't a translation problem, it's a Lottie limitation. See airbnb/lottie/after-effects.md for the full supported feature list.

Loop behavior

Remotion's loop={true} plays the animation continuously. Translate to the lottie-web loop: true setting AND rely on the adapter's natural seek behavior (it'll seek modulo the animation's duration). For non-default playback rates, set playbackRate in loadAnimation and HF will respect it during seek.

Performance note

Per the Lottie adapter docs: lottie-web's goToAndStop(time, isFrame=false) takes time in ms; the adapter passes time * 1000 for precision. This is more accurate than passing frame numbers (especially for animations whose internal fps doesn't match the HF render fps).