✍️ Visão Geral — A categoria Texto
Texto animado não é opcional em vídeo — é o veículo principal de informação. A categoria Texto da biblioteca cobre 9 padrões distintos, de revelar letra a letra até onda senoidal e glitch RGB. Entender qual usar em qual contexto é o que separa um vídeo raso de um com identidade visual.
🎯 Quando usar animação de texto
Revelar informação progressivamente:
- →animated-text ou typewriter para dados que "chegam"
- →slide-text para entradas direcionais (slide-in)
Chamar atenção sobre texto existente:
- →pulsing-text para respiração suave contínua
- →glitch-text para estilo retro/hacker
✓ Quando o texto anima bem
- ✓Ritmo alinhado com narração ou música de fundo.
- ✓Duração proporcional ao comprimento do texto.
- ✓Estilo de animação coerente com o tom do vídeo.
✗ Quando prejudica
- ✗Animação mais rápida que a leitura — texto some antes de ser lido.
- ✗Glitch ou bounce em contexto corporativo sério.
- ✗Múltiplas animações diferentes na mesma cena.
🔤 animated-text — stagger letra a letra
O template animated-text.tsx divide o texto em um array de caracteres e aplica uma Sequence com from escalado por índice. Cada letra entra com um pequeno atraso em relação à anterior, criando o efeito de "digitação veloz" sem usar setTimeout ou estado.
const frame = useCurrentFrame(); const chars = text.split(""); return ( <div style={{ display: "flex" }}> {chars.map((char, i) => { const opacity = interpolate( frame, [i * 2, i * 2 + 8], [0, 1], { extrapolateRight: "clamp" } ); return <span key={i} style={{ opacity }}>{char}</span>; })} </div> );
💡 Por que i * 2 e não um valor fixo?
O i * 2 é o delay: cada letra começa 2 frames depois da anterior. Mude para i * 4 e a revelação fica mais lenta; i * 1 deixa quase simultâneo. O + 8 define a duração do fade individual — tempo para opacidade ir de 0 a 1.
Timeline de execução (texto "OLÁ"):
Frame 0 — "O" começa a aparecer
opacity do "O" vai de 0→1 nos frames 0-8. "L" e "Á" ainda invisíveis (opacity=0).
Frame 2 — "L" começa seu fade
"O" ainda animando; "L" inicia interpolação 0→1 nos frames 2-10.
Frame 8 — texto completo visível
Todos os caracteres em opacity=1. Animação concluída.
🏀 bounce-text — spring com overshoot
O bounce-text.tsx usa spring() em vez de interpolate(). A diferença visual é enorme: em vez de subir linearmente, o texto "quica" — ultrapassa o destino e volta, como um objeto com massa e amortecimento.
const { fps } = useVideoConfig(); const frame = useCurrentFrame(); const scale = spring({ fps, frame, config: { damping: 8, // baixo = mais quique stiffness: 120, // alto = mais rápido mass: 1, }, }); return <div style={{ transform: `scale(${scale})` }}>{text}</div>;
✓ Spring: quando usar
- ✓Títulos hero que precisam de impacto visual.
- ✓CTAs e botões que "chamam" o espectador.
- ✓Emojis e ícones expressivos.
✗ Interpolate: quando usar
- →Fades — spring não controla opacidade com precisão.
- →Movimento horizontal exato (slide preciso).
- →Qualquer timing que não pode ter overshoot.
📊 Tabela de parâmetros spring
| Parâmetro | Valor baixo | Valor alto |
|---|---|---|
| damping | elástico, oscila muito | firma rápido, sem bounce |
| stiffness | lento, preguiçoso | rápido, agressivo |
| mass | leve, rápido | pesado, inércia grande |
💻 glitch-text — RGB split sem biblioteca
O efeito glitch é obtido com três cópias do mesmo texto sobrepostas, cada uma colorida em um canal (vermelho, verde, azul) e deslocada horizontalmente de forma irregular. Tudo com random() semeado e interpolate multi-keyframe para os pulsos.
// deslocamento pulsante para canal vermelho const glitchX = interpolate( frame % 12, // pulso periódico [0, 2, 4, 6, 12], [0, -4, 3, -2, 0], { extrapolateRight: "clamp" } ); return ( <div style={{ position: "relative" }}> {/* cópia vermelha */} <span style={{ color:"red", position:"absolute", transform:`translateX(${glitchX}px)`, mixBlendMode: "screen" }}>{text}</span> {/* cópia ciano e texto original */} </div> );
💡 mix-blend-mode: screen
Com mixBlendMode: "screen", onde vermelho e ciano se sobrepõem produzem branco — criando o artefato visual característico do glitch de CRT. Sem o blend mode, as cores simplesmente se cobrem.
⚠️ Não use Math.random() aqui
O deslocamento do glitch precisa ser determinístico — use random("glitch-r") do Remotion para as amplitudes fixas por canal. Math.random() fará o glitch piscar diferente em cada render, quebrando o vídeo no render paralelo.
🌊 floating-bubble-text — onda senoidal
Em vez de interpolate ou spring, o floating-bubble-text.tsx usa diretamente Math.sin() com o frame como argumento. Cada caractere oscila com uma diferença de fase em relação ao anterior, criando uma onda que percorre o texto continuamente — sem começo nem fim.
const frame = useCurrentFrame(); {text.split("").map((char, i) => { const y = Math.sin( frame / 12 // velocidade da onda + i * 0.5 // fase por índice ) * 8; // amplitude em px return ( <span key={i} style={{ display:"inline-block", transform: `translateY(${y}px)` }}> {char} </span> ); })}
📊 Ajustando o comportamento
frame / 12 — velocidade: número maior = mais lentoi * 0.5 — defasagem: menor = mais sincrônico* 8 — amplitude: pixels de deslocamento vertical⌨️ typewriter-subtitle — cursor piscante
O typewriter-subtitle.tsx emula uma digitação real: mostra progressivamente mais caracteres do texto usando text.slice(0, visibleChars), onde visibleChars deriva diretamente do frame. O cursor pisca com interpolate multi-keyframe.
const frame = useCurrentFrame(); const charsPerFrame = 0.3; // velocidade de digitação const visibleChars = Math.floor(frame * charsPerFrame); const displayText = text.slice(0, visibleChars); // cursor pisca a cada ~15 frames const cursorOpacity = interpolate( frame % 20, [0, 10, 20], [1, 0, 1] );
💡 Ajustando a velocidade
charsPerFrame = 0.3 digita ~9 chars/seg a 30fps. Para digitar mais rápido: aumente para 0.5. Para lento, tipo terminal: 0.15. A fórmula Math.floor(frame * rate) é o padrão universal para "quantos elementos mostrar até agora".
📚 Biblioteca Completa — Categoria Texto
Todos os 9 templates da categoria, com arquivo, descrição em uma linha e hook principal utilizado.
📌 Resumo do módulo
Próximo módulo:
2.2 — Charts & Dados: SVG animado com interpolate, dashoffset, arcos e contadores numéricos.