Skill 32 · Remotion To Hyperframes
Subchapter 32.6
references/lottie.mdMarkdown4 KBView on GitHub
Lottie animations are a clean translation case — HF has a built-in Lottie adapter that supports both and . The adapter auto-discovers animations registered on and seeks them per-frame via .
Scripts
Gitkeepscriptslottie-web@lottiefiles/dotlottie-webwindow.__hfLottiegoToAndStopimport { 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 seekingloop: false typically (unless Remotion’s loop={true})window.__hfLottie.push(anim) is what hooks the animation into HF’s
per-frame seekRemotion bundles the animation JSON via webpack import. HF needs the JSON
on disk under assets/ and references it via path:
hello.json from the Remotion project into hf-src/assets/.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> 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 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.
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 (opens in a new tab) for the full supported feature list.
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.
Per the Lottie adapter (opens in a new tab)
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).