Communitygithub.com

motionkit

Crie filmes de motion graphics em código com o motor canvas motionkit – copie o movimento (timing, layout, movimento) de um vídeo de referência com suas próprias palavras e arte, ou construa um novo filme cortado para uma batida a partir de 44 movimentos prontos com uma trilha sonora sintetizada.

O que é motionkit?

motionkit é um kit de ferramentas e motor de renderização para criar filmes de motion graphics programaticamente, usando HTML/JavaScript e um pipeline de linha de comando. Ele permite que agentes de IA (como Claude Code, Cursor ou Codex) gerem vídeos completos em 1920×1080 a 30 fps, com trilha sonora sintetizada, sobreposições alfa animadas e saída para o editor de vídeo EditMax via ferramentas MCP. É útil para tarefas como “clonar este vídeo”, “copiar este movimento”, “fazer um reel como este”, “criar um vídeo de lançamento”, “adicionar um título animado/intro/outro à minha edição” ou qualquer filme motion novo. O motor inclui 44 movimentos prontos (transições, animações de texto, gráficos, partículas e efeitos de câmera), suporte para batidas musicais, verificação automática de sincronismo e um sistema de paleta de cores e tipografia. O fluxo de trabalho é: o usuário escreve um script de filme (arquivos .html e .js) declarando clipes com movimentos, cenas e uma linha do tempo; o comando `bun $E/build.ts` então executa em ordem: linha do tempo, trilha sonora, verificação de som, verificação de tempo de leitura, renderização, junção e verificação de sincronismo, produzindo um MP4 ou MOV (com transparência). O kit também se integra ao editor EditMax, permitindo inserir sobreposições animadas ou clipes completos diretamente na linha do tempo via MCP. É testado apenas no macOS e requer ferramentas como bun, ffmpeg, Python/uv e um navegador Chromium. A documentação inclui exemplos prontos (hello.js, title.js, moves-demo.js) e um guia passo a passo para configuração e criação de filmes.

Funciona com✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SkidGod4444/motionkit/tree/HEAD/skills/motionkit

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que motionkit faz?

Um filme é uma página mais um script cujo renderFrame(f) desenha o quadro f (30 por segundo, 1920×1080) e nada mais. O Chrome oculto avança os quadros, o ffmpeg codifica (o mp4 é dobrado para 60 quadros por segundo em alta qualidade, cerca de 4 a 5 MB por segundo de filme), a trilha sonora é sintetizada.

Onde as coisas estão

  • Motor: a pasta engine/ ao lado deste arquivo (movimentos, renderizador, som, verificações, fontes). Chame-a de $E e use seu caminho completo. Leia a partir dela; nunca coloque filmes nela (a configuração adiciona seu próprio node_modules lá, o que é esperado).
  • Pasta de trabalho: a pasta em que o usuário está trabalhando. Filmes (<nome>.html, <nome>.js), assets/, ref/ e out-<nome>/ vão todos para lá, e todos os comandos são executados a partir dela. Uma página encontra lib.js, moves.js e fonts/ no motor por si só. Se a pasta de trabalho for um repositório git, adicione out-*/ e ref/ ao seu .gitignore.

Primeiro: configurar (uma vez por máquina)

  1. Execute sh $E/setup.sh. Ele apenas verifica: bun, ffmpeg com ffprobe, python3, uv, um navegador Chromium (Chrome, Chromium ou Edge; CHROME_PATH sobrescreve) e o único pacote do motor.
  2. Se imprimir Ready, prossiga. Se apenas engine package estiver faltando (normal em uma instalação nova), execute sh $E/setup.sh --install sem perguntar: ele só baixa um pacote para a própria pasta da skill. Se uma ferramenta ou o navegador estiver MISSING, mostre ao usuário essa lista e os comandos de instalação que foram impressos, e pergunte uma vez antes de instalar software em sua máquina.
  3. Em caso positivo, execute sh $E/setup.sh --install (Homebrew no macOS, os instaladores oficiais para bun e uv), depois execute a verificação novamente. Linhas que dizem run this yourself precisam da senha do usuário (sudo no Linux) ou de um download manual: nunca as execute; forneça ao usuário o comando exato e aguarde. Se uma instalação falhar, forneça ao usuário o único comando para executar por conta própria.
  4. Prove que funciona: a partir da pasta de trabalho, execute bun $E/build.ts hello e confirme que out-hello/hello.mp4 existe.

Testado apenas no macOS; informe isso se o usuário estiver no Linux ou Windows.

Exemplos prontos para copiar: $E/hello.js (um filme em uma grade de batidas, todo som de clipes, cenário desenhado em código), $E/title.js (um título transparente para sobrepor a filmagens), $E/moves-demo.js (cada movimento uma vez).

Construir um filme: clipes primeiro

Declare cada uso de um movimento uma vez como um clipe. A imagem, o som e a verificação de tempo de leitura vêm todos dessa única linha.

const M = window.MOVES, B = M.brand, G = M.grid(120);          // 120 bpm: uma batida são 15 quadros, um compasso 60
const K = { line: M.clip("words", G.bar(1) + 2, 10, { text: "Copie o movimento.", x: 960, y: 590, size: 110, fam: B.display, stretch: B.wide, weight: 600, color: B.paper, until: G.bar(2) }) };
// em uma cena:  K.line.draw(X, f)          K.line.on(f) é verdadeiro enquanto deve estar visível
window.timeline = () => ({ fps: 30, total: TOTAL, bpm: G.bpm, sections: [[0, "intro"], [4, "construção"], [8, "drop"], [24, "outro"]], cues: M.cues(), captions: M.captions() });

Para um vídeo de lançamento ou produto, leia "Vídeos de lançamento e produto" abaixo primeiro. Inicie um filme com bun $E/new.ts <nome>: ele escreve <nome>.html e <nome>.js na pasta de trabalho, copiados do exemplo hello. Reescreva os clipes, cenas e texto. bun $E/build.ts <nome> então faz, em ordem: linha do tempo, trilha sonora (sound.py), verificação de som, verificação de tempo de leitura (lint.py), renderização, junção, verificação de sincronismo (sync.py) e escreve out-<nome>/<nome>.mp4. Uma linha do tempo sem bpm recebe uma trilha sonora mais simples de audio.py (apenas cortes). Opções da linha do tempo: sound: "fx" (apenas sons dos movimentos, sem música), sound: "none", alpha: true (fundo transparente, saída .mov; veja a seção EditMax).

Anatomia de um script de filme

$E/hello.js é o modelo; leia-o uma vez. O que cada parte é:

  • Globais de lib.js: W, H (1920, 1080), X (o contexto do canvas), clamp, lerp, TAU, hash, noise, txt(ctx, text, x, y, size, weight, color, fam, italic, align), rr (retângulo arredondado), vignette(strength, innerRadius).
  • M.clip(move, start, length, options): start e length são quadros; length é quanto tempo o movimento leva para ser executado, não quanto tempo ele fica. Retorna { draw(ctx, f), t(f) (0..1 durante o movimento), on(f), o (as opções) }. Após sua duração, um clipe continua desenhando seu estado final: ele não se esconde. Esconda-o terminando a cena, ou com if (K.x.on(f)), onde on é verdadeiro de start até until (para sempre sem until). Para mostrar um movimento de texto finalizado dentro do from de uma transição, desenhe-o em t = 1: M.words(ctx, 1, K.line.o). Efeitos únicos (burst, glitchCut) precisam também de K.x.t(f) < 1.
  • Formas de chamada dentro de um clipe: transições recebem from e to nas opções; wrappers (punch, shake, sweep, smear) recebem draw. Todo o resto (pathDraw, burst, bars, chart, callout, logoDraw, bounce, ticker) recebe apenas opções. mesh e parallax são fundos: chame-os diretamente, M.mesh(ctx, f / 240, { colors }), onde t é apenas um número que cresce lentamente.
  • Opções de texto: x é o centro da linha (align: "center" é o padrão), y a linha de base. stretch: B.wide dá o corte largo, stretch: null desliga. Nada mede ou quebra texto para você: no tamanho 150 largo, 13 caracteres ocupam cerca de 1.340 px, então renderize um quadro fixo e verifique se cada linha cabe dentro do quadro com margem.
  • Tabela de cenas: [primeiro quadro, draw(f), drawAfterFinish(f)]. renderFrame redefine o estado do contexto (mantenha essa linha), desenha a cena atual, depois granulação e vinheta, depois o terceiro slot para qualquer coisa que deva permanecer limpa (logotipos).
  • window.ready: uma promessa que o renderizador espera: Promise.all([M.fonts(), M.levels("out-<nome>/levels.json"), M.load({ ... })]). M.levels é necessário apenas para M.eq e é seguro antes de o arquivo existir.
  • Linha do tempo: sections são [batida, nome]; um filme curto pode usar apenas [[0, "intro"], [8, "drop"], [16, "outro"]], e cada início de drop recebe o meio-tempo silencioso (mantenha ou coloque clipes mute: lá). sync lista quadros onde um corte e uma batida grave devem coincidir: use o primeiro quadro de cada cena a partir do drop. "Mudança" é julgada contra a diferença quadro a quadro usual do filme, então uma transição que termina exatamente em um quadro de sincronismo não deixa nada para mudar lá e a verificação imprime NO CHANGE: adicione um flash curto ou inicie o próximo movimento nesse quadro. cuts é cada início de cena.
  • Cores: leia tudo de M.brand (B). M.rgba(B.ink, 0.7) dá uma cor com uma opacidade, M.mix(a, b, t) uma cor entre duas. M.setBrand muda M.brand no lugar; chame-o antes de qualquer clipe ser declarado e defina accentOnDark também (o acento usado em fundos escuros; ele não segue accent). Para uma fonte sem corte largo, defina wide: null.
  • Duração: o tempo de leitura define o mínimo: uma linha de 3 palavras precisa de cerca de 1,3 s depois de aparecer, então uma linha por compasso a 120 bpm. A trilha sonora vai cerca de meio segundo além do último quadro e é cortada ali; termine em uma seção outro para que o corte caia em sua cauda.
  • Resultados da construção: build.ts sai com 0 mesmo quando uma verificação falha; falhas imprimem como linhas WARNING: com o detalhe acima delas. Trate cada aviso como uma falha: leia a saída (filtre as linhas de progresso quadro n/total), corrija, reconstrua até que não haja nenhuma. Quadros fixos são escritos como out-<nome>/fNNNN.jpg; leia-os. bun $E/pure.ts <nome> confirma que os quadros renderizam iguais sozinhos e após outros quadros.
  • sound.py precisa de numpy e é sempre executado através de uv run; os outros scripts Python usam apenas a biblioteca padrão.

Vídeos de lançamento e produto: mostre o produto

Um filme de palavras grandes em um fundo parece básico. Vídeos de lançamento que funcionam mantêm o produto na tela em um mundo visual único com profundidade e uma câmera que se move lentamente, usam texto pequeno e breve, e seguram os planos por 2 a 6 segundos (alguns compassos), não um corte por batida. Para um vídeo de lançamento ou produto, NÃO comece de hello:

  1. Decida o visual primeiro: um mundo de fundo, uma cor de destaque, uma família tipográfica. Diga ao usuário em duas linhas.
  2. Storyboard de 6 a 8 planos de coisas reais: a tela ou saída real do produto, comandos reais, código real, resultados reais. Nunca desenhe uma interface que o produto não possui, nunca invente números e nunca use o logotipo de outra empresa. As legendas são pequenos rótulos (txt, mono, canto inferior esquerdo), não manchetes.
  3. Construa um plano herói primeiro, renderize quadros fixos e compare com um vídeo de lançamento real antes de construir o resto.

A página deve carregar stage.js após moves.js (páginas feitas por new.ts fazem isso). Inicie renderFrame com M.frame(); M.reset(X);. Peças de palco (todas em MOVES):

peçao que é
backdrop(ctx, f, { base, lights[], streak })quase preto com piscinas lentas de luz: o mundo em que tudo se assenta
glass(ctx, x, y, w, h, { r, top, bottom, rim, shadow })um painel arredondado escuro com um aro de luz e uma sombra suave
camera(ctx, cam, draw) com cam(a, b, t, ease)olhe para um ponto de uma cena maior: { x, y, zoom, rot }; comece macro-perto e recue, ou deslize lentamente
tilt(ctx, draw, { depth, focus, blur, fog, top, height, width, cx, roll })desenha uma cena em quadro inteiro como um plano inclinado, borda distante menor, mais escura e fora de foco
tiles(ctx, f, { cells: [{ draw(ctx, t), label, bg, len, hold }], cols, x, y, w, gap })uma grade de telas pequenas, cada uma executando um movimento ao vivo (nunca coloque uma transição dentro de um tile)
term(ctx, f, { x, y, size, lines: [{ text, at, speed, prompt, mark: "ok" ou "run", color }] })linhas de terminal que digitam ou aparecem em seu quadro
code(ctx, { lines[], x, y, size, lead, hot, shown })JavaScript com cores de sintaxe suaves e uma linha iluminada
wave(ctx, { peaks, x, y, w, h, played, beats[], blocks[] })a forma de uma trilha sonora real com um cursor de reprodução, marcas de batida e clipes em uma faixa

Peças de palco não fazem som próprio: adicione cues manualmente à linha do tempo, { f, kind, gain } com tipos como type, tick, pop, ding.

Cortar para uma música real

  1. O usuário fornece o arquivo de música e deve ter o direito de usá-lo; diga isso e coloque o crédito que uma licença pedir no cartão final. Nunca baixe uma música de um site de streaming.
  2. uv run $E/beats.py <arquivo> imprime o tempo e o quão alto cada compasso é. Escolha um trecho que comece em um compasso com uma mudança de seção alguns compassos depois, então uv run $E/beats.py <arquivo> --from <segundos> --len <segundos> --out beats.json escreve beats.json e beats.js.
  3. Carregue beats.js na página antes do script do filme. Escreva cada início de cena como um número de batida: const b = (n) => window.BEATS.frames[n]. Corte em compassos (a cada 4 batidas), onde a faixa muda.
  4. Na linha do tempo, defina music: { file, from }, sound: "fx" (os sons dos próprios movimentos permanecem, baixos, sob a música) ou "none", um bpm, e sync: [quadros dos cortes reais]. A construção mistura a faixa a -16 LUFS, desvanece seu final e verifica se cada corte tem uma batida grave dentro de um quadro. Não adicione flashes apenas para passar nessa verificação.

Movimentos para o EditMax (um clipe na linha do tempo de um editor de vídeo)

Use isso quando o usuário estiver editando no EditMax e quiser um movimento no corte: um título animado sobre a filmagem, um cartão de intro ou outro, um tipo cinético entre as cenas. Precisa de duas coisas na mesma sessão do agente: um shell (para renderizar) e as ferramentas MCP do EditMax (inspect_timeline, import_media, ...; configurado a partir da aba Agentes do EditMax). O chat no aplicativo do EditMax recusa comandos de shell, então não pode executar esta skill: diga isso e instrua o usuário a conectar um agente como o Claude Code. Se as ferramentas do EditMax estiverem faltando ou não responderem, renderize o clipe de qualquer maneira e forneça ao usuário o caminho do arquivo para arrastar.

1. Escolha a rota. Prefira as próprias ferramentas do EditMax quando elas cobrirem o movimento, porque o texto permanece editável no aplicativo:

desejadouse
um título ou terço inferior que desaparece, desliza, aparece, digita ou varreadd_text / add_lower_third + set_text_animation
um dissolve, push, slide, wipe ou iris entre dois clipesset_transition
um clipe que se move, escala ou desapareceset_keyframe, set_clip_transform, set_clip_fades
qualquer outra coisa: slam, scramble, split-flap, word wheel, cross-out, highlight, path ou logo draw, charts, counters, bursts, sequências de múltiplos movimentos, um intro ou outro completorenderize um clipe com esta skill

2. Leia o projeto. inspect_timeline: observe o tamanho do quadro, a taxa de quadros, as faixas e o tempo onde o movimento vai. Este motor renderiza 1920×1080 a 30 quadros por segundo. Um projeto 16:9 de outro tamanho o escala limpidamente. Para um projeto vertical ou quadrado, diga claramente que o clipe será letterboxed ou deve ser escalado e cortado com set_clip_transform, e que um título nativo pode ser melhor.

3. Renderize.

  • Sobreposição (fica em cima da filmagem): bun $E/new.ts <nome> --overlay, modelado em $E/title.js. A linha do tempo tem alpha: true e sound: "fx"; a construção escreve out-<nome>/<nome>.mov (ProRes 4444 com fundo transparente). Regras: limpe o quadro (X.clearRect), nunca o preencha; sem grain, vignette, mesh, parallax ou transições de quadro inteiro; coloque uma sombra suave ou uma placa sob o tipo para que ele seja legível em qualquer filmagem; mantenha o tipo dentro dos 90% centrais do quadro; desapareça-o no final.
  • Quadro inteiro (intro, outro, um cartão entre cenas): bun $E/new.ts <nome>, modelado em $E/hello.js; a construção escreve out-<nome>/<nome>.mp4.
  • Som (defina sound: na linha do tempo): omita para a trilha sonora completa (um intro ou outro autônomo); "fx" para apenas os sons que os movimentos fazem (qualquer coisa que toque sobre filmagem, fala ou música do usuário); "none" para silêncio. Pergunte qual o usuário deseja se a edição já tiver música.
  • Construa, corrija cada WARNING e leia os quadros fixos antes de continuar.

4. Coloque o arquivo em algum lugar que dure. O EditMax referencia arquivos importados, não os copia. Copie o arquivo finalizado de out-<nome>/ para uma pasta que o usuário mantenha (pergunte uma vez; sugira ~/Movies/Motions/) e importe de lá.

5. Coloque-o sem mover o corte do usuário. insert_clip com um tempo é uma separação

Habilidades Relacionadas