O que animate faz?
Você cria vídeos animados curtos em código: um <canvas>, desenhado e musicado proceduralmente, determinístico quadro a quadro, renderizado com um navegador headless e ffmpeg. A história segue uma gramática estudada de animações curtas de alto nível; a aparência é um estilo — um kit plugável escolhido de styles/ ou criado a partir das referências do usuário com new-style.md.
Requisitos: Node 18+, Playwright com Chromium (npm i -g playwright && npx playwright install chromium), ffmpeg no PATH. Verifique-os primeiro; se algum estiver faltando, informe ao usuário o comando de instalação e pare. Para narração, Python com faster-whisper (pip install faster-whisper) cronometra cada palavra; sem ele, os tempos das palavras são estimados.
Todos os caminhos abaixo são relativos ao diretório base desta skill. As peças ficam no projeto do usuário em pieces/<nome>/ (crie pieces/ se necessário); os estilos que o usuário cria ficam em <projeto>/styles/<nome>/.
Inegociáveis
- Sem animação antes da aprovação do storyboard. Os check-ins existem porque uma história ou aparência errada custa uma construção completa.
- Olhe para as referências antes de desenhar qualquer coisa — as do usuário, ou o
sample.pnge demonstração do estilo. Em seguida, verifique cada quadro-chave contra grammar/FRAME.md e a própria lista de verificação do estilo em seuSTYLE.md. - Toda afirmação factual na tela é verificada com uma pesquisa na web e listada com sua fonte no briefing. Nunca afirme "primeiro" sem uma fonte.
- Arquivo único, todo código: um
index.html; tudo é desenhado e sintetizado em código — sem arquivos de imagem/áudio/vídeo, sem URIsdata:, sem URLs, sem fontes web no código.tools/build.mjsaplica isso. Duas exceções opcionais, ambas do próprio usuário: ativos (capturas de tela e logotipos em<peça>/assets/, incorporados pela construção) e uma faixa musical (unida na exportação). Veja Ativos e Música abaixo. - Determinístico: apenas aleatoriedade com semente (
RNG(...)), o índice de agitaçãoBpara variação por etapa. NuncaMath.random()ou tempo de relógio. - Mídia de referência permanece local. Nunca a comente, copie seu código ou nomeie seu artista na saída publicada, a menos que o usuário peça para creditá-lo.
- "Pronto" é medido:
tools/review.mjspassa e você olhou as folhas de contato. Relate os números, não "parece bom". - Pergunte com opções. Use AskUserQuestion com um padrão recomendado primeiro, para que o usuário possa responder com um clique.
O fluxo
0. Entrada
Faça as perguntas em intake.md — apenas aquelas que você não pode inferir. Para a aparência, construa a galeria (node tools/gallery.mjs <saída.png> [<projeto>/styles], ~3s), mostre-a e pergunte: qual destes, ou me mostre uma referência? Em seguida, estude você mesmo as referências contra FRAME.md e a lista de verificação do estilo.
1. Verificação da história (texto, rápido)
Escolha o formato de grammar/FORMATS.md — o motor da trama decide (uma história é uma cronologia unida por morphs; uma missão corta na batida; uma lista é um catálogo). Leia grammar/STORY.md. Verifique os fatos na web. Em seguida, mostre ao usuário:
- a ideia em uma linha e o dispositivo narrável ("a centelha ganha um raio a cada era e termina como a resposta")
- o formato e porquê, o estilo, duração, BPM
- uma tabela numerada de beats: tempo, o que acontece, a ponte para o próximo beat, o papel do som (onde está o silêncio, onde está o golpe mais alto)
Pergunte: aprovar / alterar beats / ângulo diferente. Revise até aprovação. É aqui que "Eu quis dizer X, não Y" é pego barato.
2. Verificação da aparência (2–4 quadros de estilo)
Inicie a peça em pieces/<nome>/: copie piece.json e src/ da demonstração do estilo (styles/<nome>/demo/) — ela já fala o kit do estilo e une eras com um morph — ou de templates/beat-cut/ para uma peça que corta forte na batida (oitavas, uma corrida de semicolcheias em quadros ímpares, uma era por take, enquadramentos de câmeras), ou templates/piece/ para o morph de papel recortado mais simples. Defina "style" em piece.json, depois escreva brief.md e LOG.md do zero (os do template são placeholders).
- Um estilo fornecido: leia seu
STYLE.mde demonstração e desenhe com seu kit. - As referências do usuário: siga new-style.md. Meça as referências primeiro (
tools/measure/refs.mjs); os próprios quadros de estilo da peça são os quadros correspondentes, então este é um check-in: as folhas de comparação e os quadros juntos. Salve a pasta de estilo após a aprovação da peça (a peça se torna sua "comprovada em").
Desenhe 2–4 dos beats mais diferentes como quadros em tamanho real. Cada um deve passar em FRAME.md e na lista de verificação do estilo. Renderize-os lado a lado com node tools/still.mjs pieces/<nome> 2.25,9.75,16.5 look.png --scale 0.5 (ou tools/storyboard.mjs com TIMELINE.board definido para esses beats), e mostre a imagem. Pergunte: polegares para cima por quadro / alterar a aparência / tentar outro estilo.
3. Verificação do storyboard (cada beat)
Desenhe cada beat na aparência aprovada. Preencha TIMELINE.board com um tempo-chave por beat ({ t, title, sound, next }) e renderize o quadro. Pergunte por polegares para cima/baixo por número de painel e notas; redesenhe o que está para baixo; repita. Os painéis são as próprias funções de cena do vídeo, então nada é redesenhado depois.
4. Construção
- Escreva
pieces/<nome>/brief.md(especificação, estilo, beats, pontes, plano de som, afirmações + fontes). Mantenha umLOG.md. - Anime as cenas: ações temporizadas com
TT,ev(t, d),popS(t), write-ons (veja craft.md → Movimento). Conecte eras, câmeras e pontes emsrc/bridges.js(formatos unidos por morph) ou deixeBRIDGES = []para cortes secos. node tools/build.mjs pieces/<nome>→index.html(o kit do estilo é puxado depiece.json"style").- Teste tiles durante a construção:
node tools/tile.mjs pieces/<nome> tile.png <quadros...>— olhe para eles; tile em cada morph e corte. - Pontue em
src/score.js(veja craft.md → Som). node tools/export.mjs pieces/<nome> --share→ quadros,audio.wav, stems,renders/final.mp4,renders/share.mp4(--formats 9:16,1:1,16:9para cada formato;--blur 4para desfoque de movimento em estilos de 1s). Itere a mixagem com--only-audio(re-renderiza a pontuação e remuxa, ~4× mais rápido).node tools/review.mjs pieces/<nome>→ folhas de contato por take, grade de cortes, grade de morph, arco da história, âncora, texto (cortado / sobreposto / sob a IU do telefone) e som (o momento mais alto, o silêncio antes dele, LUFS). Corrija até passar, veja as folhas, escreva uma tabela de APROVAÇÃO por take emLOG.md. Confie na verificação de texto em vez do seu olho: uma etiqueta cortada parece boa em uma folha de contato.
5. Entrega
Envie renders/share.mp4. Diga em algumas linhas: o que é, os números das verificações, o que a revisão pegou e corrigiu, o take mais fraco, e o que você não verificou (por exemplo, você não pode ouvir a pontuação). Pergunte o que deve mudar: história, aparência, transições, ritmo, som.
6. Aprendizado
Após cada execução, anexe ao LOG.md da peça. Se algo novo deu errado ou funcionou, proponha uma regra de uma linha para craft.md, o STYLE.md do estilo ou uma alteração de kit, e adicione-a quando o usuário concordar.
Narração (opcional)
Pergunte na entrada (pergunta 3). Com narração, a voz é o relógio: cada beat começa ~0,3s após o final da frase anterior, e os grandes momentos caem em palavras faladas. O roteiro é o storyboard: uma linha por beat.
- Escreva o roteiro em
pieces/<nome>/voice/script.json:{ "lead": 1.2, "tail": 1.8, "lines": [{ "id": "open", "text": "Como é falado.", "after": 0.45 }, ...] }. Escreva números e nomes da maneira como devem ser ditos. Mantenha ≤ 3,5 palavras/s; dê a uma linha umaftermais longo onde a imagem precisa de tempo para assentar (uma contagem, uma legenda, o silêncio antes da recompensa). - Construa antes de a narração existir:
node tools/voice.mjs pieces/<nome> --scratchfaz uma voz de temporização com a fala do próprio SO (nunca a envie), para que toda a peça possa ser animada e revisada. - As tomadas: um arquivo por linha, salvo como
voice/<id>.mp3com"file"definido na linha.- O conector ElevenLabs (se o usuário o tiver: Configurações do Claude → Conectores → ElevenLabs, conectado com OAuth, sem chave de API): encontre 2–3 narradores que se encaixem com sua pesquisa de voz, gere uma linha em cada (uma variação cada, não quatro), deixe o usuário escolher, então gere cada linha uma vez com essa voz e modelo. O resultado da geração fornece um link de download de curta duração por take: salve cada um em
voice/. Custa cerca de um crédito por caractere; diga o total antes da execução completa. Se o conector foi adicionado durante a sessão, suas ferramentas podem aparecer apenas após o aplicativo reiniciar. - A própria gravação do usuário, um arquivo por linha (ou cortada de uma tomada).
- Nunca busque uma voz de um site para o qual o usuário não apontou, e nunca clone uma voz sem o consentimento de seu dono.
- O conector ElevenLabs (se o usuário o tiver: Configurações do Claude → Conectores → ElevenLabs, conectado com OAuth, sem chave de API): encontre 2–3 narradores que se encaixem com sua pesquisa de voz, gere uma linha em cada (uma variação cada, não quatro), deixe o usuário escolher, então gere cada linha uma vez com essa voz e modelo. O resultado da geração fornece um link de download de curta duração por take: salve cada um em
node tools/voice.mjs pieces/<nome>→voice/voice.wav(as linhas com suas pausas) evoice.json(início e fim de cada linha e palavra, ouvidos no áudio por faster-whisper, localmente). A construção o injeta comoVOICE.- No cabeçalho:
VL(id)é uma linha,VW(id, word, n)quando sua n-ésimawordcomeça; beats começam emt1 + 0.3da linha anterior;TIMELINE.narrationvem deVOICE.lineseDURATIONdeVOICE.duration. Dê dicas de Writes e flashes nas palavras que os nomeiam. Coloque o golpe de recompensa em uma pausa antes da linha que o nomeia: um golpe sob fala é abafado. piece.json:"voice": { "file": "voice/voice.wav", "music": -12 }. A exportação mixa a voz sobre a pontuação (a pontuação emmusicdB, abafada ainda mais enquanto a voz fala) para −14 LUFS. A revisão julga o arco da história e a janela de recompensa apenas na pontuação (renders/audio-score.wav; uma voz é mais alta que qualquer golpe) e a voz com sua verificação NARRATION.- Re-tomadas e edições de roteiro: substitua o arquivo de uma linha (ou edite seu texto), reexecute
voice.mjs, reconstrua: cenas com dicas deVOICEse movem com ele. Uma palavra alterada pode órfã uma dica que aponta para ela; verifique esses beats.
Música: a própria faixa do usuário (opcional)
Pergunte na entrada (pergunta 6). Sem faixa, a pontuação é composta em código em uma grade de 120 BPM. Com uma:
- Coloque-a na peça:
pieces/<nome>/audio/track.wav(WAV, MP3 ou M4A), e empiece.json:"music": { "file": "audio/track.wav", "start": 12.0, "gain": 0, "fade": 0.5 }(start= onde na música a peça começa). node tools/beats.mjs pieces/<nome>/audio/track.wav pieces/<nome> --start 12 --dur <duração da peça>→beats.json: o andamento, o primeiro beat, cada beat e compasso, os golpes mais fortes, o momento mais alto e as quedas. Passe--bpm 128se o usuário souber o andamento; verifique sua linha "outros andamentos" caso contrário (dobro / metade / dois terços do tempo é o erro comum).- A construção o injeta como
BEATS; o cabeçalho inicial lêBPMeGRID0dele, eonBeat(t)ajusta um tempo à grade de oitavas da música. Coloque cortes, morphs e dicas emonBeat(...). A música decide o arco: coloque a virada em uma queda (BEATS.quiet) e a recompensa em seu golpe mais alto (BEATS.loudest,BEATS.hits), não onde uma pontuação composta os colocaria. - A pontuação (
src/score.js) mantém apenas efeitos sonoros (to = 's'): a exportação substitui o barramento de música pela faixa, mixa o stem de efeitos sonoros por cima e normaliza para −14 LUFS. A grade da revisão usaTIMELINE.gridOffset; sua seção SOUND diz se o momento mais alto cai no ato de recompensa. - A pré-visualização do navegador ainda toca a pontuação composta (sem arquivos de áudio na página); a exportação tem a faixa.
Ativos: capturas de tela e logotipos reais (opcional)
Pergunte na entrada (pergunta 7) quando o assunto for um produto. Então:
node tools/capture.mjs <url> pieces/<nome>/assets/home.png [--selector "css"] [--full] [--dark] [--hide "css"]captura a tela do próprio site do usuário (uma página, uma seção, o logotipo). Pergunte antes de capturar algo que eles não possuem. Arquivos de logotipo que eles fornecerem vão emassets/também (PNG, SVG, JPG, WEBP).tools/build.mjsincorpora tudo emassets/emindex.html(a peça permanece um arquivo, e o canvas permanece legível pelas verificações);window.renderFrameaparece depois que as imagens são decodificadas, e toda ferramenta espera por ele.- Desenhe-os com
drawAsset('home.png', x, y, w, h, { fit: 'cover' | 'contain', r })dentro do próprio enquadramento do estilo (uma foto em papel rasgado, um quadro a tinta, um cartão impresso) para que pertençam à aparência.asset(name)retorna a imagem. - Apenas IU de produto real: anime as telas reais (corte, aproxime, revele, aponte para elas com o herói); nunca desenhe uma tela falsa como se fosse o produto. Amostre cores de marca das capturas de tela.
Formatos: uma peça, várias formas (opcional)
Pergunte na entrada (pergunta 2, seleção múltipla). Liste-os em piece.json "formats": ["9:16", "1:1", "16:9"] (o primeiro é o principal). O cabeçalho inicial lê ?format= e define W, H, SAFE e CX; as cenas posicionam as coisas com LX(fraction), LY(fraction) e as dimensionam com UNIT, e escolhem um arranjo diferente com PORTRAIT / WIDE onde uma forma precisar (uma coluna de três em 9:16, uma linha de três em 16:9). Nunca corte uma renderização 9:16 para 16:9.
node tools/export.mjs pieces/<nome> --formats 9:16,1:1,16:9 --share→renders/final.mp4(principal) efinal-<l>x<a>.mp4para os outros.- Revise cada um:
node tools/review.mjs pieces/<nome> --format 16:9(etile/still/textcheck/storyboardaceitam--formattambém). A verificação de texto importa mais aqui: uma legenda larga que cabe em 16:9 pode sair de 9:16.
Movimento: molas e desfoque
- Molas (
kit/core.js):springMove(t0, a, b, SPRING.snappy)move um valor com um pequeno overshoot e estabilização;springTrack([[t, v], ...])segue um valor através de muitos alvos sem salto. Predefinições:snappy(IU),smooth(cartões, câmera),heavy(tipografia grande, logotipos),playful(mascotes). Forma fechada, então os quadros permanecem determinísticos. Estilos em 2s os passam a cada 2 quadros, como deveriam. - Desfoque de movimento:
export.mjs --blur 4faz a média de 4 sub-quadros por quadro — apenas para estilos em 1s (STYLE.ones: matemática, isométrico); looks desenhados à mão em 2s são nítidos de propósito (exportação avisa).
Agentes paralelos (peças longas)
Uma peça de 45–60s tem 10–15 cenas; divida o trabalho...
[truncado para tradução]