Communitygithub.com

stickman-explainer

Produz vídeos verticais (9:16) animados no estilo 'stick figure' (desenho à mão) para Reels/Shorts/TikTok a partir de roteiro, usando um renderizador Python guiado por storyboard JSON.

O que é stickman-explainer?

Esta skill permite criar vídeos explicativos animados no formato curto (9:16, 1080×1920) no estilo 'stick figure' desenhado à mão, com fundo de papel creme, tinta preta e um acento vermelho. O usuário escreve um storyboard JSON descrevendo cenas, elementos e transições, e a skill renderiza cada frame com linhas trêmulas, animação de 'line-boil' a 8 fps, e efeitos de fade, wipe ou pop. Opcionalmente, pode-se incluir áudio de narração e sincronizar o destaque vermelho nas legendas com a palavra falada (efeito karaokê). A skill é ideal para automatizar a criação de vídeos de história, anedotas ou conceitos simples, sem necessidade de ferramentas de edição tradicionais, e suporta continuidade de elementos entre cenas, validação de storyboard e mensagens de erro claras.

Funciona com✓Claude Code✓Codex CLI~Cursor✓Antigravity✓OpenCode
npx skills add https://github.com/Apollonny/stickman-explainer/tree/main/stickman-explainer

Perguntar na sua IA favorita

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

Documentação

O que stickman-explainer faz?

Transforma um roteiro curto em um mp4 finalizado de 1080×1920. Você escreve um storyboard JSON; scripts/render.py desenha cada frame (linhas trêmulas a tinta, line-boil a 8 fps, revelações com fade/wipe/pop) e codifica com ffmpeg.

assets/example_storyboard.json é apenas um exemplo de sintaxe (3 cenas); não copie seu layout ou acessórios de personagens como modelo.

Padrões de estilo visual

  • Use uma tela 9:16 (1080×1920, 30 fps). Mantenha cada cena em uma ideia, geralmente 2,5–4 segundos, com legendas curtas dentro de áreas seguras da plataforma.
  • Use papel quente (#f3ebdd), tinta escura (#2b2723), e acento vermelho-tijolo semântico (#b8372d). Ouro (#d89d48) é opcional apenas para o motivo do sol. Mantenha o resto plano: sem gradientes, sombras ou efeitos 3D.
  • Desenhe figuras simples de tinta preta com rostos claros e bastante espaço negativo. Não adicione capacetes, coroas, capas, roupas vermelhas ou outros acessórios a menos que a história ou o usuário os peça. Não infira figurinos a partir de um nome histórico.
  • Mantenha as cenas legíveis: no máximo 2 personagens e 5 ícones pequenos. Faça o assunto principal dominante; evite sobreposição de legendas e adereços. Use no máximo 2 linhas de legenda.
  • Torne adereços complexos reconhecíveis. Desenhe um nó com voltas distintas que se cruzam, um centro apertado e pontas de corda visíveis. Dê a uma espada um cabo claro, guarda e lâmina pontiaguda. Após um corte, deixe uma lacuna visível entre as duas pontas da corda.
  • Quando os tempos de narração estiverem disponíveis, faça o destaque vermelho da legenda seguir a palavra falada durante toda a narração. Use um intervalo karaoke para cada palavra separada por espaço na legenda; palavras não ativas permanecem na cor normal do texto.
  • Prefira layouts assimétricos e deixe espaço negativo deliberado. Linhas de chão, sóis, cartões de título, balões de pensamento e outros motivos são opcionais; escolha-os apenas quando eles apoiarem a cena.

Fluxo de trabalho

  1. Roteiro → cenas. Divida a história em cenas de uma frase (≤ 6 palavras de legenda, 2,5–4 s cada). Padrão: cartão de título → gancho/conflito → revelação concreta. Cada cena adiciona exatamente uma nova informação. Quando a narração for fornecida, alinhe os limites da cena às frases faladas.
  2. Escolha um visual para cada frase. Uma metáfora por cena: personagem + adereço, balão de pensamento ou uma fileira de ícones (X = "não tem"). Mantenha ≤ 2 personagens e ≤ 5 ícones.
  3. Escreva o storyboard (esquema abaixo). Com tempos de narração no nível da palavra, adicione um intervalo karaoke para cada palavra separada por espaço na legenda, para que o acento vermelho siga a palavra sendo falada. Use **palavra** apenas para um destaque estático quando o tempo da palavra não estiver disponível; não combine marcação estática com karaoke.
  4. Verifique os stills primeiro (rápido, ~2 s/cena): python scripts/render.py story.json --stills out/stills → abra cada scene_NN.png, corrija sobreposição/posicionamento, repita.
  5. Vídeo rascunho: python scripts/render.py story.json out/draft.mp4 --draft (sem supersampling, 12 fps).
  6. Final: python scripts/render.py story.json out/final.mp4 [--audio voiceover.mp3]. As durações das cenas devem corresponder ao comprimento das frases da narração; meça o áudio com ffprobe e defina duration de acordo. Os intervalos das palavras são em segundos desde o início da sua cena e devem vir do alinhamento da narração ou da escuta cuidadosa. Verifique se cada palavra vermelha aparece com seu áudio falado, não antes nem depois.

Mensagens de erro e validação

render.py valida o storyboard antes de desenhar: type/pose/face/kind/font desconhecidos, campo obrigatório ausente, id repetido na mesma cena, duration <= 0, caminho lines de ponto único, resolução ímpar (não par) e id de carry inexistente são rejeitados com mensagem clara em vez de traceback. Aviso é emitido para elementos que nunca serão vistos (at após o fim da cena). Se o arquivo de áudio for mais curto que o vídeo, o final é preenchido com silêncio; se for mais longo, é cortado; a duração do vídeo nunca muda.

Esquema do storyboard

{"meta": {"width":1080,"height":1920,"fps":30,"boil_fps":8,"transition":0.18,
          "palette":{"accent":"#b8372d"}, "audio":null, "font_dirs":[]},
 "scenes":[{"duration":3.4, "caption":"Foi **Alexandre**, o Grande.",
            "caption_at":0.5, "caption_y":null, "elements":[ ... ]}]}

Para ênfase de palavras seguindo a fala, forneça um array karaoke com um objeto { "start": segundos, "end": segundos } por palavra separada por espaço em caption. Os tempos são locais à cena; a ênfase vermelha muda em cada intervalo. A legenda não deve conter marcação **...** quando karaoke estiver presente.

{"duration":2.8, "caption":"Cortou o nó com um golpe.", "caption_at":0.35,
 "karaoke":[{"start":0.35,"end":0.76},{"start":0.76,"end":1.02},
            {"start":1.02,"end":1.53},{"start":1.53,"end":2.15}],
 "elements":[ ... ]}

Cada elemento: type, id opcional (para carry), at (s, tempo de aparecimento), dur (s, revelação), anim = fade | wipe | rise | pop, until/out_dur (s, desaparecimento). Posições x,x2,y,ground ≤ 2 são lidas como frações da largura/altura, caso contrário pixels. Tamanhos são sempre em pixels.

tipocampos principais
groundy (obrigatório); x, x2 opcionais, se não fornecidos ~2%–98% da tela — linha de base trêmula
sunx,y,r,rays
texttext (marcação **accent**), x,y,size,font = sans/sans_bold/sans_light/serif, tracking, caps, color, max_w, max_lines (padrão 3), rules (linha dupla para cartão de título; largura e espaçamento automáticos conforme o texto)
figurex,ground,h,head_r, pose = stand/arms_open/point/wave/think/shrug/sit, dir (±1), face = neutral/smile/sad/surprised/angry, accessory opcional = helmet/crown/hat/glasses, cape opcional, look
propkind = barrel/bowl/bucket/house/book/box/triangle/coins/tree, x,y (canto superior esquerdo), w,h, cross (X de acento), flip
thoughtx,y,w,h, tail_to [px,py] (posição da cabeça), inner: lista de elementos em px local ao balão
linespaths (lista de listas de pontos, px local), closed, smooth, color, width — escape hatch para qualquer forma personalizada

Continuidade entre cenas (carry)

Para transportar um elemento de uma cena para a próxima, dê a ele um id e chame-o na cena seguinte com carry. O elemento transportado começa com a mesma trepidação de linha (mesma seed), portanto parece ser "o mesmo desenho" mesmo com a mudança de cena; a transição de cena padrão é um corte (sem crossfade).

"carry": [
  "ground",
  {"id": "sun",  "set": {"r": 122}},
  {"id": "alex", "set": {"x": 120, "face": "smile"}, "tween": {"at": 0.1, "dur": 0.9}},
  {"id": "diog", "until": 0.1, "out_dur": 0.5}
]

As linhas são processadas em ordem: "ground" é transportado exatamente como está · sun é transportado com campo alterado (a alteração é instantânea no início da cena) · alex tem campo alterado e posição interpolada ao longo do tempo (tween) · diog é transportado, mas desaparece gradualmente dentro da cena.

  • "carry": "all" transporta tudo ("carry_except": ["id", ...] exclui itens). A legenda nunca é transportada.
  • Um elemento não transportado desaparece instantaneamente no início da cena; para desaparecimento suave, use until/out_dur. Um elemento que desaparece com until não pode ser transportado para a próxima cena.
  • tween anima apenas posição (x e y/ground); mudanças de tamanho (r, h, w) e aparência (face, pose) são aplicadas instantaneamente no início da cena.
  • Elementos transportados são desenhados abaixo dos novos elementos. id deve ser único entre cenas para elementos a serem transportados.
  • Um elemento com o mesmo id usa a mesma seed em cada cena; para um novo elemento específico da cena, não forneça id.

Adicione novos adereços/poses estendendo PROPS / hands em render.py; mantenha o mesmo estilo de tinta (use stroke(), nunca linhas simples).

Layout: decida novamente para cada vídeo

Não existem coordenadas/modelos fixos. Como o assunto de cada vídeo é diferente, derive o layout do conteúdo da cena:

  • Primeiro, escolha a única ideia visual para aquela frase (comparação, lista, sonho, jornada, número…), depois monte o layout que se encaixa nela. O layout pode variar entre cenas no mesmo vídeo.
  • Abra espaço para o elemento importante: o assunto principal deve ser o maior/mais proeminente; os elementos secundários devem ser pequenos. Deixe espaço vazio (espaço negativo) de forma deliberada.
  • Tamanho, posição e número variam conforme o conteúdo (1 personagem ou 2; fileira de ícones ou um único objeto grande; mapa/linha do tempo). Se necessário, desenhe formas personalizadas com lines.
  • Não adicione figurino/cobertura automaticamente para figuras históricas. As figuras são desenhadas sem acessórios por padrão; capacete, coroa, chapéu ou capa são adicionados apenas se a narrativa ou o usuário explicitamente exigir. Não espalhe a cor de acento como adereço na roupa do personagem.
  • Em cenas de nó e corte, construa o objeto de forma legível: desenhe a corda com várias voltas que se cruzam visivelmente, mostre o nó apertado no centro e diferencie as pontas. Na espada, o punho, a guarda e a lâmina pontiaguda devem ser distinguíveis. Após o corte, deixe as duas pontas cortadas da corda espaçadas e claramente visíveis; a espada e o nó não devem ser cobertos pela legenda. Desenhe formas de corda/espada personalizadas com lines.
  • Linhas de chão, sol, cartão de título e outros motivos são opcionais; não use se não combinarem com o assunto (ex.: interior, noite, conceito abstrato).
  • Coloque a legenda em um local legível e longe da interface da plataforma; se houver conflito, ajuste com caption_y. Verifique conflitos e estouros visualmente nos stills, não confie em números.
  • As coordenadas de desenho são fornecidas em pixels (ou proporção 0–2) na tela de 1080×1920; planeje os valores do zero para cada cena.

Pegadinhas

  • Sempre veja os stills antes de codificar; elementos sobrepostos e raios de sol cortados são os defeitos mais comuns. Use --draft para rascunho, renderização completa para detalhes: quadros inalterados não são redesenhados, um vídeo de 10 s leva cerca de 20 s em qualidade total.
  • A legenda quebra em até 86% da largura (máximo 3 linhas), mas diminui se uma palavra não couber ou exceder 3 linhas. Divida uma frase com mais de 2 linhas em duas cenas. A posição padrão da legenda é apenas um fallback; forneça caption_y na cena se necessário.
  • Fontes: instale Poppins e Playfair Display (ou Lora) ou forneça --font-dir. Se nenhuma fonte TrueType for encontrada, o renderizador emite um aviso e caracteres turcos (İ ş ğ â) podem ficar ausentes; verifique nos stills. Pastas de fontes do Linux, macOS e Windows são varridas.
  • Mantenha a cor de acento semântica (assunto, palavra-chave, negação). Não adicione mais cores.
  • Quando karaoke estiver presente, o destaque vermelho da legenda segue a narração palavra por palavra usando os intervalos fornecidos. Não deixe uma palavra-chave vermelha fixa na tela; renderize palavras não ativas na cor normal do texto da legenda.

Habilidades Relacionadas