MÓDULO 3.1

⏱️ Timing & Sincronização

A diferença entre uma cena caótica e uma cena coreografada é o timing. Aqui você aprende a escalonar entradas com Sequence from=, criar stagger com index * N e sincronizar elementos para que cada um tenha seu momento.

6
Tópicos
40
Minutos
Intermediário
Nível
Prática
Tipo
frames 0 5 10 15 → duração total item 0 · from={0} item 1 · from={5} item 2 · from={10} Stagger: cada item entra N frames depois → cascata natural
1

🎬 Sequence from= — o offset de tempo

O prop from da Sequence é simples e poderoso: diz em que frame do vídeo esse bloco começa a existir. Antes desse frame, o componente filho simplesmente não é renderizado. Depois, o frame local começa em zero — como se o relógio reiniciasse para aquele elemento.

🎯 A ideia central

Dentro de uma Sequence, useCurrentFrame() devolve 0 no frame from, 1 no frame from+1, e assim por diante. Isso significa que animações dentro de Sequences são sempre relativas ao início delas — não ao início do vídeo.

  • O filho não existe antes do frame from — não é renderizado nem ocupa espaço.
  • O frame local dentro da Sequence sempre começa em 0.
  • Combinar com durationInFrames limita também o fim da existência.
Sequence com from= básico 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>
    </>
  );
};

💡 Dica prática

Arraste a barra de tempo do Remotion Studio para o frame 14 — o Subtitle ainda não existe. Vá para 15 — aparece. Esse controle visual direto é a melhor forma de calibrar seus offsets.

from=
Delay em frames
Frame local
Reinicia em 0
Antes do from
Não renderiza
Base de
Todo stagger
2

🪜 Stagger com index * N

O padrão de stagger é o mais recorrente em listas, menus e grids animados: cada item recebe um from baseado no seu índice multiplicado por uma constante N. O resultado é a sensação de "cascata" — os elementos entram um depois do outro de forma natural.

✓ O que FAZER

  • Usar from={index * N} onde N = 4 a 8 frames.
  • Combinar com spring() local para cada entrada suave.
  • Usar valores pequenos de N para listas longas (evitar espera longa).

✗ O que NÃO fazer

  • N muito grande (>15) faz a lista demorar demais para completar.
  • Stagger em itens que o espectador não acompanha na ordem.
  • Esquecer de somar o offset ao from do grupo pai.
Stagger clássico com 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" });
N ideal
4–8 frames
Lista 4 itens
N=6 → 18 frames
spring local
Começa em 0
Efeito
Cascata natural
3

🔗 Sincronizar fim com início — overlap

Uma das técnicas mais eficazes de timing é fazer o elemento B começar enquanto o A ainda está saindo. Essa sobreposição intencional elimina o "buraco" de tela vazia e passa a atenção do espectador de forma suave de um elemento para o outro.

1

Calcule o from do elemento A

Ex: TITLE_START = 0, TITLE_DUR = 60 (frames que o título fica visível).

2

Defina o overlap desejado

Tipicamente 8–12 frames. Overlap muito longo cria confusão; muito curto não gera fluidez.

3

Derive o from de B

LIST_START = TITLE_START + TITLE_DUR - OVERLAP — B começa antes de A acabar.

4

Teste no Studio

Arraste o playhead pelos frames do overlap e verifique que nenhum dos dois elementos "compete" visualmente — um deve dominar.

💡 Dica prática

Se o elemento A tem um fade-out animado (opacidade 1→0 nos últimos 10 frames), ative o B exatamente quando A começa esse fade. O espectador percebe a transição mas não sente o corte.

Overlap
8–12 frames
Fórmula
from_A + dur_A - N
Efeito
Sem tela vazia
Limite
1 elemento domina
4

🧮 Constantes nomeadas — sem magic numbers

Um código de timing limpo declara todos os offsets como constantes nomeadas no topo do componente. Assim, quando você precisa ajustar "o título demora um pouco mais", só muda TITLE_DUR — e todos os elementos que dependem dele se recalculam automaticamente.

Constantes derivadas 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

✓ Vantagens das constantes

  • Mudar 1 número propaga para todos os dependentes.
  • Código auto-documentado: SUBTITLE_START fala por si.
  • Fácil de extrair para props e tornar o template configurável.

✗ Problema dos magic numbers

  • Mudar uma duração requer caçar e calcular todos os subsequentes.
  • from={47} — impossível saber de onde veio sem depurar.
  • Bug frequente: dois elementos que deveriam sincronisar ficam dessincronizados.
Padrão
Constantes no topo
Derivar
A + B = C
Evitar
Números soltos
Ganho
Manutenção fácil
5

👁️ Evitar tudo no frame 0

O erro mais comum de quem começa a combinar elementos é não usar from= em nenhum deles — resultado: todos aparecem simultaneamente no frame 0. Para o espectador, é como receber um grito em vez de uma apresentação.

⚠️ O que acontece sem timing

  • Título, subtítulo, ícone e lista animam juntos no frame 0 — congestionamento visual.
  • O spring de cada elemento compete pela atenção no mesmo instante.
  • A hierarquia visual desaparece — o espectador não sabe o que é importante.

Regra das prioridades

Ordene os elementos por importância e defina um from crescente para cada:

  • 1.Frame 0: o elemento mais importante (logo, título principal).
  • 2.Frame 10–15: elemento de suporte (subtítulo, descrição).
  • 3.Frame 20+: elementos secundários (lista, ícones, decoração).
Frame 0
Só o principal
Frame 10-15
Suporte
Frame 20+
Detalhes
Resultado
Hierarquia clara
6

⚡ Timing com spring dentro de Sequence

A combinação de Sequence + spring é o padrão de entrada mais natural do Remotion. Como o frame local de cada Sequence começa em 0, o spring "dispara fresquinho" para cada elemento — independentemente de quando a Sequence foi aberta na linha do tempo.

Stagger completo com 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>
))}

💡 Por que isso é poderoso

Cada Item é completamente independente — você pode reordenar o array, adicionar ou remover itens, e o stagger se recalcula automaticamente. Não há código que dependa da posição absoluta de nenhum elemento na linha do tempo.

Frame local
0 em cada entrada
spring
Mola independente
Reuso
Componente genérico
Uso
70% dos templates

📌 Resumo do módulo

Sequence from= — delay em frames; frame local reinicia em 0 dentro de cada Sequence.
Stagger index * N — N = 4–8 frames para cascata natural em listas e grids.
Overlap controlado — iniciar B antes de A terminar elimina tela vazia e cria fluidez.
Constantes nomeadas — nunca magic numbers; derivar offsets a partir das constantes base.
spring + Sequence — combinação padrão de entrada escalonada usada em 70% dos templates.

Próximo módulo:

3.2 — Camadas & Composição Visual: AbsoluteFill empilhado, ordem de camadas e como manter legibilidade.