givemotion: HTML entra, vídeo sai
Uma composição é um único arquivo HTML. Cada quadro é essa página em um momento no tempo. Animações CSS, transições, Web Animations, timers, requestAnimationFrame, canvas e WebGL rodam em um relógio virtual, então o que você escreve renderiza quadro a quadro de forma exata e idêntica toda vez. Nenhuma tag script ou importação é necessária: a runtime (window.gm) e uma folha de estilos predefinida são injetadas para você.
Este arquivo é o núcleo (leia tudo). Depois leia apenas as 1-3 receitas de técnica que seu vídeo precisa (tabela no final): cada uma mostra como um profissional constrói aquele efeito, com números e um exemplo funcional. Consulte qualquer outra coisa quando precisar.
O loop
- Direção. Antes do código, decida como um grande estúdio abordaria este briefing: pesquise o gênero (pesquise na web por exemplos reais quando puder, senão lembre-se deles), então escreva no topo do HTML: a aparência em palavras, o sistema tipográfico, a linguagem de movimento (famílias de easing, ritmo, como as cenas fazem a transição) e a lista de planos (uma linha por momento: tempo, o que está na tela, o movimento, a transição). Como:
references/direction.md. - Quadros de estilo. Construa os 2-3 planos-chave primeiro, parados, e
stillcada um: julgue-os como pôsteres (um ponto focal, hierarquia, margens). Depois anime. - Escreva o movimento; execute
npx givemotion check video.htmlenquanto avança: corrija todo ✖; ⚠ são falhas reais a menos que intencionais; ℹ são dicas de estilo. - Revise duas vezes.
npx givemotion review video.htmlescreve o que um espectador vê (visão geral, os quadros que as pessoas leem, tiras de movimento nos momentos mais movimentados) ereview/REVIEW.md: avalie com dureza, corrija os cinco piores problemas, revise novamente. Olhos frescos encontram mais: dê a um subagente apenas o briefing e a pasta de revisão. Coloque os tempos do briefing emdata-expect. - Renderize:
npx givemotion render video.html -o out/video.mp4.
Use --json para saída de máquina, <comando> --help para opções. still video.html -t 3.2 -o f.png renderiza um momento; inspect --at 4.5 --el "#logo" diz onde um elemento está.
Como um bom movimento é feito aqui
O motor te dá qualquer HTML/CSS/SVG/canvas e uma linha do tempo exata por quadro; a aparência vem de como você coreografa. Espectadores cegos preferiram vídeos onde cada elemento foi coreografado manualmente em vez de vídeos construídos com presets de uma palavra.
- Coreografe manualmente. Use
gm.timelinepara tudo que importa: tempos de início explícitos, easing por movimento (umexpo.outrápido e seco, uma deriva suavesine.inOut, um pousoback.out(1.6)), offsets de 40-120 ms entre partes relacionadas. Presets (data-enter,data-camera) são bons para pequenos elementos de suporte. - Três camadas em cada momento herói: o movimento principal; o detalhe secundário que o vende (desfoque enquanto rápido, um brilho, uma sombra que cresce, acompanhamento, um anel ou partículas no impacto); e movimento ambiente para que o quadro nunca congele (fundo flutuando, câmera lenta push).
- Contraste no tempo. Rápido para entrar, lento para estabilizar; pausas de 0,4-1 s depois que algo pousa; saídas mais curtas que entradas. Nunca mova tudo na mesma velocidade com a mesma curva.
- Siga o briefing exatamente para cores, fontes, texto, tamanhos e tempo; seu ofício vai em como as coisas se movem, não em conteúdo extra.
- O quadro 0 é o gancho, nada é cortado pela borda do quadro, o texto é grande (títulos 96-200 px, corpo ≥ 36 px em 1080p), um herói por momento, as cenas fluem umas nas outras (push, whip, morph, match cut) em vez de desvanecer.
- As coisas vêm das coisas. Um novo elemento nasce de um já na tela, não surge do nada: três círculos saem do círculo principal; um dos retângulos na tela desliza e se torna o sublinhado; um cartão cresce a partir do botão que foi clicado; a marca do logo se torna a marca do cartão final. Reutilize e transforme antes de adicionar. Plante o próximo conjunto cedo: já no mundo (pequeno, escuro) enquanto este beat toca, para que a câmera o revele.
- Um movimento de câmera significa "olhe aqui". Faça push apenas em direção a algo que o espectador deve ler em seguida. Nunca zoom em espaço vazio ou na cena antiga como forma de transição: para sair de uma cena, mova lateralmente (push, whip, wipe) ou carregue um elemento através (morph, a regra acima).
- Anime
transform/translate/scale/rotate/opacity/filter/clip-path, nãowidth/top/left. - Cada elemento tem uma vida planejada: entrada, uma pausa legível (~1 s + 0,25 s por palavra), depois uma saída ou transição. A lista de planos dá cada pausa.
Hierarquia: uma coisa importa de cada vez
Espectadores preferiram vídeos onde o olho sempre sabia onde olhar.
- Cada linha tem uma palavra-chave. Dê à palavra que carrega o significado contraste (cor de destaque, peso mais pesado, tamanho maior, ou um destaque desenhado); o resto fica mais quieto. Uma por linha, no máximo duas por tela. Se tudo é destaque, nada é.
- Cada momento tem um herói: a maior, mais brilhante coisa com mais movimento. O suporte é menor (herói ≥ 1,6× o próximo tamanho; no máximo três níveis), mais escuro (silenciado ou 50-70% de opacidade), chega depois do herói e se move menos. Efeitos (anéis, faíscas) emolduram o herói, nunca o cruzam.
- Lide o olho em ordem: o herói pousa primeiro; a palavra-chave ganha sua cor ou sublinhado 0,2-0,4 s depois que a linha se estabiliza; o suporte segue. Quando a câmera ou um destaque foca em algo, escureça o resto.
- Papéis da paleta estritamente: destaque apenas para ênfase, silenciado para texto secundário.
Easing: combine a curva com o movimento
- Entrando desacelera (ease-out:
expo.out,power3.out, ouback.out(1.4)quando pousa com peso). - Saindo acelera (ease-in:
power2.in), mais curto que a entrada (60-70%). - Movendo de A para B enquanto visível, movimentos de câmera, uma mudança de escala de algo já na tela: ease-in-out (
power2.inOut,sine.inOut): começa suavemente e pousa suavemente. - Deriva ambiente:
sine.inOutlongo;linearapenas para loops (giros, tickers). Nada que começa ou para na tela se move linearmente. - Deixe
easede fora e o motor já faz isso (entradas com spring, movimentos com ease in e out, saídas com ease in); quando você definir um, siga as regras acima.
Composição mínima
<!doctype html>
<html data-width="1920" data-height="1080" data-fps="30" data-duration="2.5">
<head>
<style>
:root { --bg: #0b0d12; --ink: #fff; --accent: #7c9cff; }
body { background: var(--bg); color: var(--ink); font-family: Inter, sans-serif; }
.scene { display: grid; place-items: center; } /* .scene já é absolute + quadro cheio */
h1 { font-size: 160px; letter-spacing: -0.03em; margin: 0; }
.glow { position: absolute; width: 900px; height: 900px; border-radius: 50%; background: var(--accent); filter: blur(160px); opacity: .25; }
</style>
</head>
<body>
<section class="scene">
<div class="glow"></div>
<h1 id="t" data-split="chars">Olá</h1>
</section>
<script>
gm.timeline('.scene')
.from('.glow', { scale: 0.6, opacity: 0, duration: 1.2, ease: 'sine.out' }, 0) // ambiente: luz surge…
.to('.glow', { x: 220, y: -90, duration: 2.5, ease: 'sine.inOut' }, 0) // …e continua flutuando
.from('#t .gm-char', { y: 140, opacity: 0, filter: 'blur(12px)', duration: 0.7, ease: 'expo.out', stagger: 0.05 }, 0.2) // principal: rápido, desfocado enquanto rápido
.fromTo('#t', { letterSpacing: '0.12em' }, { letterSpacing: '-0.03em', duration: 2.4, ease: 'expo.out' }, 0.2) // detalhe: tracking aperta
.to('#t', { scale: 1.06, duration: 1.9, ease: 'sine.inOut' }, 0.6); // a pausa continua respirando
</script>
</body>
</html>
Fontes embutidas: Inter, JetBrains Mono, Playfair Display, Space Grotesk, Bebas Neue, Nunito, Caveat; outras via @font-face.
Modelo de tempo (leia isto)
- As configurações ficam em
<html>:data-width,data-height(números pares),data-fps(padrão 30),data-durationopcional,data-backgroundopcional. - Tempos são em segundos:
1.5,1.5s,500ms,45f(quadros),1:02.5. - Clipes. Um elemento com
data-start,data-durationoudata-endsó existe (édisplayado) do início até início+duration. Os tempos são relativos ao clipe pai. Elementos sem temporização estão sempre lá. - Duração do vídeo =
data-durationem<html>, senão o final do último clipe. - Sequências.
data-sequenceem um contêiner reproduz seus filhos um após o outro. Todo filho precisa dedata-duration, ou dê ao contêinerdata-cuts="0 2.13 4.27"(quando cada filho começa; também"beats: 0 4 8"/"bars: 0 1 2").data-gap="0.2"(negativo = sobreposição).data-transition="<nome> <segundos> [easing]"sobrepõe vizinhos e anima a mudança; um filho pode definir seu própriodata-transition(como ele entra). Cada transição tira seu comprimento do total: 3 cenas de 4s comfade 0.5duram 11s. Cortes no beat,data-cut-align, e onde o tempo 0 de uma cena então se situa:references/timeline.md. - Transições:
push-/cover-/whip-/wipe-+left/right/up/down(push: nova empurra a velha para fora; cover: nova desliza sobre; whip: rápida, desfocada)diagonalclockiriszoomzoom-through(cena antiga voa para longe)flip(3D)dip(através do preto)blurfade-upfade, emorph: elementos com o mesmodata-morph="nome"em ambas as cenas voam e redimensionam do lugar antigo para o novo enquanto o resto faz crossfade. Carrega um logo, cartão ou número através; em uma cena usegm.fly. - Animações CSS rodam no tempo do clipe.
animation: fade-up .6s .4s bothcomeça .4s após seu clipe aparecer. Useboth(oubackwards) fill para que o elemento fique oculto antes de seu delay. - Algo aparece depois dentro de uma cena longa (um mundo de câmera, uma lousa): o delay em
data-enterconta a partir do início do clipe do elemento, entãodata-enter="write 0.8 11.9"escreve um rótulo 11,9 s na cena e o mantém oculto até lá. Nenhum clipe extra necessário. gm.onFrame(fn)recebe o tempo do vídeo, mesmo em uma cena;gm.onFrame('#s', (local, info, el) => …)conta a partir do início de#s, comogm.timeline('#s').- Timers,
requestAnimationFrame,Date.now(),performance.now()são virtuais eMath.random()é semeado. Código normal de animação web funciona.
Linha do tempo: coreografia precisa (estilo GSAP, embutido)
Para qualquer coisa com mais de algumas partes móveis, use gm.timeline: a API GSAP que você conhece, computada a partir do tempo (exata por quadro, paralela). Os tempos são em segundos relativos ao clipe que contém o escopo.
gm.timeline('#scene2') // escopo: seletores são procurados dentro dele
.from('.title .gm-word', { y: 120, opacity: 0, rotate: 8, stagger: 0.06 }) // sem ease: spring na entrada
.to('.card', { x: 400, y: -60, scale: 1.2 }, '+=0.3') // arcos, dimensionados pela distância
.fromTo('.bar', { scaleY: 0 }, { scaleY: 1, stagger: { each: 0.08, from: 'center' } }, '<')
.to('#line', { draw: 1, duration: 1.5 }, 2) // desenha um traço SVG
.to('.price', { textContent: 249, duration: 1.5 }, 2.5); // conta um número
gm.fly('#event', { from: '#slot2', at: 7.5, duration: 0.8 }); // voa da caixa de outro elemento para seu próprio lugar
from()/fromTo() mostram seus valores iniciais a partir do início do clipe (ocultos até entrarem). Tweens sobrepostos em uma propriedade: o início mais recente vence. Posições, todas as propriedades e opções, labels, keyframes, gm.fly e ressalvas SVG: references/timeline.md.
Também embutido (tabelas em references/api.md): presets data-enter/data-exit, data-split, data-stagger, data-count (-roll), data-type (máquina de escrever), data-scramble, data-camera (push, float, shake…), data-parallax, data-morph, data-fit, data-pulse, nomes de easing (nomes GSAP funcionam), keyframes CSS predefinidos e var(--px), e blocos prontos (npx givemotion blocks: legendas, janela-de-código, cursor, janela-de-navegador, gráficos…).
Receitas de técnica (leia as que seu vídeo precisa)
| Seu vídeo tem… | Leia |
|---|---|
| Um logo, vinheta de marca, intro ou cartão final | references/techniques/logo-reveal.md |
| Tipografia grande que bate, empilha, rotaciona; um título como estrela | references/techniques/kinetic-type.md |
| Revelações de texto: palavras/caracteres, máquina de escrever, write-on, scramble, destaque | references/techniques/text-reveals.md |
| Movimentos de câmera: push, follow, whip, bank, zoom para um detalhe, shake | references/techniques/camera-moves.md |
| Várias cenas fazendo transição (push, whip, morph, shape wipes) | references/techniques/scene-transitions.md |
| Brilho, varreduras de luz, gradientes, granulação, desfoque, profundidade | references/techniques/light-and-depth.md |
| Números, contadores, gráficos de barra/linha, chamadas | references/techniques/numbers-and-charts.md |
| Linhas que desenham, rotas, mapas, pins, algo viajando um caminho | references/techniques/paths-and-maps.md |
| Formas planas: crescer, esmagar, dividir, orbitar, morph | references/techniques/shapes-and-motion-graphics.md |
| Um aplicativo/UI com cursor, cliques, digitação, listas | references/techniques/ui-demo.md |
| Código em um editor, digitação, destaques de linha | references/techniques/code-on-screen.md |
| Impacto e energia: pancadas, shake, explosões, batidas musicais | references/techniques/impacts-and-energy.md |
| Legendas palavra por palavra, clipes verticais 9:16 | references/techniques/captions-vertical.md |
| Lousa, esboço, desenhado à mão | references/techniques/hand-drawn.md |
| Um fundo vivo por trás de tudo | references/techniques/backgrounds-and-ambient.md |
Referência da API (consulte quando necessário)
| Quando… | Leia |
|---|---|
| Um atributo, preset, nome de easing, CSS predefinido ou bloco | references/api.md |
gm.timeline completo: posições, keyframes, labels, gm.fly, SVG | references/timeline.md |
Mundos de gm.camera, planos, gm.path.travel, montaria, parallax | references/camera.md |
gm.chart.*, blocos de gráfico | references/charts.md |
Diagramas, setas, data-sketch, gm.connect, gm.shape, morphs de caminho | references/diagrams.md |
Música, beats, narração + givemotion words, clipes de vídeo, legendas | references/media-audio.md |
| Dados/modelos, `<gm-in |
…
[truncado para tradução]