Skill Tracer
Skills › HyperFrames › remotion-to-hyperframes › lottie.md

lottie.md

132 lines · skills/remotion-to-hyperframes/references/lottie.md at a595755

Open on GitHub
1# Lottie translation: @remotion/lottie → HF lottie adapter
2
3Lottie animations are a clean translation case — HF has a built-in
4[Lottie adapter](https://github.com/heygen-com/hyperframes/blob/main/packages/core/src/runtime/adapters/lottie.ts)
5that supports both `lottie-web` and `@lottiefiles/dotlottie-web`. The
6adapter auto-discovers animations registered on `window.__hfLottie`
7and seeks lottie-web via `goToAndStop` and current dotLottie players via `setFrame`.
8

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 lottie-web via goToAndStop and current dotLottie players via setFrame.

Raw lines 1 to 8
9## Pattern
11```tsx
12import { Lottie } from "@remotion/lottie";
13import animationData from "./hello.json";
15export const MyComp = () => (
16 <AbsoluteFill>
17 <Lottie animationData={animationData} loop={false} />
18 </AbsoluteFill>
19);
20```
22Translates to:
24```html
25<div id="stage" ...>
26 <div id="lottie-anim" style="width:100%;height:100%"></div>
27 <script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.12.2/lottie.min.js"></script>
28 <script>
29 const anim = lottie.loadAnimation({
30 container: document.getElementById("lottie-anim"),
31 renderer: "svg",
32 loop: false,
33 autoplay: false,
34 path: "assets/hello.json",
35 });
36 window.__hfLottie = window.__hfLottie || [];
37 window.__hfLottie.push(anim);
38 </script>
39</div>
40```
42Key differences from a typical Lottie embed:
44- `autoplay: false` — HF drives playback by seeking
45- `loop: false` typically (unless Remotion's `loop={true}`)
46- `window.__hfLottie.push(anim)` is what hooks the animation into HF's
47 per-frame seek

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
Raw lines 9 to 48
49## Asset handling
51Remotion bundles the animation JSON via webpack import. HF needs the JSON
52on disk under `assets/` and references it via path:
541. Copy the animation JSON from the Remotion project into the HyperFrames project’s assets folder.
552. Pass that local path to `loadAnimation`, as shown in the example above.
57For dotlottie (binary) format, use the ESM build of `@lottiefiles/dotlottie-web`.
58Before rendering, copy `dist/index.js` and `dist/dotlottie-player.wasm` from the
59same pinned release into `hf-src/lib/dotlottie-web/`. Version 0.81.0 provides:
61- https://unpkg.com/@lottiefiles/dotlottie-web@0.81.0/dist/index.js
62- https://unpkg.com/@lottiefiles/dotlottie-web@0.81.0/dist/dotlottie-player.wasm
64The package's CommonJS entry cannot run as a classic browser script. Set the
65local WASM URL before constructing the player; the render then loads the SDK,
66WASM and animation from project files.
68```html
69<canvas id="anim" style="width:100%;height:100%"></canvas>
70<script type="module">
71 import { DotLottie } from "./lib/dotlottie-web/index.js";
73 DotLottie.setWasmUrl(new URL("./lib/dotlottie-web/dotlottie-player.wasm", import.meta.url).href);
74 const player = new DotLottie({
75 canvas: document.getElementById("anim"),
76 src: "assets/hello.lottie",
77 autoplay: false,
78 loop: false,
79 renderConfig: { autoResize: false, freezeOnOffscreen: false },
80 });
81 window.__hfLottie = window.__hfLottie || [];
82 window.__hfLottie.push(player);
83</script>
84```
86The HF adapter supports `goToAndStop` for lottie-web, `setFrame` for current
87dotLottie players, and `setCurrentRawFrameValue` / `seek` for older player shapes.

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 the animation JSON from the Remotion project into the HyperFrames project’s assets folder.
  2. Pass that local path to loadAnimation, as shown in the example above.

For dotlottie (binary) format, use the ESM build of @lottiefiles/dotlottie-web. Before rendering, copy dist/index.js and dist/dotlottie-player.wasm from the same pinned release into hf-src/lib/dotlottie-web/. Version 0.81.0 provides:

  • https://unpkg.com/@lottiefiles/dotlottie-web@0.81.0/dist/index.js
  • https://unpkg.com/@lottiefiles/dotlottie-web@0.81.0/dist/dotlottie-player.wasm

The package's CommonJS entry cannot run as a classic browser script. Set the local WASM URL before constructing the player; the render then loads the SDK, WASM and animation from project files.

<canvas id="anim" style="width:100%;height:100%"></canvas>
<script type="module">
  import { DotLottie } from "./lib/dotlottie-web/index.js";

  DotLottie.setWasmUrl(new URL("./lib/dotlottie-web/dotlottie-player.wasm", import.meta.url).href);
  const player = new DotLottie({
    canvas: document.getElementById("anim"),
    src: "assets/hello.lottie",
    autoplay: false,
    loop: false,
    renderConfig: { autoResize: false, freezeOnOffscreen: false },
  });
  window.__hfLottie = window.__hfLottie || [];
  window.__hfLottie.push(player);
</script>

The HF adapter supports goToAndStop for lottie-web, setFrame for current dotLottie players, and setCurrentRawFrameValue / seek for older player shapes.

Raw lines 49 to 88
89## Multiple Lottie animations
91Multiple `<Lottie>` instances in one composition work — push each one
92onto `window.__hfLottie` and the adapter will seek all of them in sync:
94```js
95window.__hfLottie.push(anim1);
96window.__hfLottie.push(anim2);
97window.__hfLottie.push(anim3);
98```

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);
Raw lines 89 to 99
100## Lottie source isn't actually translation-blocking
102Lottie animations encode their own deterministic timeline. They're the
103_easiest_ part of a Remotion composition to translate because the
104animation logic is already self-contained — neither Remotion nor HF
105"animate" them, both just seek them. Translation cost is near-zero.

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.

Raw lines 100 to 106
107## After Effects → Lottie limitations
109Lottie supports a subset of After Effects features. Expressions, most
110Effects (drop shadow, color overlay), all blend modes beyond Normal/Add/
111Multiply, luma mattes, and most 3D parameters are not supported. If the
112Remotion composition uses a Lottie file that depends on these, the
113animation will break in BOTH Remotion and HF — this isn't a translation
114problem, it's a Lottie limitation. See
115[airbnb/lottie/after-effects.md](https://github.com/airbnb/lottie/blob/master/after-effects.md)
116for the full supported feature list.

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.

Raw lines 107 to 117
118## Loop behavior
120Remotion's `loop={true}` plays the animation continuously. Translate it
121to `loop: true` on the player: the HF adapter wraps composition time into
122the animation's own length, so the cycle repeats for the whole scene. It
123does not add playback-rate scaling; bake a non-default rate into the
124Lottie asset and verify the rendered output.

Loop behavior

Remotion's loop={true} plays the animation continuously. Translate it to loop: true on the player: the HF adapter wraps composition time into the animation's own length, so the cycle repeats for the whole scene. It does not add playback-rate scaling; bake a non-default rate into the Lottie asset and verify the rendered output.

Raw lines 118 to 125
126## Performance note
128Per the [Lottie adapter](https://github.com/heygen-com/hyperframes/blob/main/packages/core/src/runtime/adapters/lottie.ts)
129docs: lottie-web's `goToAndStop(time, isFrame=false)` takes time in ms;
130the adapter passes `time * 1000` for precision. This is more accurate
131than passing frame numbers (especially for animations whose internal
132fps doesn't match the HF render fps).

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).

Raw lines 126 to 132