Communitygithub.com

KehanLiu/anim-slides

Transforme slides monótonos em ilustrações SVG animadas e ricas. Cria gráficos SVG animados autocontidos (com keyframes CSS e modo opcional de etapas controladas por clique) que substituem blocos de texto e capturas de tela em qualquer deck HTML, gerando-os diretamente a partir de documentação de processos, dependências, cronogramas ou arquiteturas.

O que é anim-slides?

O skill **anim-slides** cria ilustrações SVG animadas para decks de slides, convertendo slides existentes ou documentação em fragmentos HTML autocontidos. O resultado é sempre um fragmento: um único arquivo HTML com um bloco `<style>` e um `<svg>`, sem scripts externos ou arquivos adicionais, que pode ser inserido em qualquer deck HTML (como reveal.js, Slidev, impress.js ou decks escritos à mão). O skill é ideal quando um slide contém apenas cartões de texto, listas de marcadores ou capturas de tela, e o conteúdo descreve um processo, fluxo, estrutura de dependências, cronograma, comparação, arquitetura ou série temporal. Ele também funciona a partir de documentação em Markdown, exportações do Confluence, READMEs ou diagramas Mermaid. O fluxo de trabalho inclui extração de slides, definição de especificações (com nós, arestas, grupos e fases), construção de fragmentos, verificação visual com capturas de tela e integração ao deck alvo, respeitando contratos de fragmento, regras de estilo e precisão factual.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/KehanLiu/anim-slides/tree/HEAD

Perguntar na sua IA favorita

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

Documentação

O que anim-slides faz?

Ilustrações SVG animadas para decks de slides, a partir de slides existentes ou de documentação. O resultado é sempre um fragmento: um arquivo HTML com um <style> e um <svg>, sem scripts, sem arquivos externos, tematizado por variáveis CSS, que se encaixa em qualquer deck. references/fragment-contract.md é o contrato. Leia-o antes de construir qualquer coisa.

Quando usar

  • Um slide é uma fileira de cartões de texto, uma lista com marcadores ou uma captura de tela, e o conteúdo é um processo, um fluxo, uma estrutura de dependências, um cronograma, uma comparação, uma arquitetura ou uma série temporal.
  • Um documento (Markdown, exportação do Confluence, README, bloco Mermaid) descreve um processo ou dependências e o usuário deseja que ele seja mostrado como uma animação em um slide ou página.
  • O hospedeiro é um deck HTML (frontend-slides, reveal.js, impress.js, Slidev, escrito à mão) ou uma página web simples. Um arquivo .pptx ou fonte Markdown é primeiro convertido em um deck HTML projetado por um skill de deck (etapa 0); este skill então adiciona as ilustrações.

Fluxo de trabalho

<skill-dir> abaixo é a pasta que contém este SKILL.md (Claude Code expõe como $CLAUDE_SKILL_DIR; em outros ambientes use o caminho de onde carregou este arquivo). Scripts precisam de Python 3.9+ e, para renderização, um binário Chrome ou Chromium. anim/<nome>/ é uma pasta ao lado do deck do usuário.

0. Entrada

Obtenha um deck HTML primeiro. anim-slides adiciona figuras a um deck HTML; ele não projeta um.

  • A fonte já é um deck HTML (reveal.js, impress.js, qualquer deck com <section> ou .slide): prossiga.
  • A fonte é um .pptx, Markdown, remark, um documento ou qualquer outra coisa que não seja um deck HTML: um skill de deck constrói o deck HTML primeiro, não o anim-slides. Em ordem de preferência: (a) o skill de deck do próprio usuário ou da organização, se estiver instalado; (b) frontend-slides, quando instalado (converte pptx e Markdown em um deck HTML projetado; quando oferece pré-visualizações estéticas, escolha a mais próxima da marca do deck fonte, a menos que o usuário queira um novo visual); (c) apenas quando nenhum skill de deck estiver instalado, scripts/md_to_deck.py como fallback (veja o bullet de fallback abaixo), e informe ao usuário em uma frase que sua saída é um hospedeiro simples, não um design, e parecerá um documento até que um skill de deck ou um designer o estilize. Nos casos (a) e (b), o .pptx original permanece como fonte para triagem de extract_slides.py e render_deck.py (gráficos, figuras, notas), mas a integração tem como alvo o deck que o skill produziu, e a aparência correspondente vem da paleta desse deck via host_theme.py. Peça ao skill de deck (ou faça logo após) para envolver o corpo de cada slide candidato em um slot de tamanho fixo <div id="sN-slot"> entre <!-- sN-body --> e <!-- /sN-body --> (o id e os nomes de marcadores que md_to_deck.py usa, embora lá o slot seja um irmão vazio do corpo): measure_slot.py --selector '#sN-slot' é então exato, e integrate_fragment.py --anchor/--replace-until tem como alvo os marcadores. O link de fonte de um skill de deck (Google Fonts, Fontshare) é a carga do deck, não uma adicionada pelo anim-slides; mantenha-o e incorpore-o na entrega com bundle_deck.py --fetch.

Em seguida, decida qual ponto de entrada se aplica:

  • Deck existente: execute python3 <skill-dir>/scripts/extract_slides.py deck.pptx|deck.html|doc.md -o anim/outline.json e python3 <skill-dir>/scripts/render_deck.py deck -o anim/render, depois olhe as folhas de contato sheet-NN.png (12 slides numerados cada), não página por página (quando a contagem de imagens de um slide em outline.json difere das imagens em sua renderização, observe as imagens do layout do slide: uma foto de capa no layout é fácil de perder); em seguida, faça a triagem com references/input-stage.md e escreva a tabela em anim/triage.md: cada slide, uma decisão e um motivo, sem pulos silenciosos (3 a 8 ilustrações por 30 slides é normal; em um deck curto, cada slide de processo, estrutura, cronograma, comparação ou dados recebe uma). Em seguida, defina a aparência uma vez para todo o deck: match (fragmentos herdam a paleta e as fontes do hospedeiro, o padrão para decks corporativos ou com marca) ou lean (fragmentos mantêm a paleta enxuta em um fundo escuro, para palestras e pitches). python3 <skill-dir>/scripts/host_theme.py deck.html --mode match -o anim/host-theme.css deriva a cola de match do CSS do deck (--mode lean escreve a cola lean); compare o bloco derivado uma vez com as próprias variáveis do deck (uma cor de texto suave, um fundo secundário) e corrija manualmente onde a derivação escolheu uma mistura computada; renderize o primeiro fragmento de ambas as formas (render-phases.sh --theme anim/host-theme.css ...) e mostre as duas imagens estáticas antes de construir o restante, a menos que o usuário já tenha nomeado uma aparência. Apenas cores e fontes mudam entre as duas: as regras de forma de references/style.md valem em ambas. O controle é once para todo o deck, a menos que o usuário solicite passagem por clique: cada figura do slide executa uma passagem calma quando o slide aparece e depois descansa. Não recomende step por conta própria. Mencione-o em uma linha apenas quando outline.json relatar builds acima de 0 (a fonte já constrói por clique: fragmentos reveal.js, animações de clique do PowerPoint, subetapas impress.js, as próprias etapas de construção do deck): "seu deck constrói por clique; as figuras podem fazer o mesmo (step), diga se você quer isso". Sob step, a entrada desenha e cada clique aterrissa a próxima fase; as fases são as fases narradas do briefing (3 a 5 por slide), o arquivo do fragmento é o mesmo, e o clique viaja na própria navegação do deck. Step escuta apenas teclas, então um deck step é apresentado com o teclado ou um clicker (um deck que também navega por roda ou deslize, como o frontend-slides faz, pula as fases em uma rolagem). Escreva Aparência e Controle no cabeçalho de anim/triage.md.
  • Fallback, nenhum skill de deck instalado (Markdown, remark ou um pptx extraído para Markdown): python3 <skill-dir>/scripts/md_to_deck.py deck.md -o deck.html faz um hospedeiro simples e autocontido para integrar (uma <section> por slide, portão .visible, layout de impressão, marcadores <!-- sN-body --> em volta do corpo de cada slide). Não é um deck projetado: diga isso ao usuário em uma frase. Busque as imagens que o Markdown referencia (caminhos relativos) na mesma pasta primeiro, ou o deck mostrará placeholders; em seguida, extraia da fonte original (o .pptx se houver um) ou do Markdown.
  • Documentação: leia a fonte, escolha o arquétipo com a tabela em references/archetypes.md, extraia uma especificação (etapa 1).
  • Solicitação de slide único: vá diretamente para a etapa 1 para esse slide. Pergunte ao usuário apenas quando a fonte for ambígua sobre ordem, direção ou agrupamento. Caso contrário, declare a suposição no briefing e continue.

1. Especificação

Escreva anim/<nome>/spec.yaml seguindo references/spec-format.md: nome, arquétipo, nós, arestas, grupos, fases com marcas de segundos, ciclo (a duração da passagem), controle (a escolha do deck da entrada: once, uma passagem calma de 4 a 10 s quando o slide se torna atual, terminando no quadro de repouso; step, a mesma passagem cortada nas marcas de fase para que cada clique aterre a próxima fase; loop apenas quando o usuário solicitar um loop contínuo). O arquivo do fragmento é o mesmo sob once e step; as marcas de fase se tornam data-anim-phases. Reutilize as palavras da própria fonte como rótulos. Mantenha uma especificação com cerca de 12 nós no máximo; divida caso contrário.

1b. Verifique o pool

Leia <skill-dir>/pool/index.yaml, depois $ANIM_POOL/index.yaml (ou liste $ANIM_POOL/*/) se essa variável estiver definida, e procure uma entrada com o mesmo arquétipo e uma história ou tags semelhantes.

  • Correspondência próxima: copie a pasta para anim/<nome>/, renomeie o fragmento e cada prefixo para <nome>, depois adapte rótulos, dados, temporização e viewBox à especificação na etapa 3 em vez de scaffold. Seu spec.yaml, se presente, é um ponto de partida para o seu.
  • Mesmo arquétipo apenas: faça o scaffold normalmente e abra o fragmento do pool como referência de qualidade para densidade, movimento e quadro de repouso.
  • Nada se encaixa: construa a partir da especificação; a entrada mais próxima do pool ainda vale uma olhada. Nunca copie um fragmento do pool inalterado em um deck: sua história é um exemplo, não a do usuário.

2. Slot e briefing

Meça a caixa livre no slide: python3 <skill-dir>/scripts/measure_slot.py deck.html --slide N [--selector SEL] [--ignore .body] imprime a caixa em pixels de palco, um viewBox correspondente e as bandeiras do verificador (references/layouts.md explica o método manual). Em um layout posicionado absolutamente, medir sem --selector retorna lixo; meça o div slot (--selector '#sN-slot', etapa 0). Escolha um viewBox com a mesma proporção de aspecto e preencha anim/<nome>/brief.md a partir de references/brief-template.md. O briefing fixa viewBox e tamanho renderizado, composição, fases, quadro de repouso, tokens de tema e tamanho mínimo de texto, e nomeia o que no slide o fragmento substitui (as pílulas, o diagrama de caixas, a coluna de marcadores). A qualidade do fragmento acompanha a qualidade do briefing.

3. Construção

python3 <skill-dir>/scripts/scaffold_from_spec.py anim/<nome>/spec.yaml -o anim/<nome>/<nome>.html --rendered-width <px> valida a especificação e escreve um esqueleto compatível com o contrato (layout, fases, pacotes, notas, quadro de repouso; tamanhos de fonte elevados ao mínimo na largura renderizada), depois executa o verificador nele. O comentário no topo da saída lista o que refinar manualmente. Refine-o na ilustração que o briefing descreve, usando references/archetypes.md para composição e movimento, references/motion-rules.md para temporização e easing, e references/style.md para a aparência (lean: anéis e linhas finas, sem caixas, um acento brilhante, sub-rótulos mono, legendas simples). Para várias ilustrações, construa um fragmento de cada vez a partir dos briefings compartilhados, ou um subagente paralelo por fragmento se o ambiente os tiver; a integração sempre permanece na thread principal.

4. Verifique visualmente

  1. python3 <skill-dir>/scripts/check_fragment.py anim/<nome>/<nome>.html --name <nome> --rendered-width <px> --stage-width <largura do palco do deck> deve passar (prefixos, tokens, portões, tamanho do texto, conteúdo proibido). --stage-width define o mínimo de texto (18 px em 1920, 12 px em 1280); outline.json relata o palco.
  2. <skill-dir>/scripts/render-phases.sh anim/<nome> <W> <H> 1.5 4 7 10 rest renderiza PNGs de fase e uma folha de contato com o método pausado e delay negativo, em uma pasta temporária que ele imprime (passe --out DIR para escolher). Após a integração, render-phases.sh --page deck.html 1920 1080 rest verifica o quadro de repouso da página hospedeira; em uma página com vários slides adicione --slide N (ou #hash, ou um seletor CSS). Use --no-script para marca temporizada ou quadros de fase quando o script da própria página alterna a classe do portão, nunca para rest: em decks frontend-slides .visible é tanto o portão quanto a classe que mostra o slide, a renderização de repouso o remove, e o slide permanece apenas porque o script do deck também define .active; sem o script o quadro de repouso fica em branco. Abra cada PNG com sua ferramenta de visualização de imagens. Corrija cortes, sobreposições, texto ilegível, painéis vazios. Itere pelo menos uma vez.
  3. O quadro de repouso deve ser legível como um quadro completo (exportação PDF mostra apenas isso).
  4. python3 <skill-dir>/scripts/verify_facts.py anim/<nome>/<nome>.html --source anim/outline.json --slide <N> (ou --source doc.md) deve passar: cada número no fragmento vem da fonte ou é marcado como ilustrativo; leia cada AVISO e substitua palavras não rastreáveis pelas palavras da própria fonte ou remova-as. Regras em references/accuracy.md. Uma figura não está pronta até que isso passe. Nunca confie em --virtual-time-budget, e nunca confie em ler a fonte em vez do PNG.

5. Integração

python3 <skill-dir>/scripts/integrate_fragment.py deck.html anim/<nome>/<nome>.html --name <nome> --anchor '<string única no slide>' [--replace-until '<string>'] [--gate 'section.present'] [--control once|step] --backup eleva o estilo para o head, insere o fragmento entre <!-- anim:<nome>:start --> e <!-- anim:<nome>:end --> marcadores (o estilo entre marcadores anim-style; reexecutar substitui ambas as cópias), reescreve o portão para o deck hospedeiro e prefixa qualquer classe que tenha escapado. Para páginas simples, copie <skill-dir>/scripts/snippets/observer.html para a página. --control define o controle do deck no wrapper; --control step também coloca scripts/snippets/step-host.html (um pequeno script simples, sem bibliotecas) no head uma vez e configura seu portão a partir de --gate. O controle é uma chave em todo o deck na integração: execute novamente com o outro valor para mudá-lo, os fragmentos permanecem como estão. A âncora e a string-until são mantidas; o que está entre elas é substituído. O portão é o marcador de "slide atual" do hospedeiro: section.present para reveal.js, .visible para páginas simples (scripts/snippets/observer.html) e para decks de md_to_deck.py. Em decks md_to_deck.py, e em decks de skill de deck com os marcadores de slot da etapa 0, o fragmento substitui o corpo: --anchor '<!-- sN-body -->' --replace-until '<!-- /sN-body -->'. Verifique se os cabeçalhos e o texto do corpo do slide aparecem sem o script do deck e na impressão. As animações de entrada dos skills de deck geralmente chaveiam suas revelações apenas na classe de slide atual (frontend-slides mostra elementos .reveal apenas sob .slide.visible), então renderizações de repouso e PDF mostram slides vazios; chaveie essas revelações também na classe ativa do deck (.slide.active) e adicione uma regra de impressão que as mostre. (O nome da classe .reveal também corresponde à detecção do reveal.js nos seletores de slide do host_theme.py; inofensivo até agora, mas verifique quais slides ele encontrou.) Ele também adiciona uma guarda de impressão para que a exportação PDF (o ?print-pdf do reveal marca cada slide presente) mostre quadros de repouso. Mantenha o deck de trabalho enxuto: fragmentos são texto SVG pequeno e entram por marcadores, mas não incorpore fontes, imagens, bibliotecas ou folhas de estilo enquanto trabalha, e nunca leia o deck inteiro no contexto; leia fatias em torno da âncora (grep -n, sed -n) e deixe os scripts editá-lo. Em seguida, abra o deck em um navegador real e veja…

…[truncado para tradução]

Habilidades Relacionadas