Skill Index

claude-code-video-toolkit/

transitions

community[skill]

Scene transitions and overlays for Remotion using TransitionSeries.

$/plugin install claude-code-video-toolkit

details

TransitionSeries

<TransitionSeries> arranges scenes and supports two ways to enhance the cut point between them:

  • Transitions (<TransitionSeries.Transition>) — crossfade, slide, wipe, etc. between two scenes. Shortens the timeline because both scenes play simultaneously during the transition.
  • Overlays (<TransitionSeries.Overlay>) — render an effect (e.g. a light leak) on top of the cut point without shortening the timeline.

Children are absolutely positioned.

Prerequisites

npx remotion add @remotion/transitions

Transition example

import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";

<TransitionSeries>
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneA />
  </TransitionSeries.Sequence>
  <TransitionSeries.Transition
    presentation={fade()}
    timing={linearTiming({ durationInFrames: 15 })}
  />
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneB />
  </TransitionSeries.Sequence>
</TransitionSeries>;

Overlay example

Any React component can be used as an overlay. For a ready-made effect, see the light-leaks rule.

import { TransitionSeries } from "@remotion/transitions";
import { LightLeak } from "@remotion/light-leaks";

<TransitionSeries>
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneA />
  </TransitionSeries.Sequence>
  <TransitionSeries.Overlay durationInFrames={20}>
    <LightLeak />
  </TransitionSeries.Overlay>
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneB />
  </TransitionSeries.Sequence>
</TransitionSeries>;

Mixing transitions and overlays

Transitions and overlays can coexist in the same <TransitionSeries>, but an overlay cannot be adjacent to a transition or another overlay.

import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
import { LightLeak } from "@remotion/light-leaks";

<TransitionSeries>
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneA />
  </TransitionSeries.Sequence>
  <TransitionSeries.Overlay durationInFrames={30}>
    <LightLeak />
  </TransitionSeries.Overlay>
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneB />
  </TransitionSeries.Sequence>
  <TransitionSeries.Transition
    presentation={fade()}
    timing={linearTiming({ durationInFrames: 15 })}
  />
  <TransitionSeries.Sequence durationInFrames={60}>
    <SceneC />
  </TransitionSeries.Sequence>
</TransitionSeries>;

Transition props

<TransitionSeries.Transition> requires:

  • presentation — the visual effect (e.g. fade(), slide(), wipe()).
  • timing — controls speed and easing (e.g. linearTiming(), springTiming()).

Overlay props

<TransitionSeries.Overlay> accepts:

  • durationInFrames — how long the overlay is visible (positive integer).
  • offset? — shifts the overlay relative to the cut point center. Positive = later, negative = earlier. Default: 0.

Available transition types

Import transitions from their respective modules:

import { fade } from "@remotion/transitions/fade";
import { slide } from "@remotion/transitions/slide";
import { wipe } from "@remotion/transitions/wipe";
import { flip } from "@remotion/transitions/flip";
import { clockWipe } from "@remotion/transitions/clock-wipe";

Slide transition with direction

import { slide } from "@remotion/transitions/slide";

<TransitionSeries.Transition
  presentation={slide({ direction: "from-left" })}
  timing={linearTiming({ durationInFrames: 20 })}
/>;

Directions: "from-left", "from-right", "from-top", "from-bottom"

Timing options

import { linearTiming, springTiming } from "@remotion/transitions";

// Linear timing - constant speed
linearTiming({ durationInFrames: 20 });

// Spring timing - organic motion
springTiming({ config: { damping: 200 }, durationInFrames: 25 });

Duration calculation

Transitions overlap adjacent scenes, so the total composition length is shorter than the sum of all sequence durations. Overlays do not affect the total duration.

For example, with two 60-frame sequences and a 15-frame transition:

  • Without transitions: 60 + 60 = 120 frames
  • With transition: 60 + 60 - 15 = 105 frames

Adding an overlay between two other sequences does not change the total.

Getting the duration of a transition

Use the getDurationInFrames() method on the timing object:

import { linearTiming, springTiming } from "@remotion/transitions";

const linearDuration = linearTiming({
  durationInFrames: 20,
}).getDurationInFrames({ fps: 30 });
// Returns 20

const springDuration = springTiming({
  config: { damping: 200 },
}).getDurationInFrames({ fps: 30 });
// Returns calculated duration based on spring physics

For springTiming without an explicit durationInFrames, the duration depends on fps because it calculates when the spring animation settles.

Calculating total composition duration

import { linearTiming } from "@remotion/transitions";

const scene1Duration = 60;
const scene2Duration = 60;
const scene3Duration = 60;

const timing1 = linearTiming({ durationInFrames: 15 });
const timing2 = linearTiming({ durationInFrames: 20 });

const transition1Duration = timing1.getDurationInFrames({ fps: 30 });
const transition2Duration = timing2.getDurationInFrames({ fps: 30 });

const totalDuration =
  scene1Duration +
  scene2Duration +
  scene3Duration -
  transition1Duration -
  transition2Duration;
// 60 + 60 + 60 - 15 - 20 = 145 frames

technical

github
digitalsamba/claude-code-video-toolkit
stars
928
license
MIT
contributors
1
last commit
2026-04-20T10:52:53Z
file
.claude/skills/remotion-official/rules/transitions.md

related