Communitygithub.com

MBehtemam/montagent-skills

Graphismes et titres animés dans Montagent : spots publicitaires, annonces produit et réseaux sociaux, intros, outros, texte cinétique et typé, révélations de logo, boucles, fondus, pop-in, changements de couleur, cartes qui se retournent et portes qui pivotent en perspective, et effets de bande-annonce (titres percutants, coupures glitch, HUDs). À utiliser quand une vidéo Montagent est construite avec des graphismes et du texte plutôt qu'avec des séquences filmées ou un personnage.

Qu'est-ce que montagent-skills ?

Ce skill spécialise l'agent dans la création d'animations de graphismes et de titres dans Montagent. Il fournit des recettes structurées pour construire des éléments comme des spots publicitaires, des intros, des révélations de logo, des effets de texte cinétique et des transitions entre scènes, le tout basé sur une grille rythmique (`montagent-craft`). L'utilisateur commence par un « beat sheet » qui spécifie chaque entrée, changement de couleur, coupe et sortie sur un temps de la grille, puis un script génère le projet à partir de cette table. Les recettes incluent des techniques comme le « Pop » (entrée avec léger dépassement), le « Hold, then clear » (maintien suivi d'une sortie rapide), le changement de couleur sur un mot, le texte cinétique/typé (avec `units` pour le décalage lettre par lettre, mot par mot ou ligne par ligne), le dévoilement par wipe (avec occluseur et barre de bord), et la transition poussée/glissée/wipe entre éléments. Chaque recette fournit des plages de paramètres (durée, échelle, courbe d'ease) et se termine par une étape de vérification visuelle : `frame` puis `preview`. Le skill précise également des contraintes importantes : ne pas convertir les glyphes en `path` pour les polices multi-contours (O, A, B, etc.), utiliser `letter_spacing` pour les titres espacés, et pour le texte vertical CJK ou les colonnes latines en rotation, utiliser ` ` ou `rotation` respectivement. Les instructions sont complexes et techniques, nécessitant une bonne compréhension de la structure de Montagent et des animations par keyframes.

Compatible avec~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/MBehtemam/montagent-skills/tree/HEAD/skills/montagent-motion

Demander à votre IA préférée

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

Documentation

Graphismes et titres animés

Recettes pour des pièces construites à partir de formes, d'images fixes et de texte. Elles s'insèrent dans la boucle de montagent à l'étape de construction ; chargez d'abord montagent si ce n'est pas déjà fait.

Ouvrez le fichier de référence pour le type de pièce avant de la planifier :

La pièceOuvrir
Spot publicitaire, annonce produit ou réseau social, intro, outrola structure d'un spot publicitaire
Révélation de logo, logo sting, tout ce qui bouclela boucle de logo
Bande-annonce, ou tout effet percutant, glitché, clignotant ou HUDeffets de bande-annonce

Pour une nouvelle pièce ou une refonte, lisez la direction créative avant de choisir la mise en page. Elle couvre les concepts visuels, la composition et la chorégraphie en Montagent natif. Pour une édition spécifique, lisez uniquement la recette pertinente et conservez la direction existante.

Planifier sur une grille rythmique (beat sheet)

Avant d'écrire un élément, écrivez la grille rythmique (beat sheet) : chaque entrée, changement de couleur, coupe et sortie dans un seul tableau, chacun sur un temps de la grille que montagent-craft fournit (son tempo, downbeat, accrochage aux images, et quels événements vont sur les temps).

Construisez le projet avec un script générateur à partir de la grille rythmique, afin qu'un réajustement temporel soit une modification d'une seule ligne.

Recettes

Chaque recette donne des plages de départ, pas des réponses. Chacune se termine par une étape de vérification (look step) : chargez montagent-craft, puis regardez là où l'étape le dit avant de continuer.

Pop

Une entrée avec un petit dépassement qui se stabilise. Le dépassement est la courbe : une paire de keyframes avec une bezier dont le y dépasse 1, pas trois keyframes.

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/pop.mp4",
  "tracks": [
    {"name": "badge", "layer": 10, "elements": [
      {"id": "badge", "type": "ellipse", "start": 500, "end": 2000, "x": 960, "y": [{"t": 500, "v": 580}, {"t": 900, "v": 540, "ease": [0.34, 1.56, 0.64, 1]}], "origin": "center", "width": 240, "height": 240, "fill": "#FF5A36", "scale": [{"t": 500, "v": [0.5, 0.5]}, {"t": 900, "v": [1.0, 1.0], "ease": [0.34, 1.56, 0.64, 1]}]}
    ]}
  ]
}
  • Durée : 300–450 ms. Plus court pour les snaps, plus long pour les flottements.
  • Échelle de départ : 0,5–0,7 pour le texte et les cartes ; 0 pour les petites formes et badges.
  • Dépassement : [0.34, 1.56, 0.64, 1] culmine à environ 10 % au-dessus. Augmentez son deuxième nombre à 1,8 pour quelque chose de ludique, ou abaissez-le à 1,3 pour quelque chose de corporate. Gardez une seule courbe pour chaque pop dans une pièce.
  • Montée : 20–60 px de déplacement sur y avec la même courbe ajoute du poids. Sautez-la sur les pops qui se suivent en ligne.
  • Décalage : un temps lorsque chaque élément atterrit sur son propre temps ; 60–120 ms entre les éléments à l'intérieur d'un même temps.
  • Vérification : frame au début plus 40 % de la durée, là où le dépassement culmine, et vérifiez que rien ne dépasse du bord du cadre ou d'un voisin. Ensuite preview une plage allant de juste avant le premier pop à juste après le dernier.

Hold, then clear (Maintenir, puis effacer)

La dernière keyframe d'une entrée maintient déjà, donc un maintien ne coûte rien. Une sortie commence par une keyframe à la valeur maintenue, au moment où la sortie commence. validate signale cette keyframe comme R-EASE-INERT, et le guide des résultats explique pourquoi c'est attendu.

  • Durée de sortie : 200–350 ms, ease-in. Les sorties sont plus rapides que les entrées.
  • Mouvement de sortie : un fondu plus 20–40 px de déplacement, ou une réduction d'échelle à 0,9. Pour une coupe franche, utilisez une seule keyframe step vers la nouvelle valeur (voir le projet de démarrage du titre).
  • Durée de maintien : le temps de lecture que montagent-craft donne.
  • Regrouper les sorties : tout le groupe part ensemble, ou décalé de 30–60 ms dans l'ordre de lecture.
  • Vérification : frame sur la dernière image dessinée avant la sortie, et vérifiez que tout le groupe est complètement entré et au repos.

Changement de couleur sur un mot

Recolorez un mot à l'intérieur de sa ligne avec un highlight sur la séquence de ce mot, commençant sur le temps. Cela conserve un seul élément : il n'y a pas de deuxième copie à fondre, et la couleur propre de l'élément reste la couleur de la ligne.

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 3000, "output": "out/accent.mp4",
  "fonts": {"title": [{"file": "fonts/Inter-Bold.ttf"}]},
  "fontVendor": {"fonts/Inter-Bold.ttf": {"licence": "OFL-1.1", "source": "https://github.com/rsms/inter", "sha256": "288316099b1e0a47a4716d159098005eef7c0066921f34e3200393dbdb01947f"}},
  "tracks": [
    {"name": "line", "layer": 20, "elements": [
      {"id": "line", "type": "text", "start": 0, "end": 3000, "x": 960, "y": 540, "origin": "center", "width": 1600, "height": 140, "font": "title", "size": 110, "color": "#F5F0E6", "align": "center", "runs": [{"text": "Video your agent can "}, {"text": "read.", "highlight": {"start": 2000, "end": 3000, "color": "#FF5A36"}}], "caption": false}
    ]}
  ]
}
  • Timing : le changement atterrit sur un temps, jamais sur l'entrée du mot. Donnez à l'œil au moins un demi-temps pour lire le mot d'abord.
  • Emphase : lorsque le mot est son propre élément, une bosse d'échelle sur le même temps (1,0 à 1,06–1,1 et retour sur 200–300 ms) fait atterrir le changement.
  • Vérification : frame une image avant et une image après le changement, et vérifiez qu'un seul mot a changé.

Texte cinétique et typé

Lorsque chaque lettre, mot ou ligne partage une même courbe de mouvement sur un pas régulier (every ms), conservez un seul élément text et décalez-le avec units (by : letter, word ou line ; order : forward, reverse, center_out ou edges_in). Ici, un titre s'évapore en se concentrant depuis son centre vers l'extérieur :

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/evaporate.mp4",
  "fonts": {"title": [{"file": "fonts/Inter-Bold.ttf"}]},
  "fontVendor": {"fonts/Inter-Bold.ttf": {"licence": "OFL-1.1", "source": "https://github.com/rsms/inter", "sha256": "288316099b1e0a47a4716d159098005eef7c0066921f34e3200393dbdb01947f"}},
  "tracks": [
    {"name": "title", "layer": 20, "elements": [
      {"id": "evaporate", "type": "text", "start": 0, "end": 2000, "x": 960, "y": 540, "origin": "center", "width": 1400, "height": 160, "font": "title", "size": 108, "color": "#F5F0E6", "align": "center", "runs": [{"text": "SHARP FOCUS"}], "units": {"by": "letter", "order": "center_out", "every": 45, "y": [{"t": 0, "v": 20}, {"t": 360, "v": 0, "ease": "ease-out"}], "opacity": [{"t": 0, "v": 0}, {"t": 360, "v": 1, "ease": "ease-out"}], "blur": [{"t": 0, "v": 24}, {"t": 360, "v": 0, "ease": "ease-out"}]}, "caption": false}
    ]}
  ]
}
  • Évaporation / mise au point optique (blur) : clé blur dans units de 16–32 px jusqu'à 0 sur 300–450 ms (ease-out), associée à opacity (0 -> 1) et une petite levée y (16–28 px -> 0) ou scale ([1.08, 1.08] -> [1.0, 1.0]). Une fois que blur atteint 0 et opacity atteint 1, le rendu emprunte le chemin rapide avec un coût de couche supplémentaire nul.
  • Ordres symétriques (center_out, edges_in) : center_out commence sur l'unité du milieu (ou la paire du milieu lorsque le nombre est pair) et s'étend vers les deux extrémités ; edges_in commence sur la première et la dernière unité ensemble et converge vers le milieu.
  • Onde progressive (A -> pic -> A) : au lieu d'un After Effects Range Selector (triangle, round ou smooth), écrivez une courbe de retour à trois keyframes dans units — par exemple "y": [{"t": 0, "v": 0}, {"t": 180, "v": -28, "ease": "ease-out"}, {"t": 360, "v": 0, "ease": "ease-in-out"}] (ou une impulsion scale / blur) — et laissez every onduler le pic à travers la ligne. Pour isoler un mot ou une lettre avec un timing personnalisé, divisez-le dans sa propre séquence avec unit.
  • Conserver les glyphes en tant que text (ne jamais convertir les glyphes en path) : les éléments path ont un seul contour (points sans holes), donc la conversion de glyphes multi-contours (O, A, B, 8, i, ?, %) en path remplit les compteurs intérieurs en plein ou perd des îlots (ADR-0224). Conservez le texte en tant que text et stylisez-le ou animez-le avec stroke, units, path et effects.
  • Temps de battement irréguliers ou curseur de frappe (scripts/type_on.py) : lorsque les mots atterrissent sur des horodatages de battement irréguliers ou que les lettres ont besoin d'un cursor pas à pas, exécutez python3 scripts/type_on.py <project> <spec> (--help pour la spécification). Il mesure la ligne avec measure et émet un élément text par unité ("by": "word" avec "enter": "pop" et times / highlights, ou "by": "letter" à 60–150 ms avec un cursor clignotant), marquant chaque caption: false.
  • Titres espacés : ne divisez pas le titre en lettres. Écrivez un seul élément text avec letter_spacing, en millièmes d'em (size × letter_spacing / 1000 px après chaque lettre ; le négatif resserre). Clé pour écarter un titre : "letter_spacing": [{"t": 0, "v": 0}, {"t": 800, "v": 120, "ease": [0.65, 0, 0.35, 1]}]. Toute valeur non nulle désactive les ligatures optionnelles, et un script de jointure comme l'arabe ne prend pas d'espacement.
  • Colonnes verticales et épines latérales : Montagent n'a pas de propriété writing_mode (ADR-0224). Pour une colonne empilée verticale (texte vertical CJK ou marquee empilé), joignez les graphèmes avec \n ("text": "東\n京\n都") à l'intérieur d'une boîte text étroite avec "align": "center" et "line_height": 1.0 ou 1.1 ; conservez 2–3 chiffres horizontaux ou initiales latines sur une ligne ("text": "第\n25\n回", Tate-chu-yoko) et décalez avec "by": "line" afin que le nombre horizontal se déplace comme une unité. Pour une épine latérale latine, définissez un élément text horizontal et faites-le pivoter avec "rotation": -90 (lecture de bas en haut) ou "rotation": 90 (lecture de haut en bas).
  • Vérification : preview la plage de la ligne qui arrive. Ensuite frame au repos, et vérifiez que l'espacement se lit comme une seule ligne, sans écart plus large à une limite de mot ou de lettre.

Dévoilement par wipe (balayage)

Un wipe découvre quelque chose en faisant glisser un bord dessus. Placez un occluseur au-dessus de la chose : un rect rempli exactement de ce qui se trouve derrière la chose. Réduisez ensuite l'occluseur autour de son bord éloigné, de sorte que son bord proche balaye. Une barre d'accentuation chevauchant ce bord rend le wipe délibéré.

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 2000, "output": "out/wipe.mp4",
  "tracks": [
    {"name": "mark", "layer": 10, "elements": [
      {"id": "mark", "type": "image", "start": 0, "end": 2000, "source": "media/still.png", "x": 960, "y": 540, "origin": "center", "width": 360, "height": 360, "fit": "contain"}
    ]},
    {"name": "occluder", "layer": 11, "elements": [
      {"id": "occluder", "type": "rect", "start": 0, "end": 1000, "x": 1160, "y": 540, "origin": "center-right", "width": 400, "height": 400, "fill": "#101418", "scale": [{"t": 400, "v": [1.0, 1.0]}, {"t": 900, "v": [0.0, 1.0], "ease": [0.65, 0, 0.35, 1]}]}
    ]},
    {"name": "edge", "layer": 12, "elements": [
      {"id": "edge", "type": "rect", "start": 400, "end": 1000, "x": [{"t": 400, "v": 760}, {"t": 900, "v": 1160, "ease": [0.65, 0, 0.35, 1]}], "y": 540, "origin": "center", "width": 16, "height": 420, "fill": "#FF5A36", "opacity": [{"t": 900, "v": 1.0}, {"t": 1000, "v": 0.0, "ease": "ease-in"}]}
    ]}
  ]
}
  • Durée : 400–600 ms, [0.65, 0, 0.35, 1] : un balayage qui commence et se termine en douceur.
  • Occluseur : 20–40 px plus grand que la chose sur chaque côté, et le même remplissage que le fond derrière elle. La keyframe de départ se trouve là où le wipe commence, donc la chose reste couverte jusqu'à ce moment.
  • Barre de bord : 8–24 px de large, 5–10 % plus haute que l'occluseur, se déplaçant sur la même courbe et le même temps. Elle disparaît sur 100–200 ms une fois le balayage terminé.
  • Direction : wipe dans le sens de la lecture ; pour effacer, agrandissez à nouveau l'occluseur depuis le bord proche.
  • Fond chargé : un occluseur ne fonctionne que sur une couleur unie. Sur une photo, un dégradé ou une séquence filmée, utilisez plutôt le mask propre de l'élément : {"name": "mask", "shape": "rect", "x": 0, "y": 0, "width": [{"t": 400, "v": 0}, {"t": 900, "v": 400, "ease": [0.65, 0, 0.35, 1]}], "height": 400} découvre un élément 400 × 400 depuis son bord gauche, sans occluseur. Le rect est local à l'élément, depuis son coin supérieur gauche ; un masque de largeur width zéro cache l'élément, donc la révélation commence couverte. Ajoutez feather pour un bord doux.
  • Vérification : frame au milieu du balayage et vérifiez que la barre de bord recouvre exactement le bord de l'occluseur ; ensuite frame juste après le balayage et vérifiez qu'il ne reste rien de l'occluseur.

Passer la main avec une poussée, un glissement ou un wipe

Pour passer d'une carte, image fixe ou scène à la suivante avec du mouvement, faites le pont entre les deux avec une transition de type push, slide ou wipe. Un x clé sur les deux éléments dériverait à la jonction ; la transition maintient les deux moitiés jointes au pixel près, et validate le vérifie.

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 3000, "output": "out/handover.mp4",
  "tracks": [
    {"name": "first", "layer": 10, "elements": [
      {"id": "card-1", "type": "rect", "start": 0, "end": 1700, "x": 0, "y": 0, "origin": "top-left", "width": 1920, "height": 1080, "fill": "#FF5A36"}
    ]},
    {"name": "second", "layer": 11, "elements": [
      {"id": "card-2", "type": "rect", "start": 1200, "end": 3000, "x": 0, "y": 0, "origin": "top-left", "width": 1920, "height": 1080, "fill": "#2E86FF"}
    ]},
    {"name": "handover", "layer": 12, "elements": [
      {"id": "handover", "type": "transition", "start": 1200, "end": 1700, "kind": "push", "from": "card-1", "to": "card-2", "direction": "left", "ease": [0.65, 0, 0.35, 1]}
    ]}
  ]
}
  • Type : push lorsque les deux appartiennent à une même bande (pages, étapes, un carrousel) ; slide lorsque le nouveau atterrit au-dessus d'un ancien immobile ; wipe lorsque l'ancien doit rester en place et être découpé.
  • Direction : la direction du mouvement. left fait entrer le nouveau par la droite, ce qui suit le sens de la lecture.
  • Durée : 400–600 ms, [0.65, 0, 0.35, 1]. Le start et end de la transition sont exactement le temps que les deux partagent.
  • Empilement du slide : dans un slide, l'élément entrant doit se trouver sur le layer le plus élevé.

Effets de bande-annonce

Utilisez trailer.md pour les titres percutants, les coupures glitch, les superpositions HUD et les effets de flash. Cela couvre la mise à l'échelle sous contrainte (fit: cover avec une fenêtre d'affichage), le tramage temporel, les éclairs de flash et les réflexions de lentille. (Se reporter au fichier de référence.)

Configuration de la fenêtre d'affichage

Pour forcer l'échelle et le recadrage d'une image de fond ou d'un élément plein écran, définissez viewport sur la piste :

{
  "frame": {"width": 1920, "height": 1080}, "fps": 30, "background": "#101418", "duration": 3000, "output": "out/viewport.mp4",
  "tracks": [
    {"name": "footage", "layer": 10, "viewport": {"x": 0, "y": 0, "width": 1920, "height": 1080}, "elements": [
      {"id": "bg", "type": "image", "start": 0, "end": 3000, "source": "media/bg.png", "x": 960, "y": 540, "origin": "center", "width": 2400, "height": 1350, "fit": "cover"}
    ]}
  ]
}
  • viewport : la région visible de la piste, en pixels de l'espace du cadre. Tout ce qui dépasse est masqué.
  • fit: cover : l'image remplit la fenêtre d'affichage en conservant son rapport hauteur/largeur, recadrant l'excédent.
  • Les fenêtres d'affichage animées (clé sur x ou y) créent un effet de caméra panoramique sur un arrière-plan fixe.
  • Vérification : frame au début et à la fin, et vérifiez que l'élément remplit la fenêtre d'affichage sans barres noires.

Construire et vérifier

  1. Écrivez la grille rythmique.
  2. Générez le projet : exécutez python3 scripts/generate.py <beat-sheet> <output-dir>.
  3. Vérifiez chaque étape : pour chaque recette, exécutez montagent build puis montagent preview ou montagent frame comme indiqué.
  4. Validez : exécutez montagent validate pour détecter les problèmes courants.
  5. Exportez : exécutez montagent render.

Dépannage

ProblèmeCause probableSolution
Le wipe montre une coutureL'occluseur ne correspond pas au fondDéfinissez fill de l'occluseur sur la même couleur que background du cadre
Le pop semble saccadéLe dépassement est trop élevé ou la durée trop courteAbaissez le deuxième nombre de l'ease à 1,3 ou augmentez la durée de 50 ms
La transition push a un écartLes éléments n'ont pas la même tailleAssurez-vous que les deux éléments from et to ont des dimensions et des origines identiques
units n'a aucun effetunits est mal orthographié ou by est manquantVérifiez que la propriété s'appelle units (pas unit), avec by : letter, word ou line
Les glyphes path ont des trous remplisLa police a des glyphes multi-contoursUtilisez type: text au lieu de convertir en path (voir ci-dessus)

Voir aussi

Individual skills in this repo

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

Skills associés