PTENES
MODULE 3.1

⏱️ Timing & Synchronization

The difference between a chaotic scene and a choreographed scene is timing. Here you'll learn to stagger entrances with Sequence from=, creating stagger with index * N and synchronize elements so each one gets its moment.

6
Topics
40
Minutes
Intermediate
Level
Practice
Type
frames 0 5 10 15 → total duration item 0 · from={0} item 1 · from={5} item 2 · from={10} Stagger: each item enters N frames later → natural cascade
1

🎬 Sequence from= — the time offset

The prop from of the Sequence is simple and powerful: it specifies the frame where this block starts existing in the video. Before that frame, the child component simply isn’t rendered. Afterward, the local frame starts at zero—as if the clock reset for that element.

🎯 The central idea

Inside a Sequence, useCurrentFrame() returns 0 at the frame from, 1 on the frame from+1, and so on. This means animations inside Sequences are always relative to their start — not at the start of the video.

  • •The child does not exist before frame from — it isn't rendered or take up space.
  • •The local frame within the Sequence always starts at 0.
  • •Combine with durationInFrames also limits the end of its existence.
Basic Sequence with from= StaggedEntry.tsx
import { Sequence, useCurrentFrame, spring, useVideoConfig } from "remotion";

export const StaggedEntry = () => {
  const { fps } = useVideoConfig();

  return (
    <>
      {/* Título aparece imediatamente */}
      <Sequence from={0}>
        <Title />
      </Sequence>

      {/* Subtítulo entra 15 frames depois */}
      <Sequence from={15}>
        <Subtitle />
      </Sequence>

      {/* Lista entra após 30 frames */}
      <Sequence from={30}>
        <ItemList />
      </Sequence>
    </>
  );
};

💡 Practical tip

Drag the Remotion Studio timeline bar to frame 14 — the Subtitle doesn’t exist yet. Go to 15 — it appears. This direct visual control is the best way to calibrate your offsets.

from=
Delay in frames
Local frame
Resets to 0
Before the from
Doesn’t render
Base of
Every stagger
2

🪜 Stagger with index * N

The stagger pattern is the most common in animated lists, menus, and grids: each item gets a from based on its index multiplied by a constant N. The result feels like a “cascade”—the elements enter one after another naturally.

✓ What to DO

  • ✓Use from={index * N} where N = 4 to 8 frames.
  • ✓Combine with a local spring() for each smooth entrance.
  • ✓Use small N values for long lists (to avoid long waits).

✗ What NOT to do

  • ✗N too large (>15) makes the list take too long to complete.
  • ✗Stagger for items the viewer doesn't follow in order.
  • ✗Forgetting to add the offset to from from the parent group.
Classic stagger with spring StaggeredList.tsx
const items = ["React", "Remotion", "TypeScript", "Vite"];
const STAGGER = 6; // frames entre cada entrada

return (
  <>
    {items.map((item, index) => (
      <Sequence key={item} from={index * STAGGER}>
        <AnimatedItem text={item} />
      </Sequence>
    ))}
  </>
);

// Dentro de AnimatedItem:
const frame = useCurrentFrame(); // começa em 0 para cada item
const { fps } = useVideoConfig();
const scale = spring({ frame, fps, config: { damping: 14 } });
const opacity = interpolate(frame, [0, 8], [0, 1], { extrapolateRight: "clamp" });
Ideal N
4–8 frames
List of 4 items
N=6 → 18 frames
local spring
Starts at 0
Effect
Natural cascade
3

🔗 Sync End with Start — Overlap

One of the most effective timing techniques is to make element B start while A is still exiting. This intentional overlap eliminates the “gap” of an empty screen and smoothly shifts the viewer’s attention from one element to another.

1

Calculate the from value for element A

Ex: TITLE_START = 0, TITLE_DUR = 60 (frames the title stays visible).

2

Define the desired overlap

Typically 8–12 frames. Too much overlap creates confusion; too little doesn’t feel smooth.

3

Derive B's from

LIST_START = TITLE_START + TITLE_DUR - OVERLAP — B starts before A ends.

4

Test in Studio

Drag the playhead through the overlap frames and check that neither element visually “competes” — one should dominate.

💡 Practical tip

If element A has an animated fade-out (opacity 1→0 in the last 10 frames), activate B exactly when A starts fading. The viewer perceives the transition without noticing the cut.

Overlap
8–12 frames
Formula
from_A + dur_A - N
Effect
No blank screen
Limit
1 element dominates
4

🧮 Named Constants — No Magic Numbers

Clean timing code declares all offsets as named constants at the top of the component. That way, when you need to adjust "the title takes a little longer," you only change TITLE_DUR — and all elements that depend on it recalculate automatically.

Derived constants TimedScene.tsx
// ✅ Constantes no topo — fáceis de ajustar
const TITLE_START  = 0;
const TITLE_DUR    = 45;
const OVERLAP      = 10;
const SUBTITLE_START = TITLE_START + TITLE_DUR - OVERLAP; // 35
const LIST_START   = SUBTITLE_START + 30;               // 65

// ❌ Magic numbers — impossível de manter
// <Sequence from={35}> ← por que 35? ninguém sabe
// <Sequence from={65}> ← muda TITLE_DUR e quebra

✓ Advantages of constants

  • ✓Changing 1 number propagates to all dependents.
  • ✓Self-documenting code: SUBTITLE_START speaks for itself.
  • ✓Easy to extract into props and make the template configurable.

✗ The problem with magic numbers

  • ✗Changing one duration means hunting down and calculating all the following ones.
  • ✗from={47} — impossible to know where it came from without debugging.
  • ✗Common bug: two elements that should stay in sync drift out of sync.
Pattern
Constants at the top
Derive
A + B = C
Avoid
Standalone numbers
Gain
Easy maintenance
5

👁️ Avoid starting everything at frame 0

The most common mistake beginners make when combining elements is not using from= in any of them — the result: everything appears simultaneously on frame 0. For viewers, it’s like receiving a shout instead of an introduction.

⚠️ What happens without timing

  • ✗Title, subtitle, icon, and list all animate together at frame 0 — visual congestion.
  • ✗Each element's spring competes for attention at the same instant.
  • ✗The visual hierarchy disappears—the viewer can't tell what's important.

✅ Priority rule

Sort elements by importance and define a from increasing for each:

  • 1.Frame 0: the most important element (logo, main title).
  • 2.Frame 10–15: supporting element (subtitle, description).
  • 3.Frame 20+: secondary elements (list, icons, decoration).
Frame 0
Main element only
Frame 10-15
Support
Frame 20+
Details
Result
Clear hierarchy
6

⚡ Timing with spring inside Sequence

The Sequence + spring combination is the most natural starting pattern in Remotion. Since each Sequence's local frame starts at 0, the spring "starts fresh" for each element—regardless of when the Sequence was opened on the timeline.

Complete stagger with spring StaggerSpring.tsx
const Item = ({ label }: { label: string }) => {
  const frame = useCurrentFrame(); // sempre 0 no primeiro frame do item
  const { fps } = useVideoConfig();

  const progress = spring({
    frame,
    fps,
    config: { damping: 12, stiffness: 120 },
  });

  return (
    <div style={{
      opacity: progress,
      transform: `translateY(${(1 - progress) * 20}px)`,
    }}>
      {label}
    </div>
  );
};

// No componente pai — stagger automático:
{["A", "B", "C"].map((l, i) => (
  <Sequence key={l} from={i * 5}>
    <Item label={l} />
  </Sequence>
))}

💡 Why this is powerful

Each Item is completely independent — you can reorder the array, add or remove items, and the stagger recalculates automatically. No code depends on any element's absolute position on the timeline.

Local frame
0 on each entrance
spring
Independent spring
Reuse
Generic component
Usage
70% of templates

📌 Module summary

✓
Sequence from= — delay in frames; local frame resets to 0 inside each Sequence.
✓
Stagger index * N — N = 4–8 frames for a natural cascade in lists and grids.
✓
Controlled overlap — starting B before A finishes eliminates blank screens and creates flow.
✓
Named constants — never use magic numbers; derive offsets from the base constants.
✓
spring + Sequence — standard combination of staggered entrance used in 70% of templates.

Next module:

3.2 — Layers & Visual Composition: stacked AbsoluteFill, layer order, and how to maintain legibility.