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.4 KiB
Transitions translation: @remotion/transitions → HF crossfades / shader-transitions
The @remotion/transitions package is Remotion's library of pre-built
scene-to-scene transitions. HF has two paths to translate them:
- Manual GSAP crossfade — for simple opacity/transform transitions. Free, no extra package.
- HF shader-transitions package — for visually-rich transitions that match the @remotion/transitions presets.
Pattern: <TransitionSeries> is <Series> with overlap
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60}>
<SceneA />
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={fade()}
timing={linearTiming({ durationInFrames: 15 })}
/>
<TransitionSeries.Sequence durationInFrames={60}>
<SceneB />
</TransitionSeries.Sequence>
</TransitionSeries>
Translates to scenes that overlap by the transition duration:
- SceneA: [0, 60] =
data-start="0" data-duration="2" - SceneB: [60-15, 60-15+60] =
data-start="1.5" data-duration="2"(the transition window overlaps the end of A and start of B)
Then drive the transition with GSAP:
// Manual fade (presentation={fade()})
tl.to(sceneA, { opacity: 0, duration: 0.5, ease: "none" }, 1.5);
tl.fromTo(sceneB, { opacity: 0 }, { opacity: 1, duration: 0.5, ease: "none" }, 1.5);
Presentation table
Remotion presentation |
HF translation |
|---|---|
fade() |
manual gsap.to(opacity) crossfade |
slide({direction: "from-right"}) |
gsap.fromTo(translateX: "100%" → 0) on incoming + to(translateX: "-100%") on outgoing |
wipe({direction: "from-left"}) |
gsap.fromTo(clip-path: inset(0 100% 0 0) → inset(0 0 0 0)) on incoming |
clockWipe() |
use HF's sdf-iris shader-transition (npx hyperframes add sdf-iris) |
flip() |
gsap.to(rotateY) 180° split between scenes |
cube() |
use HF's cinematic-zoom or build manually with rotateY + transform-origin |
iris() |
use HF's sdf-iris shader-transition |
none() |
no transition; hard cut at the boundary |
Timing translations
linearTiming({durationInFrames: 15}) → ease: "none"
linearTiming({durationInFrames: 15, easing: ...}) → ease per the easing table in timing.md
springTiming({config: {damping: 12}}) → ease: "back.out(1.4)" (~0.7 s)
Convert durationInFrames to seconds (/fps).
When to use HF shader-transitions
For transitions Remotion presets that have visually-rich GLSL equivalents (iris, ripple, zoom, glitch), use HF's shader-transitions package. They produce richer output than manual GSAP transforms.
npx hyperframes add sdf-iris
Then in the composition:
<div id="iris-transition" class="hf-shader-transition" data-start="1.5" data-duration="0.5">
<!-- bound scenes via the shader-transition's data-from / data-to -->
</div>
Each shader-transition has its own data attributes; see the catalog page for the specific block.
When the source uses a custom Presentation
Remotion supports custom presentation implementations:
const customPresentation: PresentationComponent = ({
children,
presentationProgress,
presentationDirection,
}) => {
return (
<div
style={
{
/* compute transform from progress */
}
}
>
{children}
</div>
);
};
Translation: extract the math from the style={...} block and emit
equivalent GSAP tweens. Specifically the transform formula maps directly
to a gsap.to(target, { transform: ... }) parameterized by progress.
If the custom presentation uses useCurrentFrame() internally to
animate something outside the simple progress curve, treat the source
as untranslatable and bow out to the runtime interop pattern (see
escape-hatch.md).