🌊 spring() — simulação de mola
O spring() não recebe um inputRange e outputRange — ele simula física. Dado o frame atual e o fps, calcula um valor que parte de 0, vai em direção a 1, passa um pouco de 1 (overshoot) e depois assenta. É esse bounce que dá vida à animação.
🎯 Chamada mínima
import { spring, useCurrentFrame, useVideoConfig } from "remotion"; const frame = useCurrentFrame(); const { fps } = useVideoConfig(); // retorna 0 → 1 (com overshoot natural) const progress = spring({ frame, fps }); return <div style={{ transform: `scale(${progress})` }}>Pop!</div>;
📊 spring() vs interpolate() — saídas diferentes
- interpolate: você controla cada keyframe; movimento é previsível e exato.
- spring: você define a física; o movimento emerge da simulação com naturalidade.
- O spring retorna um valor ≈ 0→1, mas pode ultrapassar 1 antes de assentar — isso é o overshoot.
⚙️ config: damping, stiffness e mass
O comportamento da mola é ajustado pelo objeto config. Três parâmetros principais: damping (amortecimento), stiffness (rigidez) e mass (peso). Combinando os três, você vai de um pop rápido a uma oscilação longa e suave.
damping — amortecimento (padrão: 10)
Alto (ex.: 200): sem overshoot, movimento direto como um CSS ease-out. Baixo (ex.: 5): muita oscilação, efeito "trampolim".
stiffness — rigidez (padrão: 100)
Alto (ex.: 300): movimento mais rápido e agressivo. Baixo (ex.: 40): movimenta-se mais devagar, mola "frouxa".
mass — peso (padrão: 1)
Alto (ex.: 3): "objeto pesado", movimento lento com mais oscilação. Baixo (ex.: 0.5): objeto leve, resolve rápido.
// Pop rápido sem bounce spring({ frame, fps, config: { damping: 200 } }) // Bounce divertido spring({ frame, fps, config: { damping: 8, stiffness: 120 } }) // Entrada pesada e lenta spring({ frame, fps, config: { damping: 15, stiffness: 60, mass: 2.5 } })
⚖️ spring vs interpolate — quando usar cada um
As duas funções servem propósitos diferentes. A escolha certa poupa tempo e deixa o vídeo mais polido. Uma regra simples: spring para entradas com vida, interpolate para timing exato e fades.
✓ Use spring() quando…
- ✓Elemento "pula" para a posição — ícone, badge, card de entrada.
- ✓Você quer overshoot natural sem definir keyframes manualmente.
- ✓Scale de 0→1 com bounce (logo aparecendo).
↔ Use interpolate() quando…
- →Fade-in/out com timing exato (você sabe o frame certo).
- →Cor, opacidade — valores que não devem ultrapassar um limite.
- →Animação com múltiplos keyframes (hold, sequência).
💡 Combine os dois!
É muito comum usar spring() para a escala de entrada e interpolate() para a opacidade do mesmo elemento — cada um onde brilha. Não há conflito em chamar os dois no mesmo componente.
⏩ Sequence — cenas com atraso e frame local
O <Sequence> é um wrapper que atrasa o início de um componente filho. Com a prop from, o filho só começa a existir no frame especificado — e, crucialmente, o frame local dentro do filho reinicia em 0 naquele ponto.
import { Sequence } from "remotion"; // Título 1: frame global 0–59 → frame local 0–59 <Sequence from={0} durationInFrames={60}> <Title1 /> // useCurrentFrame() aqui retorna 0..59 </Sequence> // Título 2: começa no frame global 60 → frame local reinicia em 0 <Sequence from={60} durationInFrames={60}> <Title2 /> // useCurrentFrame() aqui também retorna 0..59 </Sequence>
✓ O que FAZER com Sequence
- ✓Usar
frompara atrasar qualquer componente sem mudar o código interno. - ✓Usar
durationInFramespara limitar a janela de visibilidade do filho. - ✓Reutilizar o mesmo componente em múltiplas Sequences com offsets diferentes.
✗ O que NÃO fazer
- ✗Usar
frame - offsetmanualmente no componente filho — Sequence já faz isso. - ✗Deixar de usar
durationInFrames: o filho fica "vivo" para sempre (visível após o seu tempo). - ✗Confundir frame global com frame local — dentro de Sequence o clock reinicia.
🪟 AbsoluteFill — empilhamento de camadas
O <AbsoluteFill> é um div que ocupa 100% da largura e altura da composição, com position: absolute. Empilhado com outros AbsoluteFills, ele cria camadas — fundo, conteúdo, overlay — sem interferência de layout.
🎯 A estrutura de três camadas
import { AbsoluteFill } from "remotion"; export const Scene = () => ( <> {/* Camada 1 — fundo (z mais baixo) */} <AbsoluteFill style={{ backgroundColor: "#0a0a0a" }} /> {/* Camada 2 — conteúdo principal */} <AbsoluteFill> <div>Título e elementos</div> </AbsoluteFill> {/* Camada 3 — overlay (z mais alto) */} <AbsoluteFill style={{ opacity: 0.15, background: "radial-gradient(...)" }} /> </> );
💡 Ordem = z-index implícito
No React, elementos irmãos com position: absolute e mesmo z-index se sobrepõem pela ordem no JSX: o último fica na frente. AbsoluteFills em sequência criam uma pilha de camadas previsível — não precisa de z-index explícito na maioria dos casos.
🎞️ Series.Sequence — cenas em fila automática
Com o <Series>, você não precisa calcular manualmente o from de cada cena. Coloque filhos dentro de <Series.Sequence durationInFrames={N}> e o Remotion calcula os offsets automaticamente. É a base de qualquer projeto com múltiplas cenas da Trilha 4.
import { Series } from "remotion"; export const MyVideo = () => ( <Series> {/* Cena 1: frames 0–89 */} <Series.Sequence durationInFrames={90}> <Intro /> </Series.Sequence> {/* Cena 2: frames 90–179 (calculado auto) */} <Series.Sequence durationInFrames={90}> <MainContent /> </Series.Sequence> {/* Cena 3: frames 180–269 */} <Series.Sequence durationInFrames={90}> <Outro /> </Series.Sequence> </Series> );
✓ Vantagens de Series
- ✓Offsets calculados automaticamente — adicionar cena não quebra as outras.
- ✓Cada cena recebe frame local reiniciado em 0 — mesma lógica do Sequence.
- ✓Estrutura declarativa: a ordem no JSX = a ordem no vídeo.
↔ Series vs Sequence manual
- →Series: cenas lineares em fila — projetos com cortes diretos.
- →Sequence manual: camadas simultâneas sobrepostas, timing fino.
- →Projetos reais costumam usar os dois: Series para cenas, Sequence para elementos internos.
📌 Resumo do módulo
from; frame local reinicia em 0 dentro do filho.Próxima trilha:
Trilha 2 — Recursos: imagens, vídeos, áudio, fontes e assets externos no Remotion. Você já domina o motor; agora vem o combustível.