Conception et animation dans Quar Animator
Quar Animator est un éditeur d'animation vectorielle 2D ; ses outils MCP lisent et modifient les projets cloud de l'utilisateur. Vous travaillez comme un motion designer qui peut voir son travail : planifier, construire, regarder, corriger, animer, observer le mouvement, exporter. Chaque regard est une image du serveur — faites-lui confiance plutôt qu'à ce que vous aviez l'intention de faire.
Si les outils quar-animator ne sont pas disponibles, dites-le et orientez l'utilisateur vers la configuration dans le README de cette compétence (connectez le MCP à https://api.animator.quar.pro/mcp) ; n'improvisez pas d'autre moyen de créer le fichier.
La boucle
- Lire.
list_projects(oucreate_project {name}pour un nouveau départ — donnez à l'utilisateur soneditorUrl, qui l'ouvre dans son éditeur ; un projet marquéstillUploadingn'a pas encore de version, ses vidéos sont encore en cours de téléchargement depuis l'éditeur : rien à ouvrir tant qu'il n'y en a pas), puisget_scene_context {project_id}. Notez leseq— transmettez-le commebase_seqà chaque modification, afin qu'une édition échoue au lieu d'atterrir sur des changements que vous n'avez pas vus. NotezframeRate,duration,artboardTimelines, et ce qui est verrouillé (celui de l'utilisateur : laissez-le tranquille sauf demande contraire). - Planifier avant de toucher à quoi que ce soit : le cadre (taille de l'artboard), la disposition, la palette, le
type, ce qui bouge et quand. Écrivez le plan en quelques lignes pour l'utilisateur. Utilisez
reference/design.mdetreference/motion.md; pour un type de pièce connu, suivez sa recette dansrecipes/. - Construire avec un essai à sec. Un
apply_edit_batchpour une étape cohérente (l'arrière-plan, la disposition, le type…) avecdry_run: true. Cela ne sauvegarde rien et renvoie ce qui changerait,placed— leatetboundsde chaque nœud ajouté ou modifié dans le résultat hypothétique, pour mesurer une disposition avant de la sauvegarder — et une image (preview_frame;preview_nodepour montrer un artboard ou nœud ;preview_sizejusqu'à 1024). Donnez vos propres identifiants àadd_node("id": "title") afin que les opérations ultérieures dans le lot puissent s'y référer. - Regarder et corriger. Jugez l'image par rapport à la checklist dans
reference/design.md: alignement, espacement, hiérarchie, contraste, rien de coupé. Corrigez le lot et refaites un essai à sec jusqu'à ce que ce soit bon. Ensuite, envoyez-le sansdry_run, avec unmessage("Disposition : titre, sous-titre et logo"). - Animer de la même manière : des opérations
animate(une par propriété, la courbe entière en une fois) dans un lot, essai à sec avecpreview_frameà un moment révélateur, puis validez. - Observer le mouvement.
render_previewaveccount: 8–12(répartis sur la timeline de ce qu'il dessine — celle d'un artboard) ou lesframesexactes où les choses se produisent (16 au maximum) donne une planche contact annotée (aveccount, sa dernière cellule est l'image N, que les exports ne jouent pas). Vérifiez le timing, le chevauchement, les pauses, que rien ne saute, et pour les boucles, que la dernière image correspond à la première. Corrigez avecanimate,move_keyframes,set_easing. - Exporter quand demandé (
export, puisget_export {export_id, wait: true}), et lisez ses détails : ce que Lottie n'a pas pu transférer (unsupported: types de nœuds, calques avec effets, modes de fusion), les images, la taille. Donnez le lien à l'utilisateur directement — il fonctionne une fois, dans l'heure ;get_exportà nouveau en donne un nouveau. - Informer l'utilisateur de ce que vous avez créé, en quelques lignes, et que chaque étape est une version qu'il peut annuler
(
list_versions,restore_version).
Gardez les lots ciblés : une version par étape significative (pas une par forme, ni la pièce entière d'un seul coup aveugle). Un lot accepte jusqu'à 500 opérations et est tout ou rien.
Les appels
Les arguments sont placés les uns à côté des autres — jamais imbriqués dans un objet options.
create_project {name}
get_scene_context {project_id, page?, node?, depth?}
get_node {project_id, node, page?} (chaque propriété stockée, ses images clés)
get_timeline {project_id, page?, node?, property?} (chaque image clé, avec son easing ; une propriété)
get_animatable_properties {node_type} (ce qu'un type peut animer : les os prennent aussi x, y)
list_fonts {} (les polices dans lesquelles le texte peut être dessiné, et leurs graisses)
measure_text {text, font_family?, font_weight?, font_size?, letter_spacing?, line_height?, box_width?}
(le x et l'avance de chaque glyphe, largeurs de ligne, ascent, descent)
apply_edit_batch {project_id, ops: [...], base_seq?, message?, dry_run?, preview_frame?,
preview_page?, preview_node?, preview_size?}
render_frame {project_id, frame?, node?, page?, size?, transparent?}
render_preview {project_id, frames? | count?, node?, page?, size?, transparent?}
capture_canvas {project_id, frame?, page?} (l'éditeur ouvert de l'utilisateur le dessine ; la version sauvegardée s'il ne répond pas)
export {project_id, format, node?, frame?, start_frame?, end_frame?, fps?, width?, height?}
get_export {export_id, wait?, include_file?}
list_versions {project_id}
restore_version {project_id, seq}
Une opération est {"op": <nom>, …ses arguments} ; chaque opération prend son propre page optionnel (il n'y a pas
de page sur le lot lui-même). Les opérations sont les noms des outils d'édition : add_node, update_node,
set_style, delete_node, duplicate_node, group_nodes, mask_nodes, ungroup_node, reorder_node, set_pivot, convert_to_outlines,
add_keyframe, animate, remove_keyframe, move_keyframes, set_easing, clear_animation,
add_page, delete_page, rename_page, duplicate_page, set_document,
set_artboard_duration, add_bone, pose_bone, set_ik_target, bind_mesh (au plus 20
bind_mesh et 60 calques dans un lot : liez plusieurs formes en une seule), unbind_mesh,
set_video_clip (ci-dessous). get_bindings lit quels os chaque calque lié suit ; un calque lié peut être supprimé (sa liaison disparaît avec lui). Lorsqu'un nom est partagé (une forme et un os tous deux "Cuisse G"), utilisez l'identifiant.
[
{ "op": "add_node", "type": "rectangle", "id": "card", "parent": "frame", "x": 0, "y": 0,
"width": 640, "height": 360, "cornerRadius": 24, "fill": "#1f1d29" },
{ "op": "set_style", "node": "card",
"effects": [{ "type": "drop-shadow", "color": "#07060b", "offsetY": -16, "blur": 40, "opacity": 0.4 }] },
{ "op": "animate", "node": "card", "property": "y",
"keyframes": [{ "frame": 0, "value": -120 }, { "frame": 18, "value": 0, "easing": "easeOutCubic" }] },
{ "op": "animate", "node": "card", "property": "scale",
"keyframes": [{ "frame": 0, "value": { "x": 0.9, "y": 0.9 } }, { "frame": 18, "value": { "x": 1, "y": 1 } }] },
{ "op": "animate", "node": "card", "property": "fill",
"keyframes": [{ "frame": 0, "value": "#1f1d29" }, { "frame": 18, "value": "#a855f7" }] }
]
Valeurs : nombres pour x, y, rotation, opacity, tailles ; {x, y} pour position et scale ;
"#rrggbb" pour fill et stroke. Effets : drop-shadow et inner-shadow prennent color,
offsetX, offsetY, blur, spread, opacity ; layer-blur prend radius.
Faits qui surprennent
- Y pointe vers le haut. Le
x,yd'un nœud est son ancrage — le centre pour la plupart des formes, artboards inclus. Un y plus grand est plus haut à l'écran. (Les données de cheminsvgsont l'exception : Y vers le bas, comme dans les fichiers SVG, dans l'espace propre du nœud autour de son centre.) - Deux espaces.
atetbounds(dansget_scene_contextet leplacedd'un essai à sec) sont des coordonnées de page ; lex,yd'un nœud — et les images clés dessus — sont dans l'espace de son parent. À l'intérieur d'un artboard ou d'un groupe qui n'est pas au centre de la page, les deux diffèrent : animez autour dux/ypropre du nœud (get_node), pas sonat. - Les enfants sont dessinés de l'arrière vers l'avant : les frères ultérieurs sont au-dessus. Ajoutez l'arrière-plan en premier et la
forme focale en dernier, ou réorganisez avec
reorder_node {node, to: "front"|"back"|…, index?}. - Un artboard est blanc sauf si on lui donne un remplissage :
"fill": "none"pour un transparent (un Lottie d'application, un autocollant). - Pivots. La mise à l'échelle et la rotation se font autour de la position d'un nœud, son pivot — le centre pour la plupart
des formes. Pour pivoter ailleurs — un membre à son articulation, un logo s'écrasant sur le sol, un mot grandissant
vers sa droite —
set_pivot {node, at: "bottom"}(un emplacement sur sa propre boîte :left,top-right…) ou{node, x, y}(un point sur la page) ; il reste là où il est à l'écran. Les groupes, rectangles et images acceptent un pivot ; mettez tout autre chose d'abord dans un groupe (group_nodes {nodes: [it], id}— son groupe se trouve à l'origine de son parent jusqu'à ce qu'il soit pivoté), puis pivotez le groupe. Définissez les pivots avant d'animer la rotation ou l'échelle : les rotations animées se font autour du pivot. (update_nodene peut pas changer un parent :reorder_node {node, parent}déplace un nœud dedans, en le gardant en place.) - Masques.
mask_nodes {nodes, mask?, mode?}place les nœuds et un masque (une forme, du texte ou une image ; le plus en avant des nœuds lorsqu'il n'est pas nommé) dans un groupe qui les montre seulement à l'intérieur — révélations, vignettes, une image dans un cadre, quelque chose passant derrière un bord. Le masque n'est pas dessiné ; animez-le (sa taille, position, échelle) pour révéler.mode:clip(son contour),alpha(son opacité : un dégradé de transparence),luminance(le blanc montre, le noir cache). rotationest en degrés dans le sens inverse des aiguilles d'une montre, interpolé tel qu'écrit : 0 → 360 est un tour complet ; -360 tourne dans le sens horaire.- Dégradés : l'angle 0° va de gauche à droite, 90° de bas en haut (270° de haut en bas).
- Ombres : un
offsetYnégatif place une ombre en dessous. letterSpacingest en pixels (−2 à 100 px est une police d'affichage serrée).- Un chemin conserve son propre centre comme position : animez
x/yautour de sa valeur actuelle (lisez-la avec leatdeget_scene_context), jamais autour de 0. - Texte et polices. Le texte est dessiné, disposé et mesuré dans sa propre famille lorsqu'il s'agit d'Inter (toujours
présente : toutes les graisses de 100 à 900, italiques à 400 et 700) ou d'une des polices Google de l'éditeur
(
list_fonts: familles et leurs graisses — uniquement droites ; une graisse manquante prend la plus proche). Le serveur récupère une police Google la première fois qu'un document l'utilise. Sa largeur est exacte (avances, crénage, espacement des lettres) ; sa hauteur est la boîte de ligne (lignes × taille ×lineHeight). Une famille non présente dans la liste est dessinée et mesurée dans Inter, et les réponses le disent (fonts) : choisissez dans la liste, ou vérifiez la police propre de l'utilisateur aveccapture_canvaspendant que le projet est ouvert dans son éditeur.measure_textplace le texte sans le positionner : lexetadvancede chaque glyphe, la largeur de chaque ligne, l'ascent et le descent de la police — pour les curseurs, les soulignements et l'ajustement d'un mot à une largeur.convert_to_outlines {node}transforme du texte en un groupe de chemins de lettres (<id>-1…, nommés par leur lettre) pour une animation lettre par lettre : échelonnez-les, recolorez-en un, faites-en rebondir un. Unidirectionnel. - Timelines.
durationetframeRatesont ceux du document. Chaque artboard en haut d'une page joue sa propre timeline — les images clés de ses calques, à sa propre longueur (artboardTimelines;set_artboard_duration {artboard, duration}; celle du document jusqu'à ce qu'il en ait une). Une timeline de N images prend des images clés à 0…N ; les exports et diapositives jouent les images 0…N−1, donc pour une boucle, l'image clé N doit être égale à l'image 0. Allongez une timeline avant de placer des clés au-delà de sa fin (set_document {duration}pour celle de la page). - Diapositives. Dans les présentations et exports vidéo de l'éditeur, et dans les exports GIF et séquence PNG
d'une page avec plusieurs artboards (pas de
node, pas de plage), les artboards jouent l'un après l'autre — le plus en avant en premier (le haut du panneau Calques), chacun pour sa propre durée, ajusté dans la taille du premier. Un artboard ajouté plus tard est devant, donc il jouerait en premier : ajoutez les diapositives ultérieures avecindex: 0, oureorder_node.artboardTimelinesles liste dans l'ordre de lecture. Exportez un artboard avecnode. Les MP4 et WebM proviennent de l'éditeur (Fichier › Exporter), pas du MCP. easingest la courbe dans une image clé depuis la précédente. Les noms sont dansreference/motion.md;[x1, y1, x2, y2]donne une courbe de Bézier cubique. Un easing de dépassement (easeOutBack) dans une image clé qui est déjà le dépassement dépasse deux fois : utilisezeaseOutCubicdans le pic et l'easing élastique pour la stabilisation.- Vidéos. Un calque vidéo (
"type": "video": un MP4, MOV ou WebM, ou un GIF animé que l'utilisateur a importé) est une image qui joue tant que son clip dure et n'affiche rien en dehors à moins qu'il ne tienne.get_scene_contextdonne sonvideo: lefile,gif, salength(secondes), et sonclip—start(l'image à laquelle il commence),end(l'image à laquelle il s'arrête),offset(secondes rognées du début de la vidéo),duration(secondes de la vidéo qu'une passe joue),speed,loopetloopFor(secondes pendant lesquelles il boucle),hold(sa dernière image reste après sa fin) — et sonsoundlié (un clip sur la timeline qui bouge avec lui). Changez le clip avecset_video_clip {node, moveTo?, trimStart?, trimEnd?, speed?, loop?, hold?, stopAt?, unlinkSound?}— images de la timeline sur laquelle le calque joue, appliquées dans l'ordre loop, speed, moveTo, trimStart, trimEnd, hold, stopAt :moveTole fait commencer à une image ;trimStartfait d'une image sa première, sa fin restant en place (plus tard rogne le début de la vidéo, plus tôt en joue plus) ;trimEndle fait s'arrêter à une image (plus tôt rogne la fin ; plus tard en joue plus, jusqu'à la fin de la vidéo — ou, avecloop, boucle jusqu'à ce moment :{loop: true, trimEnd: 300}remplit une diapositive de 10 secondes).speed0,25–4 (le son garde sa hauteur) ;hold: truegarde la dernière image affichée ;stopAtle termine à une image, en affichant ce qui s'y trouve (un GIF figé à mi-parcours) ;loop: falsesur un GIF le tient aussi.- Son son suit chaque changement, et la timeline sur laquelle il joue est allongée pour le jouer jusqu'à sa
fin (le résultat dit
timelineLengthened).unlinkSound: truerend le son indépendant. Sinon, un calque vidéo est une image : déplacez-le, redimensionnez-le (width,height), arrondissez-le (cornerRadius), fondez,adjustments, effets, modes de fusion, masques (il peut aussi masquer), pivots et images clés comme pour une image — mais pas de tirage de coin ni d'os.duplicate_nodecopie son son avec lui ;delete_nodesupprime son son.