use_figma — Skill API Figma pour Motion
Contexte Motion pour l'outil MCP use_figma. figma-use couvre les règles fondamentales de l'API Plugin — charge les deux ensemble.
Passe toujours skillNames: "figma-use-motion" (séparées par des virgules aux côtés de figma-use) lors de l'appel de use_figma pour le travail motion. Logging uniquement.
Runtime Gating
Les APIs Motion sont gérées par le flag utilisateur metronome_plugin_api. Quand l'utilisateur qui appelle ne l'a pas, chaque propriété motion et helper référencés dans ce skill lèvent "<name>" is not a supported API.
Abandon rapide sur cette erreur. Ne réessaye pas ; dis à l'utilisateur que motion n'est pas activé pour lui et arrête. Sinon tu brûleras des appels et confondras l'utilisateur avec des défaillances répétées identiques.
Quand utiliser ce skill
Charge ce skill chaque fois qu'une tâche use_figma implique :
- Ajouter, éditer ou supprimer des keyframes sur un nœud (
manualKeyframeTracks,applyManualKeyframeTrack,removeManualKeyframeTrack). - Animer les couleurs de remplissage ou de contour dans le temps.
- Appliquer, éditer ou supprimer des styles d'animation (
applyAnimationStyle,removeAnimationStyle,animationStyles). - Lire ou écrire la durée de la timeline via
node.timelines/node.setTimelineDuration(id, seconds). - Choisir l'easing pour l'un des éléments ci-dessus.
Le travail de design statique (créer des formes, composants, variables, layout) passe par figma-use seul — ce skill est uniquement pour la dimension temporelle.
Surface API motion exposée
node.manualKeyframeTracks— lire/écrire les keyframes manuelles (incluant les tracks de remplissage, contour et effet).node.applyManualKeyframeTrack(field, track)/node.removeManualKeyframeTrack(field)— ajouter, remplacer ou supprimer une seule track de keyframe manuelle sans réécrire l'objet entier.node.animationStyles— lire/écrire les métadonnées de style d'animation appliquées à un nœud.node.applyAnimationStyle(styleId, presetData?)/node.removeAnimationStyle(id)— appliquer un style découvert et supprimer une instance de style appliquée par sonidretourné/relus.node.timelines— liste timeline en lecture seule pour le frame top-level contenant, avec durées en secondes.node.setTimelineDuration(id, durationSeconds)— écrire la durée timeline du frame top-level contenant.node.animations— données de keyframe résolues en lecture seule (actuellement tracks manuelles uniquement — voir motion-patterns.md).figma.motion.figmaAnimationStyles()— liste en lecture seule des styles d'animation propriétaires de Figma.
L'authoring du code source du module preset "figma:motion" personnalisé est hors de portée. Si l'utilisateur veut un style d'animation totalement nouveau, dis-le et arrête ; ne l'invente pas.
Docs de référence
Charge-les selon les besoins en fonction de ce que la tâche implique :
| Doc | Quand charger | Ce qu'elle couvre |
|---|---|---|
| motion-patterns.md | Ajouter/éditer motion animation | Keyframes manuelles, remplissages/contours animés, appliquer des styles d'animation, durée timeline |
| motion-easing.md | Définir l'easing de l'animation | Objets easing keyframe, cubic/spring personnalisé, HOLD, appliquer l'easing dans un style d'animation |
Vérifier l'animation
get_screenshot montre uniquement l'état de repos de la timeline, jamais le motion. Pour vérifier le motion, export_video et sample les frames — mais c'est rendu côté serveur et slow et expensive (~10s à des minutes), donc rends chaque render rentable.
Planifie avant de rendre — le coût s'échelonne avec pixels × frames, garde donc les deux pas plus grands que les frames ne le nécessitent :
- Choisis d'abord les moments. Tu as besoin d'un frame par phase (p. ex. par étape stagger, ou start / mid / settle), pas une lecture fluide — habituellement 4–6. Ce compte définit ton fps.
- Dimensionne à ce que tu dois lire. Commence petit —
constraint: { type: 'WIDTH', value: 320 },quality: "low"— mais le texte et les petits éléments s'y floutent, donc augmenteWIDTH(768+) quand tu as besoin de juger les détails fins. Omettreconstraint= taille complète (1x ; le serveur limite à 10x / 4096px). - Définis fps juste assez haut pour atterrir sur ces frames :
fps: 5couvre une poignée ; 10 est une limite supérieure. Plus haut gonfle juste le render.
Mécaniques : export_video fonctionne uniquement sur un frame top-level dont les enfants portent l'animation (passe ce frame, pas le descendant que tu as keyframé). Il retourne un jobId avec status: "processing" — réinvoque avec { fileKey, jobId } pour sonder. Puis extrai les frames localement avec ffmpeg -ss <t> -i anim.mp4 -frames:v 1 frame_<t>.png — l'extraction est gratuite, donc une fois que tu as payé pour le render, exploite-le pour chaque frame qui te dit quelque chose plutôt que de re-exporter. Sans extracteur de frame comme ffmpeg, skip l'export et raisonne sur les keyframes à la place.
Itère jusqu'à ce que ce soit juste. L'export est un diagnostic, pas une approbation : si les frames sont incorrects (mauvais ordre, timing décalé, élément manquant, un mask blanking du composite), corrige les keyframes/styles et re-exporte. Lis tous les frames et batch chaque correction en un seul passage avant de re-rendre — chaque render porte une surcharge réelle, donc rends chaque un utile au lieu de re-exporter après chaque petit changement.
Saute l'export entièrement pour les changements triviaux ou auto-évidents.
Checklist pré-vol
En plus de la checklist pré-vol figma-use, vérifie :
- [ ] L'easing utilise la forme publique
{ type: 'EASE_OUT', easingFunctionCubicBezier?: …, easingFunctionSpring?: … }— pas les noms scenegraph internes commeOUT_CUBIC. - [ ] Ease-in-out utilise l'enum public exact
EASE_IN_AND_OUT(ouEASE_IN_AND_OUT_BACK) ; n'émets jamais l'alias invalideEASE_IN_OUT. - [ ] Le nœud animé n'est pas un frame top-level (enfant direct d'une page). Anime les descendants à la place.
- [ ] Les valeurs timeline sont en secondes dans la Plugin API publique. Étends via
setTimelineDuration; ne raccourcis jamais sauf si l'utilisateur a demandé. - [ ] Les champs de keyframe Transform utilisent les noms publics (
TRANSLATION_X,TRANSLATION_Y,ROTATION,SCALE_X,SCALE_Y,SCALE_XY), pas les noms scenegraph internesMOTION_*. - [ ] Les champs keyframe manuels proviennent de la liste d'approbation publique dans motion-patterns.md ; les champs scenegraph générés/internes lèvent intentionnellement.
- [ ] Les IDs de nœud mutés sont retournés (par
figma-useRule 15). - [ ] Quand la correction motion n'est pas auto-évidente et qu'un extracteur de frame (
ffmpeg) est disponible, vérifie viaexport_video+ frame sampling — rends petit,fpsbas, itère jusqu'à ce que ce soit juste (voir la section Vérifier l'animation ci-dessus).get_screenshotmontre uniquement l'état de repos.