MÓDULO 1.3

🌊 spring & composição

O spring() simula física de mola para animações com vida própria. Sequence e AbsoluteFill empilham cenas em camadas. Juntos, formam a base de todo projeto da Trilha 4.

6
Tópicos
40
Minutos
Básico
Nível
Prático
Tipo
frame valor 1.0 overshoot spring({ frame, fps, config: { damping } }) damping baixo → mais oscilação (overshoot pronunciado)
1

🌊 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.
Entrada
frame + fps
Saída
≈ 0 → 1
Overshoot
Ultrapassa 1 brevemente
Física
Simulação de mola
2

⚙️ 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.

D

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".

S

stiffness — rigidez (padrão: 100)

Alto (ex.: 300): movimento mais rápido e agressivo. Baixo (ex.: 40): movimenta-se mais devagar, mola "frouxa".

M

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.

Variações de config SpringConfig.tsx
// 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 } })
damping alto
Sem bounce
damping baixo
Muita oscilação
stiffness
Velocidade da mola
mass
Peso do objeto
3

⚖️ 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.

spring
Entradas com pop
interpolate
Timing exato
Combinação
Sem conflito
Regra
Física vs keyframe
4

⏩ 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.

Dois títulos em sequência Titles.tsx
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 from para atrasar qualquer componente sem mudar o código interno.
  • Usar durationInFrames para 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 - offset manualmente 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.
from
Offset de início
durationInFrames
Janela de visibilidade
Frame local
Reinicia em 0
Reutilizável
Mesmo comp, N vezes
5

🪟 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.

100% × 100%
Preenche composição
position: absolute
Sem afetar layout
Ordem JSX
= z implícito
Empilhar
Fundo/conteúdo/overlay
6

🎞️ 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.

Três cenas sem calcular offset Video.tsx
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.
Series
Cenas em fila
Auto-offset
Sem cálculo manual
Frame local
Reinicia por cena
Base T4
Todos os projetos

📌 Resumo do módulo

spring({ frame, fps }) — simula mola, retorna 0→1 com overshoot natural; perfeito para entradas com vida.
config: damping / stiffness / mass — damping alto elimina bounce; stiffness define velocidade; mass define inércia.
spring vs interpolate — spring para pop/entrada; interpolate para timing exato e opacidade. Combine os dois sem problema.
Sequence — atrasa o início de um componente com from; frame local reinicia em 0 dentro do filho.
AbsoluteFill — preenche 100% da composição; empilhado em camadas fundo/conteúdo/overlay pela ordem JSX.
Series.Sequence — cenas em fila com offsets automáticos; base de todos os projetos da Trilha 4.

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.