graphic-gif
Génère un GIF animé en boucle à partir d'animations CSS ou d'une API IA image-vers-vidéo. Fichier de sortie : animation.gif.
Contrairement aux autres skills graphic- qui produisent un PNG ou PDF statique, celui-ci produit un .gif animé. Utilise les animations CSS @keyframes capturées image par image via Playwright et l'API Web Animations (Option A, par défaut), ou un pipeline IA image-vers-vidéo via Kling (Option B).
Règles critiques (à lire avant chaque génération)
- Par défaut, c'est css-animated. N'utilisez jamais
ai-generatedsauf demande explicite. - La zone de travail est de 800×800 px. Tous les calculs
clamp()sont basés sur 800 px (1vw = 8 px). - Un seul fichier HTML autonome. Tout le CSS en ligne dans
<style>. La seule dépendance externe autorisée est un<link>CDN pour les polices. - Ne publiez jamais le HTML dans le chat. Sauvegardez dans un fichier, affichez uniquement un résumé.
- La capture d'images utilise l'API Web Animations par défilement temporel. PAS de boucles
setTimeout, PAS d'astuces avecanimation-delay. - Nombre exact d'images :
Math.floor(durée_secondes * fps)images. L'image àt=durée_msNE DOIT PAS être capturée — elle dupliquet=0et provoque un à-coup visible au point de boucle. - Pas de boîtes de remplissage. Visuels générés uniquement par CSS. Pas d'éléments « l'image va ici ».
- Des palettes plus simples = des fichiers plus petits. Utilisez :
clean-slate,terminal,electric-burst,brutalist. - Pas de
animation-delaypour l'échelonnement. Intégrez l'échelonnement dans les pourcentages des@keyframes— le défilement temporel gère le timing. - Engagez-vous sur la direction du design avant d'écrire le CSS. Ton, élément signature, style de mouvement, détail inoubliable — tout décidé avant la première ligne de code.
Étape 1 : Prise en compte
Requis : prompt (description du contenu ET consigne de mouvement)
Optionnel avec valeurs par défaut :
| Paramètre | Valeur par défaut | Options |
|---|---|---|
| animation_type | css-animated | css-animated / ai-generated |
| duration | 3.0 | secondes |
| fps | 12 | images par seconde |
| loop | true | true / false |
| style | clean-slate | clean-slate / terminal / electric-burst / brutalist |
| dimensions | 800x800 | LxH en pixels |
| optimization | balanced | quality / balanced / filesize |
Si le prompt est manquant ou ne décrit pas le mouvement, demandez exactement :
« Que doit montrer le GIF ? Décrivez le contenu ET le mouvement (ex. : 'Compteur de stats : 73 % des acheteurs lisent 3+ contenus avant d'acheter. Effet machine à écrire, un caractère à la fois. Style : terminal. 3 secondes, 12 ips.') »
« Paramètres clés (tous optionnels, valeurs par défaut indiquées) :
- animation_type : css-animated (par défaut) ou ai-generated
- duration : 3,0 secondes
- fps : 12
- loop : true
- style : clean-slate (options : clean-slate / terminal / electric-burst / brutalist)
- dimensions : 800x800
- optimization : balanced (options : quality / balanced / filesize) »
Si toutes les informations requises sont présentes → passez directement à l'Étape 2.
Étape 2 : Architecture interne (jamais montrée à l'utilisateur)
Pour css-animated :
- Choisissez le type d'animation parmi :
fade-in,slide-in,typewriter,counter,pulse,loop-scroll - Lisez
references/animation-library.md— trouvez le cahier des charges HTML/CSS complet du type choisi - Lisez
references/style-presets.md— chargez le bloc de jetons CSS du style choisi - Calculez le nombre d'images :
Math.floor(durée_secondes * fps)— notez ce nombre - Engagez-vous sur la direction du design :
| Décision | Dérivé de |
|---|---|
| Ton | Registre émotionnel pour le public (mécanique / chaleureux / électrique / professionnel) |
| Élément signature | UN dispositif visuel utilisé systématiquement (clignement de curseur, chiffre fantôme, superposition de lignes de balayage, bordure d'accent) |
| Style de mouvement | Philosophie de courbe d'atténuation pour ce type (ressort / linéaire / par paliers / ease-in-out) |
| Détail inoubliable | La UNE chose dont un spectateur se souviendra en voyant ce GIF |
Pour ai-generated :
- Générez une image fixe de base au format HTML (disposition style affiche pour la zone de travail)
- Exportez-la en PNG via capture d'écran
- Appelez l'API Kling :
POST https://api.klingai.com/v1/videos/image2videoavecimage_urletpromptdécrivant le mouvement - Interrogez l'état d'avancement du travail
- Téléchargez la vidéo → convertissez-la en GIF avec ffmpeg :
# Palette en deux passes pour une meilleure qualité de couleur ffmpeg -i input.mp4 -vf "fps=12,scale=800:800:flags=lanczos,palettegen=stats_mode=diff" palette.png ffmpeg -i input.mp4 -i palette.png -vf "fps=12,scale=800:800:flags=lanczos,paletteuse=dither=bayer:bayer_scale=5" output.gif
Étape 3 : Génération HTML (chemin css-animated)
Lisez references/animation-library.md et references/style-presets.md avant de générer.
Base de la zone de travail — requise sur chaque GIF :
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
body {
width: 800px;
height: 800px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
}
.canvas {
width: 800px;
height: 800px;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
Règles d'animation :
animation-fill-mode: forwards(ouboth) sur TOUS les éléments animés- Fonctions de temporisation par type :
typewriter→steps(N, end)où N = nombre exact de caractèrescounter→linearfade-in→cubic-bezier(0.22, 1, 0.36, 1)(ease-out)slide-in→cubic-bezier(0.34, 1.56, 0.64, 1)(dépassement élastique)pulse→ease-in-outavecanimation-iteration-count: infiniteloop-scroll→linearavecanimation-iteration-count: infinite
- Pour les animations uniques (fade-in, slide-in, typewriter, counter) :
animation-iteration-count: 1— la boucle se fait au niveau du GIF - Pas de
animation-delay— l'échelonnement est intégré dans les pourcentages des@keyframes
Calcul du N pour le typewriter : Comptez chaque caractère, y compris les espaces, la ponctuation et les chiffres :
- « 73% d'acheteurs » = 15 caractères →
steps(15, end) - « Bonjour le monde ! » = 18 caractères →
steps(18, end)
CSS @property pour le counter (requis pour le type counter) :
@property --num {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
.counter {
animation: countUp var(--duration) linear forwards;
counter-reset: num var(--num);
}
.counter::after { content: counter(num); }
@keyframes countUp {
from { --num: 0; }
to { --num: var(--target); }
}
Loop-scroll : le contenu DOIT être dupliqué :
<!-- 4 éléments originaux + 4 éléments dupliqués -->
<div class="ticker-track" style="--item-count: 4;">
[élément1][élément2][élément3][élément4][élément1][élément2][élément3][élément4]
</div>
translateX(0 → -50%) avec linear infinite.
Règles de qualité du design (issues de l'engagement à l'Étape 2) :
- L'élément signature nommé DOIT être présent dans le CSS/HTML (pas seulement décrit)
- Typographie : contraste de poids minimum 2:1 (ex : 700 vs 400) entre le texte d'affichage et le texte secondaire
- Arrière-plan : pas de blanc pur
#fffpour les styles sombres — utilisez la valeur exacte--bgdu préréglage - Pour le style terminal : ajoutez une superposition de lignes de balayage
::afteravecrepeating-linear-gradientàopacity: 0.03 - Pour le style brutalist : bordure épaisse
4px solid #000ou4px solid var(--accent)sur l'élément clé - Détail inoubliable : s'il nécessite un élément supplémentaire — ajoutez-le maintenant
Étape 4 : Auto-vérification (corrigez chaque échec avant l'Étape 5)
Zone de travail :
-
bodyet.canvasexactement 800×800 px (ou dimensions spécifiées) -
overflow: hiddenà la fois surbodyet.canvas - Aucun élément ne dépasse les bords de la zone de travail
Animations :
- AUCUN
animation-delaynulle part — l'échelonnement est dans les pourcentages des@keyframes - Toutes les animations commencent à
t=0(l'API Web Animations cherchera à partir de là) -
animation-fill-mode: forwardsoubothsur tous les éléments animés - Animations uniques :
animation-iteration-count: 1 - Animations infinies (pulse, loop-scroll) :
animation-iteration-count: infinite
Vérifications spécifiques au type :
- Typewriter : N dans
steps(N, end)= nombre exact de caractères de la chaîne de texte - Counter :
@property --numdéclaré avecsyntax: '<integer>'etinitial-value: 0 - Counter :
counter-reset: num var(--num)et::after { content: counter(num) } - Loop-scroll : contenu dupliqué exactement une fois dans le HTML
Design :
- Pas de boîtes de remplissage
- Jetons du préréglage de style appliqués depuis
references/style-presets.md— pas de couleurs hexadécimales isolées - L'élément signature nommé à l'Étape 2 est effectivement présent dans le HTML/CSS
- Le détail inoubliable de l'Étape 2 est effectivement implémenté
-
<link>CDN pour la police présent pour la police du style choisi
Étape 5 : Export
Déterminez le slug à partir du prompt (kebab-case, ≤30 caractères). Créez le répertoire de sortie :
mkdir -p [slug]
Sauvegardez le HTML :
[slug]/animation.html
Ouvrez dans le navigateur pour un contrôle visuel rapide :
open [slug]/animation.html
Exécutez le script d'export (remplacez [skill-root] par le chemin réel de ce skill) :
bash [skill-root]/scripts/export-gif.sh \
[slug]/animation.html \
[slug]/animation.gif \
--duration [duration] \
--fps [fps] \
[--no-loop si loop=false] \
--optimization [optimization] \
--width [W] \
--height [H]
Le script :
- Installe
gifenc,sharp(oujimp) etplaywrightdans un répertoire temporaire - Télécharge Chromium s'il n'est pas en cache
- Exécute
capture-and-encode.mjs— met les animations en pause, cherche chaque image, prend une capture d'écran, assemble le GIF - Exécute une passe d'optimisation
gifsiclesi disponible - Signale la taille du fichier et ouvre le résultat
Si le script d'export n'est pas trouvé à l'emplacement [skill-root]/scripts/export-gif.sh, vérifiez que le skill a bien été installé avec son dossier scripts/ intact.
Étape 6 : Résumé de sortie
Affichez après un export réussi :
## GIF : [description en 1 ligne]
Date : [AAAA-MM-JJ] | Style : [style] | Animation : [type] | [durée]s @ [fps] ips
Dimensions : [LxH] | Images : [N] | Boucle : [true/false]
Fichiers
Source : [slug]/animation.html
Sortie : [slug]/animation.gif
Taille : [X] Ko
Liste de contrôle
- [ ] L'aperçu boucle proprement au point de départ/arrivée (pas d'à-coup)
- [ ] Texte lisible à la taille d'affichage prévue
- [ ] Taille de fichier appropriée : e-mail <500 Ko / réseaux sociaux <3 Mo
Chemin IA (Option B)
À utiliser uniquement lorsque animation_type: ai-generated est explicitement spécifié.
Prérequis :
- Clé API Kling dans l'environnement :
KLING_API_KEY(66 crédits gratuits/jour, pas de carte de crédit pour le niveau gratuit) ffmpeginstallé localement pour la conversion vidéo→GIF
Flux de travail :
- Générez une image fixe de base HTML correspondant au prompt (style affiche/graphique aux dimensions spécifiées)
- Exportez l'image fixe en PNG :
# Capture d'écran rapide via Playwright node -e " const { chromium } = require('playwright'); (async () => { const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: W, height: H } }); await page.goto('file://[slug]/animation.html'); await page.screenshot({ path: '[slug]/base-frame.png' }); await browser.close(); })(); " - Téléversez vers le point de terminaison image-vers-vidéo de Kling
- Convertissez le résultat en GIF avec la palette en deux passes de ffmpeg
- Appliquez l'optimisation gifsicle
Lorsque Kling est indisponible : Revenez à css-animated avec une note à l'utilisateur : « La génération IA nécessite une clé API Kling (KLING_API_KEY). Repli sur css-animated. Définissez la clé pour activer la génération IA. »
Conseils pour le prompt (afficher lorsque l'utilisateur demande des conseils)
« Décrivez le mouvement, pas seulement le contenu. 'Compteur de stats qui défile un par un' est mieux que 'afficher les stats'. »
« Restez simple pour la taille du fichier. 1 à 3 éléments animés et un arrière-plan uni. »
« Pensez en boucles. L'animation doit passer de la fin au début de manière invisible. »
« Spécifiez le type d'animation explicitement.
typewriteretcountersont les plus efficaces pour les réseaux sociaux. »✅ Bon : « Crée un GIF animé, css-animated, effet typewriter. Texte : '73 % des acheteurs B2B lisent 3+ contenus avant de contacter les ventes.' Chaque caractère s'affiche un par un. Style : terminal. 3 secondes, 12 ips, loop=true. »
❌ Mauvais : « fais un gif animé de conseils marketing »