Communitygithub.com

YahyaLendani/motionbrief

Crie gráficos em movimento e vídeos curtos a partir de HTML ou React — cartões de título, vinhetas de logotipo, texto cinético, contagens regressivas, revelações de estatísticas, terços inferiores, sobreposições transparentes e montagens de recursos.

O que é motionbrief?

Motionbrief é uma habilidade poderosa para agentes de IA que permite gerar vídeos de motion graphics a partir de descrições em linguagem natural. Ela suporta duas estruturas: HyperFrames (HTML + GSAP, ideal para builds rápidas e licenciamento Apache 2.0) e Remotion (React + TypeScript, para projetos mais maduros). O fluxo de trabalho compila automaticamente um brief detalhado em `brief.json`, garantindo que duração, tamanho, FPS, batidas, cópia e transições sejam definidos sem ambiguidade. A habilidade inclui validação rigorosa para evitar erros silenciosos, como timelines não registradas ou fontes não carregadas, e oferece ferramentas para inspecionar quadros, verificar contratos e renderizar vídeos de alta qualidade. O resultado é um processo eficiente, de baixo custo e altamente iterativo, ideal para criar desde vinhetas simples até séries de vídeos em lote.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YahyaLendani/motionbrief-claude-skills/tree/main/skills/motionbrief

Perguntar na sua IA favorita

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

Documentação

Gráficos em movimento

Gere vídeos escrevendo uma página da web que o renderizador percorre quadro a quadro. Ambas as abordagens abaixo fazem a mesma coisa; a diferença é o que você escreve.

  • HyperFrames — um arquivo HTML, CSS para aparência, uma timeline GSAP pausada para movimento. node scripts/hf.mjs executa a versão fixada e a instala uma vez a partir de um lockfile confirmado. Apache 2.0.
  • Remotion — componentes React. useCurrentFrame() retorna o quadro, você faz a matemática. Maduro, tipado e licenciado gratuitamente apenas para até três pessoas.

Carregue a referência correspondente antes de escrever o código da composição. As regras da estrutura não são adivinháveis e a maioria das falhas é silenciosa: um arquivo HyperFrames que nunca registra sua timeline renderiza um quadro estático sem erro.


O caminho fácil

O usuário descreve o que deseja em qualquer palavra. Ele nunca escreve um brief, uma especificação ou um roteiro — Claude compila um.

/motion uma vinheta de logotipo impactante de 6 segundos para Inkwell

Essa é toda a entrada. Por baixo dos panos:

  1. Compile a solicitação em brief.json — duração, tamanho, fps, batidas com tempos, cópia literal, suavização, paleta e uma lista de suposições. Cada lacuna recebe um padrão da tabela em references/brief.md; nada fica indefinido e nada é questionado.
  2. Mostre o resumo compacto (uma tabela, ~12 linhas) e construa na mesma rodada. Sem portão de aprovação.
  3. Construa a partir do modelo, valide, renderize, olhe para os quadros.

A iteração é então uma edição de campo, não uma reconstrução. "Deixe mais impactante" muda sentir.suavizacao e duas durações; o código não se move a menos que tipo ou movimento mude.

O brief é o artefato que torna isso barato. Ele fica no disco ao lado da composição, então uma revisão é um diff, e re-renderizar é um comando.


Roteie primeiro

SinalAbordagem
Build novo, sem estrutura nomeadaHyperFrames
HTML/CSS/GSAP/Lottie existente para reutilizarHyperFrames
Sem node_modules, sem etapa de build desejadaHyperFrames
Equipe maior que três pessoasHyperFrames (licença)
Usuário nomeia Remotion, ou repositório é React/TSRemotion
Precisa de um sistema de design, biblioteca de gráficos ou componentes complexosRemotion
Portando um projeto Remotion existenteRemotion (portar custa mais do que economiza)

Quando o usuário nomeia ambos, construa em HyperFrames e diga em uma linha que o port para Remotion está disponível mediante solicitação. Duas construções completas da mesma peça é trabalho desperdiçado, a menos que uma comparação tenha sido solicitada.


O ciclo

1. Compile o brief

Transforme a solicitação em brief.json antes de escrever código. O esquema, a gramática tipo/movimento, a tabela de padrões e as alavancas de iteração estão em references/brief.md.

node scripts/brief.mjs brief.json          # validar + tabela de resumo
node scripts/brief.mjs brief.json --json   # resultado da máquina

Mostre o resumo ao usuário, corrija qualquer ERRO, depois continue na mesma rodada. Avisos são decisões de julgamento — um aviso que você aceita vai em suposições.

O brief também carrega o ritmo. Escolha audio.bpm para que a grade de batidas divida os cortes — em bpm, uma batida é 60 / bpm segundos e todo batidas[].inicio deve cair em uma delas. 120 BPM dá uma batida a cada 0,5 s e serve para a maioria das peças curtas. Se brief.mjs reportar fora_da_grade, mova o corte ou mude o tempo; não ignore, porque essa é a diferença entre uma peça que acerta e uma que parece sutilmente errada.

Concluído quando brief.mjs sai com 0, cada batida tem uma janela de tempo, um tipo, um movimento e cópia literal, e nenhum corte está fora da grade de batidas.

2. Estruture

Comece pelos modelos nesta habilidade em vez de um arquivo em branco — eles estão corretos em relação a ambos os contratos e evitam as duas etapas propensas a falhas (registro de timeline, temporização de sequência).

# HyperFrames — HTML puro. O motor fixado se instala uma vez, o que precisa de rede
cp -R assets/hyperframes/. ./meu-video/
node scripts/hf.mjs lint ./meu-video

# Remotion — projeto React, precisa de suas dependências fixadas uma vez
cp -R assets/remotion/. ./meu-video/
cd meu-video && npm ci
# PowerShell
Copy-Item -Recurse -Force assets\hyperframes\* .\meu-video\
Copy-Item -Recurse -Force assets\remotion\* .\meu-video\

Concluído quando node scripts/hf.mjs lint passa, ou npx remotion compositions src/index.tsx lista o id da composição.

3. Construa as batidas

Um arquivo por batida. Mantenha a timeline plana — tempos absolutos em HyperFrames, quadros <Sequence> em Remotion. Atualize a folha de batidas quando a construção mudar a temporização, depois verifique novamente a duração total.

Nomeie cada cena após sua batida, porque é assim que as verificações a encontram: data-brief-beat="<id>" no host HyperFrames, <Sequence name="<id>"> em Remotion. Se uma Sequência Remotion calcula sua temporização, também coloque data-brief-beat="<id>" em um elemento dentro dela, para que a temporização possa ser medida.

Concluído quando cada batida na folha existe no código, a duração da composição corresponde à folha, e não há TODOs, stubs ou cópia de placeholder.

4. Verifique o movimento

Quadros parados mentem sobre temporização. Olhe para os quadros, depois olhe para a renderização.

node scripts/check-contract.mjs --dir ./meu-video --preflight   # estático, sem instalação
node scripts/check-contract.mjs --dir ./meu-video --runtime     # também inspeciona em um navegador

node scripts/hf.mjs check ./meu-video                # layout, movimento, contraste
node scripts/hf.mjs snapshot ./meu-video --review    # quadros de batida + emendas como PNGs
node scripts/hf.mjs keyframes ./meu-video --selector "#card" --shot motion.png

npx remotion still src/index.tsx LaunchCard out/f.png --frame=45
npx remotion studio src/index.tsx              # assista em 1x

check-contract.mjs captura as falhas silenciosas sem instalar nada: uma timeline não registrada, uma chave window.__timelines incompatível, uma timeline não pausada, uma duração ausente, Math.random() em uma composição, interpolate sem clamp. É uma pré-verificação, não um substituto para os lintners reais.

Quando brief.json está no projeto (ou --brief aponta para um), ele também compara a construção com o brief. Todo requisito termina como verificado, falhou ou não_verificado. não_verificado não é aprovado e bloqueia a renderização.

CódigoStatusSignificado
brief_formato_incompativelfalhouLargura, altura, fps ou duração diferem de formato
brief_contagem_cenas, brief_cena_nao_mapeadafalhouUma batida não tem cena que declare seu id, ou uma cena não tem batida. Posição não é identidade
brief_temporizacao_incompativelfalhouUma cena não começa ou dura o que o brief diz, dentro de um quadro
brief_copia_ausentefalhouA linha não está na cena. Comentários e variáveis não utilizadas não contam
brief_copia_cena_erradafalhouA linha está apenas em outra cena
copia_nao_visivelfalhouTempo de execução: no DOM mas oculta, transparente, fora da tela, recortada, desfocada ou coberta
copia_segurar_curtofalhouTempo de execução: legível por menos de batidas[].segurar
primeiro_quadro_vaziofalhouTempo de execução: visivelNoInicio está definido e nada da batida é pintado
primeiro_quadro_nao_verificadonão_verificadoTempo de execução: apenas um gráfico está no primeiro quadro, ou a batida não tem cópia. Olhe para o quadro
brief_temporizacao_nao_verificada, brief_formato_nao_verificadonão_verificadoA fonte calcula isso. O tempo de execução pode resolver
brief_copia_dinamica, brief_copia_nao_verificadanão_verificadoSe é mostrado é uma questão de tempo de execução. A cópia do Remotion é sempre esta até o tempo de execução

A correspondência ignora maiúsculas/minúsculas e espaços em branco e dobra aspas curvas. Outra pontuação é significativa, e "12.480" corresponde a uma contagem que se estabiliza em 12480. Quando os requisitos permanecem não verificados, diga quais, e tente torná-los mensuráveis antes de aceitá-los. Aceitar um significa nomeá-lo, com --allow-unverified "batida.linhas.copia[0].visivel", e relatar isso ao usuário. Nunca aceite um padrão genérico, e falhas não podem ser aceitas de forma alguma. Leia references/validation.md para as regras e limites exatos.

Corrija a deriva no código, ou mude o brief intencionalmente e execute brief.mjs novamente — nunca deixe os dois discordarem.

Revise os quadros — toda verificação pode passar em um filme quebrado

Um contrato aprovado diz que temporização e cópia correspondem, e que o texto é legível. Ele não diz nada sobre paleta, suavização, transições, ou se o filme funciona. Os verificadores de lint, layout, movimento, contraste e qualidade passaram no modelo desta própria habilidade enquanto ele cortava para preto em cada batida e encerrava sua contagem no instante em que o número pousava. Apenas olhar para os quadros capturou isso. Capture-os:

# HyperFrames: quadros de batida, uma tira de 5 quadros em torno de cada corte, e uma folha de celular
node scripts/motion-render.mjs --brief ./meu-video/brief.json --snapshot --no-render

# Remotion: para cada corte c (em quadros), pegue c-6, c e c+6, mais o meio de cada batida
# (o modelo corta em 75, 210 e 270)
node scripts/motion-render.mjs --dir ./meu-video --no-render \
  --stills 37,69,75,81,142,204,210,216,240,264,270,276,315

Em seguida, leia as imagens e responda a cada pergunta. Corrija o código, recapture, olhe novamente:

  • O corte está preto? Mais de um quadro vazio em torno de um corte significa que a saída termina cedo e a próxima batida aparece do nada. Mova a saída para que ela termine no corte (inicio = duração da batida − duração da saída).
  • A recompensa se sustenta? O número final de uma contagem, ou a última palavra de uma linha, fica parado na tela por pelo menos uma batida (60 / bpm s) antes de sair. Sair no momento em que pousa significa que nunca é lido.
  • Dá para ler em um celular? Verifique review-phone.jpg, ou imagine o quadro com 360 px de largura. Em 1080p, rótulos e tags abaixo de ~40 px geralmente falham.
  • É a fonte do brief? Uma fonte de fallback como Segoe UI ou Arial significa que a fonte nunca carregou, e outra máquina renderizará um filme diferente. --runtime avisa com fonte_fallback, e o relatório registra as fontes realmente desenhadas. Remotion precisa de @fontsource/* (a escolha do modelo) ou @remotion/fonts para um arquivo local.
  • É a transição do brief? sentir.transicao está nos quadros em torno de cada corte, não um mergulho no preto.

Concluído quando você leu os quadros de batida e cada tira de emenda, respondeu a cada pergunta acima, e cada linha da checklist sob "Checklist de entrega" se sustenta.

5. Renderize

node scripts/motion-render.mjs --brief ./meu-video/brief.json
node scripts/motion-render.mjs --brief ./meu-video/brief.json --batch rows.json --no-audio

O wrapper lê abordagem, formato, fps e slug do brief, e para antes que qualquer tempo de renderização seja gasto se o brief, as verificações estáticas, as ferramentas, os assets ou a verificação de tempo de execução disserem isso. Ele sai com 1 em uma falha e 3 em requisitos não verificados. --no-checks pula a validação e registra isso no relatório. Em seguida, ele faz lint, renderiza, mede o arquivo com ffprobe e escreve <saida>.report.json.

Quando audio.politica é gerado, em qualquer abordagem, ele sintetiza a base com music.mjs, renderiza o vídeo apenas com imagem, e multiplexa os dois com uma chamada ffmpeg — para que a composição nunca dependa do mixer de áudio de um motor. Em seguida, ele mede que o arquivo tem um fluxo de áudio e que não está silencioso.

Para transparência: --format webm ou --format mov — H.264 não pode transportar alfa. --no-audio pula a base e fornece um arquivo sem fluxo de áudio. GIF não pode transportar áudio, então um brief com uma base é recusado para GIF a menos que você passe --no-audio.

Com --batch, um brief mais um arquivo de linhas se torna N vídeos: HyperFrames renderiza linhas nativamente, Remotion recebe um arquivo de props por linha. Batch é apenas vídeo, e um brief com uma base é recusado a menos que você passe --no-audio.

Concluído quando o arquivo existe, o relatório diz renderizado, sua lista naoVerificado está vazia ou você informou ao usuário o que está nela, e seu primeiro e último quadros são intencionais.


O contrato que quebra silenciosamente

HyperFrames — quatro coisas, todas obrigatórias:

  1. A raiz carrega data-composition-id, data-width, data-height, data-duration, data-start="0".
  2. Cada elemento temporizado carrega id + data-start + data-duration.
  3. A timeline GSAP é construída com { paused: true }.
  4. window.__timelines[<data-composition-id>] = tl — mesma chave. Depois que os tweens são adicionados. Perca isso e você obtém um quadro estático, sem erro.

Remotion — três:

  1. registerRoot() no arquivo de entrada, <Composition> no componente raiz.
  2. interpolate(..., { extrapolateLeft: "clamp", extrapolateRight: "clamp" }) — clamp em ambas as extremidades, todas as vezes.
  3. Sem Math.random(), sem Date.now() em uma composição. Use random(seed).

As quatro regras que decidem se parece barato

Estas são as que dão errado com mais frequência. Conjunto completo com código em references/motion-craft.md.

  1. Mova apenas o que está ativo. Coisas estabilizadas ficam paradas. Uma escala de "respiração" ociosa parece gerada por máquina.
  2. Sobreponha, não enfileire. Intercale ≈ 15–30% da duração do próprio elemento. A próxima coisa começa enquanto a última ainda está se estabilizando.
  3. Sem bounce em texto. Overshoot é para objetos com massa — cartões, abas, personagens. Texto, números e rótulos de UI usam power3.out / expo.out e nunca overshoot.
  4. Uma ideia por movimento. y + opacidade é "chegando". Adicione rotação e escala e a palavra fica ilegível durante o voo.

Também: uma transição é a saída, não um fade-out seguido por um fade-in. Isso renderiza como um corte abrupto com um mergulho no meio.


Checklist de entrega

  • brief.json valida: temporização das batidas, primeiro quadro intencional, segurar final ≥ 2 s.
  • check-contract.mjs --runtime diz verificado, ou os ids não verificados são aceitos por nome e reportados ao usuário.
  • Cópia, números, handles e URLs estão como escritos — sem lorem, sem placeholder.
  • Timeline registrada sob o id da composição (HyperFrames), ou composição listada por npx remotion compositions (Remotion).
  • Lint/check limpo.
  • <saida>.report.json diz renderizado, com o tamanho, fps, duração e áudio esperados.
  • Quadros inspecionados: cada batida, cada emenda, largura de celular — sem preto em um corte,

…[truncado para tradução]

Habilidades Relacionadas