Communitygithub.com

KehanLiu/anim-slides

Convierte diapositivas aburridas en atractivas presentaciones HTML con animaciones. Crea ilustraciones SVG animadas autónomas (con keyframes CSS y modo paso opcional activado por clic) que reemplazan bloques de texto y capturas de pantalla en cualquier presentación HTML, generándolas directamente a partir de documentación de procesos, dependencias, cronogramas o arquitecturas.

¿Qué es anim-slides?

Este skill de agente de IA, llamado 'anim-slides', está diseñado para transformar diapositivas estáticas y aburridas (de presentaciones PPT, PPTX, HTML o incluso documentos Markdown) en diapositivas HTML ricas en animaciones. Su función principal es generar fragmentos SVG animados y autónomos que ilustren procesos, flujos de trabajo, dependencias, cronogramas, arquitecturas o comparaciones. Cada fragmento es un único archivo HTML que contiene un `<style>` y un `<svg>`, sin scripts externos ni dependencias, y se integra perfectamente en cualquier presentación HTML (como reveal.js, impress.js, Slidev, o frontend-slides). El skill sigue un flujo de trabajo estructurado que incluye la ingesta de la presentación, la extracción de diapositivas, la definición de una especificación YAML para la animación, la medición del espacio disponible en la diapositiva, la construcción del fragmento animado, la verificación visual, y la integración final en la presentación. Es útil para desarrolladores y creadores de contenido que desean mejorar visualmente sus diapositivas, haciendo que conceptos complejos sean más atractivos y comprensibles mediante animaciones claras y paso a paso.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace anim-slides?

Ilustraciones SVG animadas para presentaciones de diapositivas, a partir de diapositivas existentes o de documentación. La salida siempre es un fragmento: un archivo HTML con un <style> y un <svg>, sin scripts, sin archivos externos, tematizado mediante variables CSS, que se inserta en cualquier presentación. references/fragment-contract.md es el contrato. Léelo antes de construir cualquier cosa.

Cuándo usarlo

  • Una diapositiva es una fila de tarjetas de texto, una lista con viñetas o una captura de pantalla, y el contenido es un proceso, un flujo, una estructura de dependencias, un cronograma, una comparación, una arquitectura o una serie temporal.
  • Un documento (Markdown, exportación de Confluence, README, bloque Mermaid) describe un proceso o dependencias y el usuario quiere mostrarlo como una animación en una diapositiva o página.
  • El anfitrión es una presentación HTML (frontend-slides, reveal.js, impress.js, Slidev, hecho a mano) o una página web simple. Un archivo .pptx o fuente Markdown se convierte primero en una presentación HTML diseñada por un skill de presentación (paso 0); este skill luego agrega las ilustraciones.

Flujo de trabajo

<skill-dir> a continuación es la carpeta que contiene este SKILL.md (Claude Code lo expone como $CLAUDE_SKILL_DIR; en otros entornos usa la ruta desde la que cargaste este archivo). Los scripts necesitan Python 3.9+ y, para renderizar, un binario de Chrome o Chromium. anim/<name>/ es una carpeta junto a la presentación del usuario.

0. Ingreso

Primero obtén una presentación HTML. anim-slides agrega figuras a una presentación HTML; no diseña una.

  • La fuente ya es una presentación HTML (reveal.js, impress.js, cualquier presentación con <section> o .slide): continúa.
  • La fuente es un archivo .pptx, Markdown, remark, un documento o cualquier otra cosa que no sea una presentación HTML: un skill de presentación construye la presentación HTML primero, no anim-slides. En orden de preferencia: (a) el skill de presentación del propio usuario o de la organización, si está instalado; (b) frontend-slides, cuando está instalado (convierte pptx y Markdown en una presentación HTML diseñada; cuando ofrece vistas previas estéticas, elige la más cercana a la marca de la presentación original a menos que el usuario quiera un nuevo aspecto); (c) solo cuando no hay ningún skill de presentación instalado, scripts/md_to_deck.py como respaldo (consulta la viñeta de respaldo a continuación), e informa al usuario en una oración que su salida es un anfitrión simple, no un diseño, y se leerá como un documento hasta que un skill de presentación o un diseñador le dé estilo. En los casos (a) y (b) el archivo .pptx original sigue siendo la fuente para extract_slides.py y render_deck.py (gráficos, figuras, notas), pero la integración apunta a la presentación que produjo el skill, y la apariencia de coincidencia proviene de la paleta de esa presentación a través de host_theme.py. Pídele al skill de presentación (o hazlo justo después) que envuelva el cuerpo de cada diapositiva candidata en un slot de tamaño fijo <div id="sN-slot"> entre <!-- sN-body --> y <!-- /sN-body --> (el id y los nombres de marcador que usa md_to_deck.py, aunque allí el slot es un hermano vacío del cuerpo): measure_slot.py --selector '#sN-slot' es entonces exacto, e integrate_fragment.py --anchor/--replace-until apunta a los marcadores. El enlace de fuente de un skill de presentación (Google Fonts, Fontshare) es la carga de la presentación, no una agregada por anim-slides; mantenlo, e incorpóralo en la entrega con bundle_deck.py --fetch.

Luego decide qué punto de entrada aplica:

  • Presentación existente: ejecuta python3 <skill-dir>/scripts/extract_slides.py deck.pptx|deck.html|doc.md -o anim/outline.json y python3 <skill-dir>/scripts/render_deck.py deck -o anim/render, luego mira las hojas de contactos sheet-NN.png (12 diapositivas numeradas cada una), no página por página (cuando el recuento de imágenes de una diapositiva en outline.json difiere de las imágenes en su renderizado, mira las imágenes del diseño de la diapositiva: una foto de portada en el diseño es fácil de pasar por alto); luego triaje con references/input-stage.md y escribe la tabla en anim/triage.md: cada diapositiva, una decisión y una razón, sin saltos silenciosos (de 3 a 8 ilustraciones por cada 30 diapositivas es normal; en una presentación corta, cada diapositiva de proceso, estructura, cronograma, comparación o datos recibe una). Luego define el aspecto una vez para toda la presentación: coincidir (los fragmentos toman la paleta y las fuentes del anfitrión, el valor predeterminado para presentaciones corporativas o de marca) o minimalista (los fragmentos mantienen la paleta minimalista sobre un fondo oscuro, para charlas y presentaciones). python3 <skill-dir>/scripts/host_theme.py deck.html --mode match -o anim/host-theme.css deriva el código de coincidencia del CSS de la presentación (--mode lean escribe el código minimalista); compara el bloque derivado una vez con las variables propias de la presentación (un color de texto apagado, un fondo secundario) y corrige manualmente donde la derivación eligió una combinación calculada; renderiza el primer fragmento de ambas maneras (render-phases.sh --theme anim/host-theme.css ...) y muestra las dos imágenes fijas antes de construir el resto, a menos que el usuario ya haya nombrado un aspecto. Solo los colores y las fuentes cambian entre los dos: las reglas de forma de references/style.md se mantienen en ambos. El control es once para toda la presentación a menos que el usuario solicite un clic secuencial: la figura de cada diapositiva realiza un pase tranquilo cuando la diapositiva aparece, luego descansa. No recomiendes step por tu cuenta. Menciónalo en una sola línea solo cuando outline.json informe builds por encima de 0 (la fuente ya se construye mediante clics: fragmentos de reveal.js, animaciones de clic de PowerPoint, subpasos de impress.js, los propios pasos de construcción de la presentación): "tu presentación se construye mediante clics; las figuras pueden hacer lo mismo (step), dilo si lo quieres". Bajo step, la entrada se dibuja y cada clic aterriza la siguiente fase; las fases son las fases narradas del resumen (de 3 a 5 por diapositiva), el archivo del fragmento es el mismo, y el clic se basa en la navegación propia de la presentación. Step solo escucha las teclas, por lo que una presentación step se presenta con el teclado o un clic (una presentación que también navega por rueda o deslizamiento, como lo hace frontend-slides, se salta las fases en un desplazamiento). Escribe Aspecto y Control en el encabezado de anim/triage.md.
  • Respaldo, sin skill de presentación instalado (Markdown, remark, o un pptx extraído a Markdown): python3 <skill-dir>/scripts/md_to_deck.py deck.md -o deck.html crea un anfitrión simple y autónomo para integrar (un <section> por diapositiva, compuerta .visible, diseño de impresión, marcadores <!-- sN-body --> alrededor del cuerpo de cada diapositiva). No es una presentación diseñada: díselo al usuario en una oración. Obtén primero las imágenes a las que hace referencia el Markdown (rutas relativas) en la misma carpeta, o la presentación mostrará marcadores de posición; luego extrae de la fuente original (el .pptx si lo había) o del Markdown.
  • Documentación: lee la fuente, elige el arquetipo con la tabla en references/archetypes.md, extrae una especificación (paso 1).
  • Solicitud de una sola diapositiva: ve directamente al paso 1 para esa diapositiva. Pregunta al usuario solo cuando la fuente sea ambigua sobre el orden, la dirección o la agrupación. De lo contrario, indica la suposición en el resumen y continúa.

1. Especificación

Escribe anim/<name>/spec.yaml siguiendo references/spec-format.md: nombre, arquetipo, nodos, aristas, grupos, fases con marcas de segundos, ciclo (la duración del pase), control (la elección de la presentación del ingreso: once, un pase tranquilo de 4 a 10 s cuando la diapositiva se vuelve actual, terminando en el fotograma de reposo; step, el mismo pase cortado en las marcas de fase para que cada clic aterrice la siguiente fase; loop solo cuando el usuario solicita un bucle continuo). El archivo del fragmento es el mismo bajo once y step; las marcas de fase se convierten en data-anim-phases. Reutiliza las palabras propias de la fuente como etiquetas. Mantén una especificación por debajo de unos 12 nodos; divídela en caso contrario.

1b. Verificar el repositorio

Lee <skill-dir>/pool/index.yaml, luego $ANIM_POOL/index.yaml (o lista $ANIM_POOL/*/) si esa variable está configurada, y busca una entrada con el mismo arquetipo y una historia o etiquetas similares.

  • Coincidencia cercana: copia la carpeta a anim/<name>/, renombra el fragmento y cada prefijo a <name>, luego adapta las etiquetas, los datos, el tiempo y el viewBox a la especificación en el paso 3 en lugar de andamiar. Su spec.yaml, si está presente, es un punto de partida para el tuyo.
  • Mismo arquetipo solamente: andamia como de costumbre, y abre el fragmento del repositorio como el estándar de calidad para densidad, movimiento y fotograma de reposo.
  • Nada encaja: construye a partir de la especificación; la entrada del repositorio más cercana aún vale la pena echarle un vistazo. Nunca copies un fragmento del repositorio sin cambios en una presentación: su historia es un ejemplo, no la del usuario.

2. Slot y resumen

Mide el cuadro libre en la diapositiva: python3 <skill-dir>/scripts/measure_slot.py deck.html --slide N [--selector SEL] [--ignore .body] imprime el cuadro en píxeles del escenario, un viewBox coincidente y las banderas del verificador (references/layouts.md explica la forma manual). En un diseño con posicionamiento absoluto, medir sin --selector devuelve basura; mide el div del slot (--selector '#sN-slot', paso 0). Elige un viewBox con la misma relación de aspecto, y completa anim/<name>/brief.md desde references/brief-template.md. El resumen fija el viewBox y el tamaño renderizado, la composición, las fases, el fotograma de reposo, los tokens del tema y el tamaño mínimo del texto, y nombra qué en la diapositiva reemplaza el fragmento (las píldoras, el diagrama de caja, la columna de viñetas). La calidad del fragmento sigue la calidad del resumen.

3. Construcción

python3 <skill-dir>/scripts/scaffold_from_spec.py anim/<name>/spec.yaml -o anim/<name>/<name>.html --rendered-width <px> valida la especificación y escribe un esqueleto compatible con el contrato (diseño, fases, paquetes, notas, fotograma de reposo; tamaños de fuente elevados al mínimo en el ancho renderizado), luego ejecuta el verificador en él. El comentario en la parte superior de la salida enumera qué refinar a mano. Refínalo en la ilustración que describe el resumen, usando references/archetypes.md para la composición y el movimiento, references/motion-rules.md para el tiempo y la suavización, y references/style.md para el aspecto (minimalista: anillos y líneas finas, sin cajas, un acento brillante, subetiquetas mono, leyendas simples). Para varias ilustraciones, construye un fragmento a la vez a partir de los resúmenes compartidos, o un subagente paralelo por fragmento si el entorno los tiene; la integración siempre permanece en el hilo principal.

4. Verificar visualmente

  1. python3 <skill-dir>/scripts/check_fragment.py anim/<name>/<name>.html --name <name> --rendered-width <px> --stage-width <ancho del escenario de la presentación> debe pasar (prefijos, tokens, compuertas, tamaño del texto, contenido prohibido). --stage-width establece el mínimo de texto (18 px a 1920, 12 px a 1280); outline.json informa el escenario.
  2. <skill-dir>/scripts/render-phases.sh anim/<name> <W> <H> 1.5 4 7 10 rest renderiza PNG de fase y una hoja de contactos con el método de pausa más retardo negativo, en una carpeta temporal que imprime (pasa --out DIR para elegir). Después de la integración, render-phases.sh --page deck.html 1920 1080 rest verifica el fotograma de reposo de la página anfitriona; en una página de varias diapositivas, agrega --slide N (o #hash, o un selector CSS). Usa --no-script para marcas de tiempo o fotogramas de fase cuando el script propio de la página alterna la clase de compuerta, nunca para rest: en presentaciones de frontend-slides, .visible es tanto la compuerta como la clase que muestra la diapositiva, el renderizado de reposo la elimina, y la diapositiva permanece solo porque el script de la presentación también establece .active; sin el script, el fotograma de reposo está en blanco. Abre cada PNG con tu herramienta de visualización de imágenes. Corrige recortes, superposiciones, texto ilegible, paneles vacíos. Itera al menos una vez.
  3. El fotograma de reposo debe leerse como una imagen fija completa (la exportación a PDF muestra solo eso).
  4. python3 <skill-dir>/scripts/verify_facts.py anim/<name>/<name>.html --source anim/outline.json --slide <N> (o --source doc.md) debe pasar: cada número en el fragmento proviene de la fuente o está marcado como ilustrativo; lee cada ADVERTENCIA y reemplaza el texto no rastreable con las palabras propias de la fuente o elimínalo. Reglas en references/accuracy.md. Una figura no está terminada hasta que esto pase. Nunca confíes en --virtual-time-budget, y nunca confíes en leer la fuente en lugar del PNG.

5. Integrar

python3 <skill-dir>/scripts/integrate_fragment.py deck.html anim/<name>/<name>.html --name <name> --anchor '<cadena única en la diapositiva>' [--replace-until '<cadena>'] [--gate 'section.present'] [--control once|step] --backup coloca el estilo en el encabezado, inserta el fragmento entre los marcadores <!-- anim:<name>:start --> y <!-- anim:<name>:end --> (el estilo entre los marcadores anim-style; volver a ejecutar reemplaza ambas copias), reescribe la compuerta para la presentación anfitriona y prefija cualquier clase que se haya escapado. Para páginas simples, copia <skill-dir>/scripts/snippets/observer.html en la página. --control establece el control de la presentación en el envoltorio; --control step también coloca scripts/snippets/step-host.html (un script simple pequeño, sin biblioteca) en el encabezado una vez y establece su compuerta desde --gate. El control es un interruptor para toda la presentación en la integración: vuelve a ejecutar con el otro valor para cambiarlo, los fragmentos permanecen como están. El ancla y la cadena hasta-hasta se mantienen; lo que está entre ellos se reemplaza. La compuerta es el marcador de "diapositiva actual" del anfitrión: section.present para reveal.js, .visible para páginas simples (scripts/snippets/observer.html) y para presentaciones de md_to_deck.py. En presentaciones de md_to_deck.py, y en presentaciones de skill de presentación con los marcadores de slot del paso 0, el fragmento reemplaza el cuerpo: --anchor '<!-- sN-body -->' --replace-until '<!-- /sN-body -->'. Verifica que los encabezados y el texto del cuerpo de la diapositiva se muestren sin el script de la presentación y en la impresión. Las animaciones de entrada de los skills de presentación a menudo basan sus revelaciones solo en la clase de diapositiva actual (frontend-slides muestra elementos .reveal solo bajo .slide.visible), por lo que los renderizados de reposo y PDF muestran diapositivas vacías; clave esas revelaciones también en la clase activa de la presentación (.slide.active) y agrega una regla de impresión que las muestre. (El nombre de clase .reveal también coincide con la detección de reveal.js en los selectores de diapositivas de host_theme.py; inofensivo hasta ahora, pero verifica qué diapositivas encontró). También agrega un protector de impresión para que la exportación a PDF (la marca ?print-pdf de reveal.js hace que cada diapositiva esté presente) muestre fotogramas de reposo. Mantén la presentación de trabajo ligera: los fragmentos son texto SVG pequeño y se insertan mediante marcadores, pero no incorpores fuentes, imágenes, bibliotecas u hojas de estilo mientras trabajas, y nunca leas toda la presentación en el contexto; lee fragmentos alrededor del ancla (grep -n, sed -n) y deja que los scripts lo editen. Luego abre la presentación en un navegador real y observa…

Skills relacionados