← Files RemotionARCHIVED FILE
skills/remotion-best-practices/remotion-markup/transitions.md
7.42 KB · Oct 10, 2026 · 06:13 UTC
---
name: transitions
description: Scene transitions and overlays for Remotion using TransitionSeries.
metadata:
tags: transitions, overlays, fade, slide, wipe, scenes
---
## 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.
Set `premountFor={fps}` on every `<TransitionSeries.Sequence>` and
`<TransitionSeries.Overlay>`, using `fps` from `useVideoConfig()`. Premount
timed children inside those items as well. `<TransitionSeries.Transition>`
does not accept `premountFor`.
For a multi-scene timeline, keep the outer `<TransitionSeries>` visible in the
timeline. Studio favors the active scene sequence when the two have the same
full-frame canvas outline.
Children are absolutely positioned.
## Prerequisites
```bash
npx remotion add @remotion/transitions
```
## Transition example
```tsx
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<SceneA />
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={fade()}
timing={linearTiming({ durationInFrames: 15 })}
/>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<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.
```tsx
import {lightLeak} from '@remotion/effects/light-leak';
import {TransitionSeries} from '@remotion/transitions';
import {interpolate, Solid, useCurrentFrame, useVideoConfig} from 'remotion';
const LightLeakOverlay: React.FC = () => {
const frame = useCurrentFrame();
const {durationInFrames, fps, height, width} = useVideoConfig();
return (
<Solid
width={width}
height={height}
premountFor={fps}
effects={[
lightLeak({
progress: interpolate(frame, [0, durationInFrames - 1], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
}),
}),
]}
/>
);
};
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<SceneA />
</TransitionSeries.Sequence>
<TransitionSeries.Overlay durationInFrames={20} premountFor={fps}>
<LightLeakOverlay />
</TransitionSeries.Overlay>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<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.
```tsx
import {lightLeak} from '@remotion/effects/light-leak';
import {TransitionSeries, linearTiming} from '@remotion/transitions';
import {fade} from '@remotion/transitions/fade';
import {interpolate, Solid, useCurrentFrame, useVideoConfig} from 'remotion';
const LightLeakOverlay: React.FC = () => {
const frame = useCurrentFrame();
const {durationInFrames, fps, height, width} = useVideoConfig();
return (
<Solid
width={width}
height={height}
premountFor={fps}
effects={[
lightLeak({
progress: interpolate(frame, [0, durationInFrames - 1], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
}),
}),
]}
/>
);
};
<TransitionSeries>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<SceneA />
</TransitionSeries.Sequence>
<TransitionSeries.Overlay durationInFrames={30} premountFor={fps}>
<LightLeakOverlay />
</TransitionSeries.Overlay>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<SceneB />
</TransitionSeries.Sequence>
<TransitionSeries.Transition
presentation={fade()}
timing={linearTiming({ durationInFrames: 15 })}
/>
<TransitionSeries.Sequence durationInFrames={60} premountFor={fps}>
<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`.
- `premountFor` — set to `fps` for one second of premounting.
## Available transition types
Import transitions from their respective modules:
```tsx
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
```tsx
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
```tsx
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:
```tsx
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
```tsx
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
```
SHA-256: 198534edd0f7744a9e6fd37a149f1b2b294c770880e383af5d81a69f9939a2cb