Communitygithub.com

gbax316/vidtsx-2d-generator

Gere arquivos TSX 2D de vídeo prontos para produção para VidTSX (baseado em Remotion) a partir de uma descrição de cena, plano ou vídeo.

O que é vidtsx-2d-generator?

Esta skill permite que um agente de IA crie arquivos .tsx de animação 2D totalmente prontos para renderização no VidTSX (plataforma baseada em Remotion). Ela cobre toda a estrutura obrigatória do arquivo, incluindo configuração de composição, presets de dimensão (horizontal/vertical/quadrado), seis presets de estilo visual (minimalista, memphis, neo-brutalismo, glassmorfismo, neon/cyberpunk e corporativo), e regras rígidas de correção que evitam quebras no renderizador. As animações são estritamente baseadas em quadros — não é permitido usar hooks como useState, useEffect ou setTimeout, pois o Remotion renderiza cada quadro de forma independente. A skill também impõe convenções específicas para o uso de interpolate (com intervalos monotônicos crescentes), easing com Easing.bezier, imports adequados para chroma-js e @remotion/paths, e IDs de composição em PascalCase. O resultado final é um arquivo .tsx completo, sem comentários extras fora do código, que o usuário pode editar e renderizar diretamente.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gbax316/shorts-director/tree/main/.claude/skills/vidtsx-2d-generator

Perguntar na sua IA favorita

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

Documentação

Gerador de Vídeo 2D VidTSX

Gere arquivos TSX 2D prontos para produção para VidTSX a partir de uma descrição de um plano ou vídeo. Os arquivos são composições Remotion que o VidTSX renderiza quadro a quadro, então a correção é mais importante que a criatividade: um único intervalo de interpolate não monotônico ou um useState perdido irá quebrar a renderização.

Esta skill cobre gráficos 2D em movimento. Trabalhos 3D (@remotion/three / React Three Fiber) estão fora do escopo.

Como usar esta skill

  1. Plano único claro → gere o arquivo .tsx diretamente.
  2. Pedido complexo, com múltiplos planos ou visualmente ambíguo → confirme a divisão dos planos ou a direção visual em uma mensagem curta primeiro, depois gere. Não pergunte demais; uma confirmação de uma linha é suficiente.
  3. Entregue como um arquivo .tsx real, não como código inline. Esses componentes TSX sempre excedem 20 linhas, e o usuário edita esses arquivos diretamente. Padrão: um plano por arquivo (atômico, fácil de editar), a menos que o usuário peça um único entregável combinado.
  4. O arquivo contém apenas o código do componente — os comentários de seção estrutural abaixo são bem-vindos, mas sem fences markdown, sem prosa explicativa dentro do arquivo.
  5. Renderize e veja antes de considerar pronto — veja Verificar a renderização. Um plano sobre o qual você apenas raciocinou não está finalizado; uma imagem estática (e, para revelações/rolagens, quadros em cada ponto-chave) é o padrão.

Especificação de saída

Presets de dimensão

FormatoLarguraAlturaUso
horizontal19201080YouTube, apresentações
vertical10801920TikTok, Reels, Shorts
quadrado10801080Feed do Instagram

Padrões

  • Formato: horizontal (1920×1080)
  • Duração: 5 segundos
  • FPS: 30
  • Estilo: minimalista (veja references/style-presets.md)

Estrutura obrigatória do arquivo

Cada arquivo gerado segue este esqueleto. Os comentários de seção rotulados são intencionais — eles mantêm arquivos grandes navegáveis.

import React from 'react';
import {
  useCurrentFrame,
  useVideoConfig,
  interpolate,
  Easing,
  AbsoluteFill,
  Sequence,
} from 'remotion';

// =============================================================================
// CONFIGURAÇÃO DA COMPOSIÇÃO
// =============================================================================
export const compositionConfig = {
  id: 'NomeDoComponente', // PascalCase apenas — SEM hífens ou underscores
  durationInSeconds: 5,
  fps: 30,
  width: 1920,
  height: 1080,
};

// =============================================================================
// CONSTANTES DE ESTILO
// =============================================================================
const CORES = {
  primary: '#6366f1',
  secondary: '#8b5cf6',
  accent: '#06b6d4',
  background: '#0f0f23',
  text: '#ffffff',
} as const;

const TIPOGRAFIA = {
  fontFamily: 'Inter, system-ui, sans-serif',
} as const;

const EASINGS = {
  easeOut: Easing.bezier(0.33, 1, 0.68, 1),
  easeIn: Easing.bezier(0.32, 0, 0.67, 0),
  easeInOut: Easing.bezier(0.37, 0, 0.63, 1),
  overshoot: Easing.bezier(0.34, 1.56, 0.64, 1),
} as const;

// =============================================================================
// DADOS PRÉ-GERADOS (calculados uma vez no nível do módulo, NÃO durante a renderização)
// =============================================================================
const seededRandom = (seed: number): number => {
  const x = Math.sin(seed * 9999) * 10000;
  return x - Math.floor(x);
};

// =============================================================================
// COMPONENTE PRINCIPAL
// =============================================================================
const NomeDoComponente: React.FC = () => {
  const frame = useCurrentFrame();
  const { fps, durationInFrames, width, height } = useVideoConfig();

  return (
    <AbsoluteFill style={{ backgroundColor: CORES.background }}>
      {/* Conteúdo */}
    </AbsoluteFill>
  );
};

export default NomeDoComponente;

Substitua NomeDoComponente por um nome em PascalCase descrevendo o plano, defina o bloco CORES a partir do preset de estilo escolhido e ajuste width/height/durationInSeconds/fps conforme a solicitação.


Regras de correção

Estas não são preferências estilísticas — são o que faz uma renderização ter sucesso. VidTSX (via Remotion) renderiza cada quadro chamando o componente em um número de quadro fixo. Não há loop de eventos, persistência entre quadros ou tempo de relógio. Qualquer coisa que assuma essas coisas quebrará.

Animação é baseada em quadros, sempre

  • Conduza todo o movimento a partir de useCurrentFrame() + interpolate().
  • Nunca use useState, useEffect, setTimeout, setInterval ou animações/transições CSS. Eles não se encaixam no modelo quadro a quadro e produzem saída quebrada ou não determinística.
  • Para qualquer coisa aleatória ou procedural, use seededRandom (ou uma função seed equivalente) para que cada renderização de um determinado quadro seja idêntica. Pré-gerar arrays de partículas/aleatórios no nível do módulo, nunca dentro da função de renderização — recomputar por quadro causa cintilação.
  • Animações escalonadas para que os elementos entrem em sequência, não todos de uma vez. Fica melhor e é a aparência esperada.

interpolate — intervalos de entrada devem ser estritamente crescentes

O intervalo de entrada do interpolate deve ser estritamente monotônico crescente. Valores duplicados ou decrescentes geram erro em tempo de execução.

// ✅ Correto
interpolate(frame, [0, 30, 60], [0, 1, 0]);

// ❌ Gera erro — intervalo de entrada decresce
interpolate(frame, [60, 30, 0], [0, 1, 0]);

Para inverter um mapeamento, inverta o intervalo de saída, nunca o intervalo de entrada:

// ✅ Correto — mapeia 0→100, 1→0
interpolate(value, [0, 1], [100, 0]);

// ❌ Errado
interpolate(value, [1, 0], [100, 0]);

Para temporização baseada em índice, certifique-se de que startFrame < endFrame e sempre use clamp:

const startFrame = index * 30;
const endFrame = startFrame + 30;
interpolate(frame, [startFrame, endFrame], [0, 1], {
  extrapolateLeft: 'clamp',
  extrapolateRight: 'clamp',
});

Sempre passe extrapolateLeft: 'clamp' e extrapolateRight: 'clamp' a menos que um valor ilimitado seja genuinamente desejado — sem eles, os valores ultrapassam seu intervalo antes/depois dos keyframes.

Easing — use Easing.bezier(), nunca sintaxe wrapper

Formas wrapper como Easing.out(Easing.cubic) quebram. Defina beziers nomeados uma vez (veja o bloco EASINGS no esqueleto) e referencie-os:

// ❌ Quebra
Easing.out(Easing.cubic);
Easing.in(Easing.quad);

// ✅ Correto
interpolate(frame, [0, 30], [0, 1], {
  easing: EASINGS.easeOut,
  extrapolateRight: 'clamp',
});

chroma-js — apenas importação de namespace

// ✅ Correto
import * as chroma from 'chroma-js';
const color = chroma('#00bfff').brighten(0.5).hex();

// ❌ Errado — "chroma is not a function"
import chroma from 'chroma-js';

@remotion/paths — apenas as funções reais existem

Estes helpers não existem e nunca devem ser usados: makeCircle(), makeRect(), makeTriangle(), makeLine(), makePie(), makePolygon(), makeEllipse(), makeStar().

Apenas estes imports são válidos:

import { evolvePath, getLength, getPointAtLength, getTangentAtLength } from '@remotion/paths';

Escreva strings de caminho SVG manualmente e anime-as com evolvePath:

const circlePath = 'M 50 10 A 40 40 0 1 1 49.99 10 Z';
const rectPath = 'M 0 0 L 100 0 L 100 50 L 0 50 Z';
const linePath = 'M 0 0 L 100 100';

const { strokeDasharray, strokeDashoffset } = evolvePath(progress, rectPath);

ID da composição

compositionConfig.id é apenas PascalCase — sem hífens, sem underscores (ex.: ProductReveal, não product-reveal ou product_reveal).


Layout

Zonas seguras

  • Top 10%: reserve para a UI da plataforma.
  • Bottom 15%: reserve para legendas/botões.
  • Mantenha o conteúdo principal entre 25%–75% verticalmente.

Auxiliar de centralização

const centered: React.CSSProperties = {
  position: 'absolute',
  top: '50%',
  left: '50%',
  transform: 'translate(-50%, -50%)',
};

Tipografia

ElementoTamanhoPeso
Manchetes72–120px700–900
Subtítulos36–48px500–700
Corpo28–36px400–500

Sempre defina margin: 0 em elementos de texto — valores padrão do navegador deslocam layouts do centro.


Presets de estilo

Neste repositório o padrão é a marca da casa, não um preset. Planos importam CORES, GRADIENTE, RAIO, SOMBRA, EASINGS de remotion/src/brand.ts e FONTE_MANCHETE, FONTE_EXIBIÇÃO, FONTE_CORPO, FONTE_MONO de remotion/src/fonts.ts em vez dos blocos locais CORES/TIPOGRAFIA do esqueleto, e seguem brand.md. FONTE_MANCHETE (Instrument Serif) tem um peso: nunca dê a ela fontWeight. Os planos ficam no fundo dia a menos que seu compositionConfig diga ground: 'night'; os componentes do kit (lib/shorts.tsx, BrandBg) escolhem suas cores a partir dele, então leia useGround() de brand.ts para qualquer cor que você definir.

Quando o usuário nomear um estilo, carregue sua paleta e características de references/style-presets.md e insira o objeto CORES no esqueleto. Os seis presets são: minimalista, memphis, neo-brutalismo, glassmorfismo, neon/cyberpunk, e corporativo. Se nenhum estilo for nomeado, use a marca da casa acima.


Verificar a renderização (não pule)

Um plano não está pronto até que você tenha olhado para ele. Após escrever o .tsx, renderize pelo menos uma imagem estática e abra-a — nunca entregue um plano sobre o qual você apenas raciocinou. A renderização pode ter sucesso e os números parecerem corretos, mas o texto pode transbordar seu cartão, uma imagem pode ser cortada no lugar errado, um elemento pode estar fora da tela, ou duas coisas podem se sobrepor. Apenas uma captura de tela pega isso.

  • Renderize uma imagem estática (ex.: node scripts/render-all.mjs --still --scale=1 <ShotId>) e Leia o PNG.
  • Para revelações baseadas em tempo (elementos entrando em um ponto-chave, rolagens, fases encenadas), uma única imagem estática com 60% da duração não é suficiente — renderize o clipe completo e extraia quadros em cada momento chave (ffmpeg -ss <t> -i out/<id>.mp4 -frames:v 1 f.jpg), ou renderize imagens estáticas em vários deslocamentos. Verifique o estado em cada ponto-chave, não apenas em um quadro.
  • Verifique especificamente: imagens cabem em seu espaço (nenhum conteúdo importante cortado; prefira objectFit: contain em um fundo correspondente para imagens reais heterogêneas), texto não está cortado ou transbordando, nada está fora da área segura, e cada elemento animado está realmente visível quando deveria.
  • Se estiver sobreposto a outras filmagens, também verifique um quadro do resultado final finalizado, não apenas o plano isolado.

Corrija o que a captura de tela revelar, depois re-renderize e olhe novamente. Trate "Eu renderizei e parece correto" — com o quadro mostrado — como o padrão para pronto.


Saída final

Gere o arquivo .tsx completo e nada mais dentro dele — sem markdown ao redor, sem comentários antes ou depois do código no próprio arquivo. Uma pequena nota de uma linha no chat ao entregar o arquivo é aceitável.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

gbax316/make-ai-short

Build a GENERATIVE-pixels vertical short (1080×1920, ~35-40s) end-to-end — a recurring locked character animated by a fal video model (Seedance 1.5 Pro default) under a philosophical/story VO, composited in Remotion with word-synced captions, SFX audition, seamless frame-0==last-frame loop. Use when the user wants to "make an AI video short", "make an ai short", "make a blue-man video", or any short where the pixels come from a VIDEO MODEL — not TSX animation (that is make-short) and not layered collage (that is make-vox). Defers model choice re-litigating to ai-shorts/IDEAS.md, TSX crash rules to vidtsx-2d-generator, SFX taste to suggest-sfx + brand §7. For a NEW short (writers' room, dialogue skits, documentaries, mixed render paths), start with shorts-director, which calls this track as an engine.

gbax316/shorts-director

Directs a faceless vertical short from idea to finished, mastered file, and gets better with every run. Picks a format, writes the episode in a writers' room (three premises judged as the buyer), voices it, gates on an animatic, then decides beat by beat how each moment is made: drawn in code in Remotion, a cut-out from a generated still, a generated clip, or one of the engine tracks. Modes: series, writers-room, produce, sound, finish, bakeoff, effects (/effects), improve (the learning loop after every short). Formats so far: character skit with dialogue and synced mouths, photoreal mini documentary with sourced figures. Triggers on "make a short", "next episode", "make a video about X", "faceless video", "reel for this offer". Do NOT trigger for editing an existing video file, for a pure code-drawn explainer with no writers' room (make-short), or for collage (make-vox).

Habilidades Relacionadas