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.
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 seekingloop: falsetypically (unless Remotion'sloop={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:
- Copy
hello.jsonfrom the Remotion project intohf-src/assets/. - Reference as
path: "assets/hello.json"inloadAnimation.
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).