Communitygithub.com

og-image-animated

Convierte la tarjeta Open Graph de un proyecto en una animación web de unos segundos: la marca y el título caen desde arriba, luego la aplicación real asciende desde abajo hasta asentarse en la tarjeta final. Crea una ruta web reproducible en el stack del proyecto y la graba fotograma a fotograma en MP4 y GIF (además del fotograma final como PNG). Úsalo cuando te pidan una imagen OG animada, tarjeta de compartir animada, video/GIF de previsualización social o una animación de introducción del título y el producto.

¿Qué es og-image-animated?

Esta habilidad para agentes de IA (compatible con Claude Code, Cursor y Codex) permite generar automáticamente una animación corta y elegante a partir de la tarjeta Open Graph estática de cualquier proyecto web. Su propósito es crear un recurso visual llamativo para redes sociales, páginas de lanzamiento o documentación, sin necesidad de edición manual de video. El flujo de trabajo consiste en tres fases: (1) detectar el componente de tarjeta OG existente, (2) añadir un modo animado mediante animaciones CSS puras (opacidad y transformación) y una nueva ruta web con bucle de previsualización, y (3) grabar la animación fotograma a fotograma usando un script de Node.js con Playwright y ffmpeg, generando MP4, GIF y PNG. La animación sigue una línea de tiempo fija de ~2‑2.5 segundos más una pausa de ~1.5s, con la marca y título cayendo desde arriba y la ventana de la aplicación ascendiendo desde abajo. El resultado es determinista, no requiere librerías de animación JavaScript y produce archivos ligeros (el GIF se mantiene por debajo de ~3MB). Los desarrolladores solo necesitan ejecutar el comando de grabación con el servidor de desarrollo activo.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/paralect/saas-skills/tree/HEAD/skills/og-image-animated

Preguntar en tu IA favorita

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

Documentación

Imagen OG animada

Todos los archivos que usa esta habilidad se entregan en su propia carpeta, junto a este SKILL.md, y las rutas aquí son relativas a esa carpeta. No necesita nada de otras habilidades ni de otras carpetas, así que no vayas a buscarlas. A menos que el usuario indique otro lugar, guarda todo lo que genere en out/og-image-animated/ dentro del proyecto actual.

La tarjeta de compartir estática animada como una revelación breve y tranquila:

  1. Tarjeta vacía: solo fondo y brillo suave.
  2. La marca y el título caen desde arriba (fundido + deslizamiento hacia abajo).
  3. La ventana de la aplicación asciende desde abajo (fundido + deslizamiento hacia arriba) y se asienta exactamente donde estaba en la tarjeta estática.
  4. Pausa en el fotograma final, que debe coincidir con la imagen OG estática.

Ejemplos: references/pulse.gif (el resultado) y references/pulse-frames.png (cuatro fotogramas: inicio, título entrando, aplicación ascendiendo, final).

Reglas

  • Partir de la tarjeta estática. Si el proyecto aún no tiene un componente de tarjeta OG, constrúyelo primero siguiendo references/static-card.md (producto real, mensajes del sitio actual, datos realistas). La animación solo añade movimiento: mismo marcado, mismo diseño final, sin contenido nuevo.
  • Un solo componente, dos modos. Añade una propiedad animated al componente de tarjeta existente en lugar de copiarlo, para que la PNG estática y la animación nunca se desvíen. Sin la propiedad, no se anima nada.
  • Movimiento, no efectos. Solo opacity + transform: translateY, una única curva de aceleración compartida (cubic-bezier(0.16, 1, 0.3, 1)). Sin rebotes, desenfoques, escalados, texto de máquina de escribir ni elementos giratorios.
  • Corta. Toda la línea de tiempo dura unos 2–2.5 s, luego una pausa de ~1.5 s. El título debe ser completamente legible hacia ~1.3 s.
  • Solo animaciones CSS (keyframes + animation con relleno both), sin interpolaciones ni temporizadores JavaScript dentro de la tarjeta. El grabador busca animaciones CSS a través de la Web Animations API; el movimiento controlado por JS no se capturaría de manera determinista.

Línea de tiempo

ElementoKeyframesDuraciónRetardo
Marcadesde opacity: 0; translateY(-48px)900 ms100 ms
Títulodesde opacity: 0; translateY(-48px)1000 ms250 ms
Ventana de appdesde opacity: 0; translateY(320px)1300 ms700 ms

Ajusta las distancias a la tarjeta: la aplicación debe comenzar mayormente por debajo del borde inferior (aproximadamente la mitad de la altura de la tarjeta) y el título aproximadamente a su propia altura por encima de su lugar de descanso. Si hay un panel flotante, que llegue al final (+200 ms después de que la ventana comience).

Pasos

1. Descubrir

  • Encuentra el componente de tarjeta estática y su ruta de renderizado (ej. og-image.tsx, /og/<pagina>), y la PNG actual en public/.
  • Anota los envoltorios de la marca, el título y la ventana de la aplicación. Si la ventana usa zoom para ajustarse, anima un envoltorio interno, no el elemento con zoom, para que los desplazamientos sigan siendo correctos.

2. Añadir el modo animado

En el componente de tarjeta:

const KEYFRAMES = `
@keyframes og-drop { from { opacity: 0; transform: translateY(-48px); } to { opacity: 1; transform: none; } }
@keyframes og-rise { from { opacity: 0; transform: translateY(320px); } to { opacity: 1; transform: none; } }
`;
const EASE = 'cubic-bezier(0.16, 1, 0.3, 1)';
const enter = (name: string, ms: number, delay: number) => ({ animation: `${name} ${ms}ms ${EASE} ${delay}ms both` });

// <div data-og-frame …>{animated && <style>{KEYFRAMES}</style>} …
// marca:  style={animated ? enter('og-drop', 900, 100) : undefined}
// título:  style={animated ? enter('og-drop', 1000, 250) : undefined}
// ventana: <div style={{ zoom }}><div className="h-full" style={animated ? enter('og-rise', 1300, 700) : undefined}>…

Pon los keyframes en el componente (una etiqueta <style>) o en el CSS global del proyecto; con Tailwind v4, los keyframes dentro de @theme solo se emiten cuando se usa un token --animate-* correspondiente, así que prefiere el componente o CSS plano.

3. Añadir una ruta web que lo reproduzca

Una ruta hermana de la estática, ej. /og/<pagina>-animated (noindex, sin interfaz de la aplicación):

  • Renderiza <Card animated /> dentro del marco 1200×630.
  • Se reproduce en bucle para previsualización: vuelve a montar la tarjeta con una key cambiante cada ~4.5 s.
  • ?loop=0 reproduce una sola vez (el grabador usa esto). Normaliza el parámetro de búsqueda a cadena primero: enrutadores como TanStack parsean ?loop=0 como el número 0, y una verificación omitida seguiría remontando la tarjeta durante la grabación.

Ábrela en el navegador y mírala varias veces. Verifica el orden de entrada, que nada parpadee antes de que comience la animación y que el estado final coincida con la tarjeta estática.

4. Grabar MP4 + GIF

Con el servidor de desarrollo en ejecución:

node <carpeta de esta habilidad>/scripts/record.mjs \
  --url "http://localhost:<puerto>/og/<pagina>-animated?loop=0" \
  --out out/og-image-animated/og-<pagina>

Escribe og-<pagina>.mp4 (2400×1260, H.264, 30 fps), og-<pagina>.gif (1200 px de ancho, optimizado por paleta, en bucle) y og-<pagina>.png (fotograma final). Cómo funciona: pausa cada animación en la página, lee la duración de la línea de tiempo, luego recorre todas las animaciones fotograma a fotograma y captura una región fija de [data-og-frame]. El resultado es idéntico en cada ejecución, sin fotogramas perdidos. Opciones: --fps, --hold, --lead, --scale, --formats mp4,gif,png, --selector.

Necesita ffmpeg en PATH. Playwright se instala en la carpeta scripts/ de esta habilidad en la primera ejecución, junto con su Chromium si no se encuentra ninguno.

Trampas:

  • La página no debe forzar movimiento reducido. Muchas hojas de estilo globales acortan las animaciones bajo prefers-reduced-motion; el grabador no lo emula y falla ruidosamente si no encuentra animaciones.
  • Las capturas de pantalla de elementos esperan "estabilidad", que nunca llega durante una animación. Por eso el script recorta una región de la página.
  • Asegúrate de que el puerto realmente sirva esta aplicación (otro servidor local podría responder en localhost).

5. Revisar

Extrae una hoja de contactos y mírala:

ffmpeg -y -loglevel error -i og-<pagina>.mp4 \
  -vf "select='eq(n\,8)+eq(n\,22)+eq(n\,40)+eq(n\,<último>)',scale=1000:-1,tile=2x2" -frames:v 1 sheet.png
  • Fotograma ~0.25 s: tarjeta vacía (solo brillo), sin salto de diseño.
  • ~0.7 s: título entrando o casi, aplicación aún no visible.
  • ~1.3 s: aplicación a media altura, título completamente legible.
  • Último fotograma: idéntico en contenido a la PNG estática.

Mantén el GIF razonablemente pequeño (por debajo de ~3 MB). Si es más grande, baja --fps (20–24) o acorta --hold.

Salida

Informa al usuario:

  • la URL de la ruta de previsualización (en bucle) y los archivos escritos (MP4, GIF, PNG)
  • el comando de regeneración
  • la línea de tiempo (qué se mueve, duraciones)
  • que og:image debe seguir siendo la PNG estática: las plataformas sociales no reproducen imágenes OG animadas. Usa el MP4/GIF para publicaciones, README, páginas de lanzamiento o og:video donde sea compatible.

Individual skills in this repo

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

Skills relacionados