Files
hyperframes/skills/remotion-to-hyperframes/references/transitions.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.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:

  1. Manual GSAP crossfade — for simple opacity/transform transitions. Free, no extra package.
  2. 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).