packages/template-prompt-to-motion-graphics/src/skills/sequencing.md
Use Sequence to delay when an element appears in the timeline.
Incorrect (manual frame checks):
{
frame >= 30 && <Title />;
}
{
frame >= 60 && <Subtitle />;
}
Correct (Sequence component):
import { Sequence } from "remotion";
<Sequence from={30} durationInFrames={90}>
<Title />
</Sequence>
<Sequence from={60} durationInFrames={60}>
<Subtitle />
</Sequence>
Use Series when elements should play one after another without overlap.
import { Series } from "remotion";
<Series>
<Series.Sequence durationInFrames={45}>
<Intro />
</Series.Sequence>
<Series.Sequence durationInFrames={60}>
<MainContent />
</Series.Sequence>
<Series.Sequence durationInFrames={30}>
<Outro />
</Series.Sequence>
</Series>;
Use negative offset for overlapping sequences:
<Series>
<Series.Sequence durationInFrames={60}>
<SceneA />
</Series.Sequence>
<Series.Sequence offset={-15} durationInFrames={60}>
<SceneB />
</Series.Sequence>
</Series>
For staggered animations of multiple items, calculate delays:
Incorrect (hardcoded delays):
const items = data.map((item, i) => {
const delay = i === 0 ? 0 : i === 1 ? 10 : i === 2 ? 20 : 30;
// ...
});
Correct (calculated stagger):
const STAGGER_DELAY = 8;
const BASE_DELAY = 15;
const items = data.map((item, i) => {
const delay = BASE_DELAY + i * STAGGER_DELAY;
const progress = spring({
frame: frame - delay,
fps,
config: { damping: 15, stiffness: 120 },
});
return (
<Item
key={i}
style={{
opacity: progress,
transform: `translateY(${(1 - progress) * 20}px)`,
}}
/>
);
});
Sequences can be nested for complex timing:
<Sequence from={0} durationInFrames={120}>
<Background />
<Sequence from={15} durationInFrames={90}>
<Title />
</Sequence>
<Sequence from={45} durationInFrames={60}>
<Subtitle />
</Sequence>
</Sequence>
Inside a Sequence, useCurrentFrame() returns the local frame (starting from 0):
<Sequence from={60} durationInFrames={30}>
<MyComponent />
</Sequence>