Estilos de animação
Um projeto Remotion com 39 estilos de animação construídos manualmente. Cada estilo redesenha uma história fixa, para que possam ser comparados lado a lado e reutilizados como modelos: uma chaleira entra, inclina-se, despeja chai em um kulhad (copo de barro), o copo enche, a chaleira sai, o vapor sobe. 150 quadros, 30 qps, 1080×1350 (4:5), silencioso. Renderizado com --scale=2 fica 2160×2700.
Tudo é desenhado em código: SVG com filtros, ou uma <canvas> pintada a cada quadro. Nenhum modelo de imagem, modelo de vídeo ou filmagem de arquivo é envolvido, portanto a saída é original e repetível.
O projeto está na pasta deste skill (a pasta que contém este arquivo, chamada <skill> abaixo). Execute os comandos a partir dela.
0. Primeira vez em uma sessão
cd <skill>e verifique senode_modules/existe. Se não, executenpm install(cerca de um minuto, precisa de Node 18+).npm run listimprime todos os 39 estilos com seu número, slug e uma descrição de uma linha.- A primeira renderização baixa um Chrome headless uma vez (cerca de 100 MB). Precisa de internet.
O pedido usual: "faça um vídeo de 5 segundos de no estilo "
Esta é a tarefa principal (e o prompt que leva as pessoas até aqui). Faça do início ao fim sem parar para perguntas, a menos que a ideia não esteja clara:
- Pasta de trabalho: use
animation-films/dentro da pasta de trabalho atual do usuário. Se não existir, crie-a a partir dessa pasta comnode <skill>/scripts/new-project.mjs animation-films, depoiscd animation-films && npm install(rápido após a primeira vez). Se existir (um acompanhamento), reutilize-a como está. - Escolha o estilo a partir do pedido (seção 1). Nenhum estilo nomeado? Sugira três que combinem com a ideia e pergunte.
- Planeje a história nas seis batidas (seção 3) em uma tabela curta. Mostre-a em uma mensagem e continue; não espere a menos que algo seja ambíguo.
- Formas primeiro: coloque os objetos do usuário (o ator, o recipiente, o que flui, o que sobe) em
src/films/<ideia>-shapes.tscomo caminhos SVG nas mesmas coordenadas quePemstory.ts, com a tabela de batidas como um comentário no topo. Toda versão de estilo desta ideia importa deste único arquivo. - Construa
src/films/<ideia>-<estilo>.tsxa partir do componente do estilo (seção 3), usando o arquivo de formas, e registre-o emsrc/films/index.tscom o id<ideia>-<estilo>. - Verifique:
npm run render -- <ideia>-<estilo> --framese veja todos os seis quadros (seção 5). Corrija e repita. - Entregue:
npm run render -- <ideia>-<estilo> --finale dê ao usuário o caminho completo deout/<ideia>-<estilo>.mp4. Mencione que ele pode pedir outro estilo ("agora faça em pixel art").
Acompanhamento de reestilização ("agora faça em pixel art", "tente aquarela", "o mesmo em xilogravura"): fique na mesma pasta animation-films/, mantenha a mesma ideia, tabela de batidas e arquivo de formas, e construa um novo src/films/<ideia>-<novo-estilo>.tsx a partir do componente do novo estilo. Registre-o junto com a versão anterior (nunca a sobrescreva), verifique os quadros, renderize o final e dê o novo caminho. Se o usuário nomear um estilo vagamente ("8-bit", "filme antigo", "giz"), mapeie-o com a seção 1. Os estilos com aparência 3D (57, 58, 59, 62, 80) constroem objetos como malhas 3D, portanto trocar objetos dá mais trabalho: transforme as formas em malhas simples de torno ou caixa com os helpers em src/styles/3d/mesh.ts.
1. Escolher um estilo
Pergunte ao usuário qual estilo ele deseja, se ele não disse. Se ele não tiver certeza, mostre npm run list agrupado por família e a galeria em README.md (cada estilo tem uma prévia animada em media/thumbs/ e um MP4 720×900 em media/videos/). Corresponda livremente: "impressão japonesa" → 33 Ukiyo-e, "giz" → 02 Lousa de giz, "8-bit" ou "jogo retrô" → 64 Pixel art RPG, "argila" → 62 Claymation, "tipo Lego" → 58 Brinquedo de bloco (nunca chame de Lego na tela), "filme antigo" → 70 Filme mudo ou 71 Cinejornal, "tela de ficção científica" → 84 Holograma HUD.
| Família | Estilos (número, slug) |
|---|---|
| Desenhado em um quadro | 01 whiteboard · 02 chalkboard · 05 notepad-doodle · 06 blueprint |
| Desenhado à mão e pintado | 08 hand-drawn · 09 urban-sketch · 10 crayon-book · 11 watercolour · 13 one-line · 16 cel-line-boil |
| Cartoon | 17 flat-vector · 21 cel-anime-80s · 22 stick-figure |
| Papel e fantoches | 23 cut-out · 24 red-papercut · 25 paper-pop-up · 27 shadow-puppet |
| Impressão e artesanato | 28 woodcut · 29 engraving · 31 silkscreen-poster · 33 ukiyo-e · 34 art-deco · 35 stained-glass |
| Gráfico e explicador | 39 memphis-diorama · 51 sticker-explainer · 52 math-diagram |
| Aparência 3D | 57 low-poly-island · 58 brick-toy · 59 glass-product · 62 claymation · 80 lidar-survey |
| Eras do cinema | 70 silent-film · 71 newsreel |
| Telas e ciência | 64 pixel-art-rpg · 81 microscope · 84 hologram-hud · 85 circuit-board |
| Abstrato | 87 liquid-motion · 89 generative-abstract |
src/catalog.ts é a lista única: número, id da composição (33-ukiyo-e), nome, família, aparência, as palavras na tela que um estilo mostra e o arquivo onde seu código reside.
2. Mostrar um estilo integrado como ele é
npm run render -- 33 # Prévia 720x900 -> out/33-ukiyo-e_preview.mp4 (segundos a um minuto)
npm run render -- 33 --final # Mestre 2160x2700 -> out/33-ukiyo-e.mp4 (crf 16)
npm run render -- 33 --frames # 6 quadros de verificação -> out/33-ukiyo-e_frames/ (+ uma folha de contato se o ffmpeg estiver instalado)
npm run render -- 33 --still 75 # Um PNG do quadro 75
Um estilo pode ser nomeado por número, id, slug ou parte de seu nome (ukiyo, pixel, stained). Os vídeos 720×900 prontos já estão em media/videos/, e os mestres 2160×2700 estão na página de lançamento do GitHub, então para apenas mostrar um estilo você não precisa renderizar nada.
3. Recontar com a história ou objeto do usuário
A história é fixa em src/story.ts. Mantenha seu ritmo e mude o que é desenhado. É isso que faz um novo filme sair certo na primeira vez: cada estilo já sabe como encenar essas batidas.
As batidas (quadros a 30 qps, nunca as mova para um filme de 5 segundos):
| Quadros | Batida | Valor de storyAt(f) |
|---|---|---|
| 0–24 | o ator entra pela direita | kx, ky |
| 24–42 | ele se prepara (inclina-se) | tilt (0 → −38°) |
| 42–96 | a ação principal (o despejo) | streaming, stream (um caminho SVG da tip para dentro do copo) |
| 44–100 | o resultado cresce (o copo enche) | level 0 → 1, surface (a elipse do chai) |
| 96–126 | termina e sai | tilt de volta a 0, kx desliza para fora |
| 104–150 | a consequência (vapor sobe) | steam[0..2] 0 → 1, desenhado com steamPath(i, p, t0) |
P em story.ts contém os caminhos SVG para o copo (kulhadBody, kulhadOutline, rim) e a chaleira (kettleBody, kettleLid, kettleSpout, kettleHandle, kettleBand, mais KNOB). A chaleira é desenhada em torno de sua própria origem e colocada com translate(kx, ky) rotate(tilt).
Mapeie a história do usuário nas mesmas seis batidas primeiro, em uma tabela curta, e mostre-a a ele. Exemplos:
| Ideia do usuário | Ator (chaleira) | Ação (despejo) | Resultado (enchimento) | Consequência (vapor) |
|---|---|---|---|---|
| Café em uma caneca | cafeteira | jato de café | caneca enche | vapor |
| Regar uma planta | regador | gotas de água | solo escurece, um broto cresce com level | duas folhas se abrem |
| Economizar dinheiro | uma mão com uma moeda | moeda cai | cofrinho enche (level → pilha de moedas) | brilhos |
| Tinta em uma lata | lata de tinta | tinta grossa | lata enche | uma gota assenta |
| Upload de dados (estilos abstratos ou informativos) | uma nuvem | pacotes viajam ao longo de stream | uma barra ou medidor enche com level | uma marca de verificação sobe |
Depois construa:
- Trabalhe em um projeto separado para que o skill instalado permaneça limpo: por padrão
animation-films/na pasta atual do usuário (veja "O pedido usual" acima), criada comnode <skill>/scripts/new-project.mjs <pasta>e depoisnpm installdentro dela. Nunca construa os filmes do usuário dentro de<skill>. - Copie o componente do estilo escolhido de seu arquivo (veja
src/catalog.ts) parasrc/films/<nome-do-filme>.tsx, junto com os helpers que importa. Nunca edite os 39 originais no lugar: eles são a referência. - Substitua as formas, não o ritmo: troque os caminhos da chaleira e do copo pelos objetos do usuário (mantenha-os aproximadamente do mesmo tamanho e posição: copo centralizado em x 540, borda em y ≈ 800; ator em repouso por volta de (796, 324) com seu "bico" no ponto local (−251, −62)), recolorir o líquido, mude o que sobe. Mantenha os próprios materiais do estilo, lógica de paleta, filtros, textura e caráter de movimento (passos em dois ou três para mídia artesanal, suave para digital, cintilação para filme).
- Se o estilo mostra palavras (listadas no campo
textdo catálogo: 51, 52, 64, 70, 71, 84 e 85 mostram palavras), reescreva-as para a nova história: curtas, inglês simples, apenas sobre a história. - Registre o filme em
src/films/index.tse renderize-o (seção 4).
Uma história mais longa ou diferente (mais batidas, dois atores, um movimento de câmera): escreva um novo arquivo de história ao lado de story.ts (por exemplo src/films/minha-historia.ts) com seu próprio storyAt(f) que retorna todos os valores que o desenho precisa, liste as novas batidas em uma tabela no topo, defina durationInFrames no filme e mantenha a regra "o arquivo de história possui todo o ritmo, o arquivo de estilo possui todas as aparências". Quantize os quadros (Math.floor(f / 2) * 2) apenas onde o estilo deve parecer artesanal.
Regras para o código: apenas determinístico (sem Math.random(), sem Date; use funções semeadas do quadro ou índice), ids únicos de filtro e clipPath, fontes apenas via @remotion/google-fonts/<Fonte> com loadFont() no nível do módulo, e nada instalado além de package.json.
4. Renderizar
| Necessidade | Comando |
|---|---|
| Olhada rápida | npm run render -- <filme-ou-estilo> (720×900, crf 23) |
| Final | npm run render -- <filme-ou-estilo> --final (2160×2700, crf 16) |
Um filme de src/films | npm run render -- <id-do-filme> --final (os mesmos flags funcionam: --frames, --still 75) |
| Edição ao vivo | npm run studio abre o Remotion Studio no navegador |
Os estilos com aparência 3D (57, 58, 59, 62, 80) pintam uma cena renderizada por software em uma tela a 1,5× (1,25× para 80) de 1080 de largura, depois esticam para 2160, portanto são ligeiramente mais suaves e lentos que os outros. Para um final mais nítido, aumente o segundo argumento de glView(...) em src/catalog.ts (2 = 4K nativo, cerca de duas vezes mais lento).
5. Verificar a saída antes de entregar
Execute npm run render -- <id> --frames e veja todos os quadros (Leia os PNGs). Depois corrija e re-renderize. Permita duas ou três passagens.
- História legível: no quadro 50 algo está claramente derramando, no 75 o recipiente está visivelmente enchendo, no 149 a consequência é visível.
- Nada cortado nas bordas do quadro; o ator entra e sai completamente.
- Camadas: o líquido fica dentro do recipiente, o jato vai para dentro dele (não na frente da borda próxima), o vapor começa na superfície.
- O estilo se lê de um quadro: alguém que conhece o estilo deve nomeá-lo a partir de um still. Dois estilos nunca devem parecer uma recoloração um do outro.
- Contraste: o líquido e o jato são visíveis contra o fundo, nada turvo.
- Caráter de movimento: com passos onde a mídia é artesanal, suave onde é digital; sem cintilação não intencional.
- Texto: apenas as palavras que você pretendia, escritas corretamente, dentro do quadro.
- Regras de conteúdo (abaixo) todas aprovadas. Por fim, assista à prévia MP4 uma vez do início ao fim e, em seguida, renderize o final.
6. Regras de conteúdo (sempre)
- Sem marcas reais, logotipos, produtos, pessoas, nomes de canais ou redes de TV, e sem nomes com marca registrada na tela. "Brinquedo de bloco" é um bloco de brinquedo genérico, nunca uma marca nomeada.
- Sem mapas reais, lugares ou fronteiras nacionais, e sem bandeiras ou símbolos políticos ou slogans. Uma paisagem, se houver, é inventada sem geografia reconhecível.
- Sem copiar um filme, programa, sequência de título, jogo, personagem específico, ou a silhueta ou sprites de um personagem conhecido. Um estilo ou gênero é aceitável; uma obra existente específica não.
- Sem fatos inventados: sem estatísticas, preços, datas, citações ou fontes falsas. Um estilo de dados plota os próprios valores da história (como o nível de enchimento) e nada mais.
- Texto apenas quando o estilo é tipográfico, de transmissão ou uma IU de jogo, e então em inglês curto sobre a própria história.
- Mantenha-o original: a história do usuário, seus próprios desenhos, o estilo como técnica.
Arquivos
| Caminho | O que é |
|---|---|
src/story.ts | A história: tamanho, ritmo, batidas, os caminhos dos objetos, storyAt(f) e steamPath() |
src/kit.tsx | Helpers compartilhados: Stage (um palco SVG), Paper (grão de papel), Rough (deslocamento irregular), region |
src/catalog.ts | Os 39 estilos: número, id, nome, família, aparência, palavras na tela, arquivo, componente |
src/styles/<familia>/ | O código de desenho, agrupado por técnica |
src/films/ | Os próprios filmes do usuário |
src/Root.tsx, src/index.ts | Registra cada estilo e filme como uma composição Remotion |
scripts/render.mjs | npm run list / npm run render |
scripts/new-project.mjs | npm run new -- <pasta> copia o código para um projeto novo |
media/videos/, media/thumbs/ | Um MP4 720×900 e um WebP animado de cada estilo |