Communitygithub.com

og-image-animated

Transforme le visuel Open Graph statique d'un projet en une courte animation web — la marque et le titre tombent du haut, puis l'application réelle s'élève depuis le bas pour se stabiliser sur la carte finale. Génère une route jouable dans la stack du projet et enregistre le résultat image par image en MP4, GIF (plus le dernier cadre en PNG). À utiliser lorsqu'on vous demande une image OG animée, une carte de partage animée, une vidéo/GIF de preview sociale ou une animation d'introduction du titre et du produit.

Qu'est-ce que og-image-animated ?

Cette compétence transforme la carte de partage Open Graph statique d'un projet en une courte animation web (environ 2 à 2,5 secondes) qui révèle élégamment la marque, le titre et l'application. Elle s'appuie sur l'infrastructure existante du projet : elle ajoute simplement une propriété `animated` au composant de carte OG existant, évitant ainsi toute dérive entre la version statique et la version animée. L'animation utilise exclusivement des animations CSS (keyframes + `animation` avec remplissage `both`) pour garantir une capture déterministe par le séquenceur, qui utilise l'API Web Animations. La compétence génère ensuite une route web dédiée (par exemple, `/og/<page>-animated`) et un script d'enregistrement basé sur Playwright qui capture l'animation image par image pour produire des fichiers MP4, GIF et le dernier cadre en PNG. Les plateformes supportées incluent tout framework web moderne (Next.js, Remix, etc.) disposant d'un composant de carte OG statique. L'utilisation est simple : découvrez le composant existant, ajoutez le mode animé via une propriété, créez la route de lecture, puis exécutez le script d'enregistrement fourni. Les cas d'usage typiques incluent les animations de partage social, les vidéos d'introduction pour les pages de lancement, ou les GIFs pour les README et les posts marketing. Attention : l'image `og:image` doit rester le PNG statique car les plateformes sociales ne lisent pas les images OG animées ; les fichiers MP4/GIF sont destinés aux publications, README, pages de lancement ou à l'utilisation avec `og:video`.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Image OG animée

Chaque fichier utilisé par cette compétence est livré dans son propre dossier, à côté de ce SKILL.md, et les chemins ici sont relatifs à ce dossier. Elle n'a besoin de rien provenant d'autres compétences ou d'autres dossiers, ne les cherchez donc pas. Sauf si l'utilisateur nomme un autre emplacement, enregistrez tout ce qu'elle produit dans out/og-image-animated/ sous le projet actuel.

La carte de partage statique animée en une courte et calme révélation :

  1. Carte vide : arrière-plan et lueur douce uniquement.
  2. La marque et le titre tombent du haut (fondu + glissement vers le bas).
  3. La fenêtre de l'application s'élève depuis le bas (fondu + glissement vers le haut) et se stabilise exactement là où elle se trouve sur la carte statique.
  4. Pause sur l'image finale, qui doit correspondre à l'image OG statique.

Exemples : references/pulse.gif (le résultat) et references/pulse-frames.png (quatre images : début, titre entré, application en ascension, finale).

Règles

  • Partez de la carte statique. Si le projet n'a pas encore de composant de carte OG, construisez-le d'abord en suivant references/static-card.md (produit réel, message du site actuel, données réalistes). L'animation n'ajoute que du mouvement : même balisage, même disposition finale, aucun nouveau contenu.
  • Un composant, deux modes. Ajoutez une propriété animated au composant de carte existant plutôt que de le copier, afin que le PNG statique et l'animation ne dérivent jamais l'un de l'autre. Sans la propriété, rien n'est animé.
  • Mouvement, pas d'effets. Uniquement opacity + transform: translateY, une seule courbe d'assouplissement partagée (cubic-bezier(0.16, 1, 0.3, 1)). Pas de rebond, de flou, de pop d'échelle, de texte machine à écrire ou d'éléments rotatifs.
  • Court. Chronologie totale d'environ 2 à 2,5 s, puis une pause d'environ 1,5 s. Le titre doit être entièrement lisible vers 1,3 s.
  • Animations CSS uniquement (keyframes + animation avec remplissage both), pas de tweens ni de minuteurs pilotés par JS à l'intérieur de la carte. Le séquenceur recherche les animations CSS via l'API Web Animations ; le mouvement piloté par JS ne serait pas capturé de manière déterministe.

Chronologie

ÉlémentKeyframesDuréeDélai
Marquede opacity: 0; translateY(-48px)900ms100ms
Titrede opacity: 0; translateY(-48px)1000ms250ms
Fenêtre de l'applicationde opacity: 0; translateY(320px)1300ms700ms

Ajustez les distances à la carte : l'application doit commencer principalement en dessous du bord inférieur (environ la moitié de la hauteur de la carte) et le titre environ à sa propre hauteur au-dessus de son emplacement de repos. S'il y a un panneau flottant, laissez-le arriver en dernier (+200ms après le début de la fenêtre).

Étapes

1. Découvrir

  • Trouvez le composant de carte statique et sa route de rendu (par ex. og-image.tsx, /og/<page>), et le PNG actuel dans public/.
  • Notez les wrappers de la marque, du titre et de la fenêtre de l'application. Si la fenêtre utilise zoom pour s'adapter, animez un wrapper interne, pas l'élément zoomé, afin que les décalages restent corrects.

2. Ajouter le mode animé

Dans le composant de carte :

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>} …
// marque :  style={animated ? enter('og-drop', 900, 100) : undefined}
// titre :  style={animated ? enter('og-drop', 1000, 250) : undefined}
// fenêtre : <div style={{ zoom }}><div className="h-full" style={animated ? enter('og-rise', 1300, 700) : undefined}>…

Placez les keyframes dans le composant (une balise <style>) ou le CSS global du projet ; avec Tailwind v4, les keyframes dans @theme ne sont émises que lorsqu'un jeton --animate-* correspondant est utilisé, donc préférez le composant ou le CSS simple.

3. Ajouter une route web qui la joue

Une route sœur de la route statique, par ex. /og/<page>-animated (noindex, sans chrome d'application) :

  • Affiche <Card animated /> à l'intérieur du cadre 1200×630.
  • Rejoue pour prévisualisation : remonte la carte avec une key changeante toutes les ~4,5s.
  • ?loop=0 joue une fois (le séquenceur utilise ceci). Normalisez d'abord le paramètre de recherche en chaîne : les routeurs comme TanStack analysent ?loop=0 comme le nombre 0, et une vérification manquée continue de remonter la carte pendant l'enregistrement.

Ouvrez-la dans le navigateur et regardez-la plusieurs fois. Vérifiez l'ordre d'entrée, qu'aucun flash n'apparaît avant le début de l'animation, et que l'état stabilisé correspond à la carte statique.

4. Enregistrer MP4 + GIF

Avec le serveur de développement en cours d'exécution :

node <ce dossier de compétence>/scripts/record.mjs \
  --url "http://localhost:<port>/og/<page>-animated?loop=0" \
  --out out/og-image-animated/og-<page>

Écrit og-<page>.mp4 (2400×1260, H.264, 30ips), og-<page>.gif (1200px de large, palette optimisée, boucle) et og-<page>.png (dernier cadre). Comment ça fonctionne : il met en pause chaque animation sur la page, lit la longueur de la chronologie, puis parcourt toutes les animations image par image et capture une zone fixe de [data-og-frame]. Le résultat est identique à chaque exécution, sans images perdues. Options : --fps, --hold, --lead, --scale, --formats mp4,gif,png, --selector.

Nécessite ffmpeg dans le PATH. Playwright s'installe dans le dossier scripts/ de cette compétence lors de la première exécution, avec son Chromium si aucun n'est trouvé.

Pièges :

  • La page ne doit pas forcer une réduction de mouvement. De nombreuses feuilles de style globales raccourcissent les animations sous prefers-reduced-motion ; le séquenceur ne l'émule pas, et il échoue bruyamment s'il ne trouve aucune animation.
  • Les captures d'écran d'éléments attendent la "stabilité", qui ne survient jamais au milieu d'une animation. C'est pourquoi le script capture une région de la page.
  • Assurez-vous que le port dessert bien cette application (un autre serveur local peut répondre sur localhost).

5. Réviser

Extrayez une planche contact et examinez-la :

ffmpeg -y -loglevel error -i og-<page>.mp4 \
  -vf "select='eq(n\,8)+eq(n\,22)+eq(n\,40)+eq(n\,<dernier>)',scale=1000:-1,tile=2x2" -frames:v 1 sheet.png
  • Image ~0,25s : carte vide (lueur uniquement), pas de saut de disposition.
  • ~0,7s : titre entré ou presque, application pas encore visible.
  • ~1,3s : application en pleine ascension, titre entièrement lisible.
  • Dernière image : identique en contenu au PNG statique.

Gardez le GIF raisonnablement petit (moins d'environ 3 Mo). S'il est plus gros, réduisez --fps (20–24) ou raccourcissez --hold.

Résultat

Informez l'utilisateur :

  • de l'URL de la route de prévisualisation (boucle) et des fichiers écrits (MP4, GIF, PNG)
  • de la commande de régénération
  • de la chronologie (ce qui bouge, durées)
  • que og:image doit rester le PNG statique : les plateformes sociales ne lisent pas les images OG animées. Utilisez le MP4/GIF pour les publications, README, pages de lancement ou og:video là où c'est pris en charge.

Individual skills in this repo

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

Skills associés