Motion design (HyperFrames 版)
Les fichiers HyperFrames vous enseignent l'API ; ce fichier gère le goût. Les chiffres ci-dessous proviennent d'une production réelle mise en ligne. Traitez-les comme des valeurs par défaut : vous pouvez vous en écarter, mais ce doit être un choix délibéré, pas un oubli.
Adapté du skill
motion-designde whaleyxbt/claude-motion (MIT, voirLICENSEdans le même dossier). L'original était pour Remotion ; cette version est réécrite pour HyperFrames (HTML + GSAP) et inclut les règles de composition en chinois traditionnel. Les sections marquées « (Ajout de cette version) » ne font pas partie du contenu original.
Répartition avec les skills officiels HyperFrames (Ajout de cette version)
Ce poste de travail dispose également des skills officiels HyperFrames de HeyGen (hyperframes, hyperframes-core, hyperframes-animation, etc.). Voici la répartition :
- Les skills officiels gèrent le « comment faire » : structure du projet, attributs
data-*, écriture de l'API, routage des flux, composants prêts à l'emploi du registry. En cas de conflit entre l'écriture de l'API et ce fichier, la version officielle prévaut. - Ce fichier gère le « bon goût » : easing, rythme, temps d'arrêt, polices de caractères, palette de couleurs, composition chinoise. Lorsque vous utilisez les règles / blueprints de
hyperframes-animationofficiel, les valeurs temporelles et d'easing restent celles de ce fichier par défaut. - Vérification : utilisez toujours
review-loop, qui intègre déjà lehyperframes checkofficiel.
0. Règles strictes d'HyperFrames (Ajout de cette version)
Enfreindre ces règles provoque des scintillements, des décalages ou des résultats différents à chaque rendu :
-
Le temps est déterminé par le HTML : chaque scène est un élément avec
class="clip", utilisantdata-startetdata-durationpour le placement sur la timeline. L'élément racine doit avoirdata-composition-idet undata-durationexplicite. -
Les animations sont gérées par GSAP :
gsap.timeline({ paused: true }), enregistrée danswindow.__timelines["<composition-id>"], dont la clé doit être égale àdata-composition-id. -
Chaque tween important reçoit une position explicite (troisième paramètre) ; utilisez
fromTo()lorsque les deux extrémités sont importantes, car le rendu peut effectuer des sauts (seek). -
Animez uniquement
transformetopacity, ne modifiez pastop/left/width/heightde manière répétée. -
Interdits : CSS
transition/@keyframes,Date.now(),requestAnimationFrame,setTimeout,Math.random()sans seed, ressources chargées pendant le rendu. -
N'utilisez pas de scripts pour lire, mettre en pause ou chercher (seek) des médias audio/vidéo, ni pour afficher ou masquer des clips en fonction du temps. Laissez ces tâches aux attributs
data. Pour déplacer une vidéo, animez son conteneur externe. -
Utilisez toujours une fonction aléatoire à graine :
function rand(seed) { let t = (seed += 0x6D2B79F5); t = Math.imul(t ^ (t >>> 15), t | 1); t ^= t + Math.imul(t ^ (t >>> 7), t | 61); return ((t ^ (t >>> 14)) >>> 0) / 4294967296; }
1. Tout le temps à un seul endroit
-
Chaque battement est un point temporel nommé (en secondes), regroupé par scène (
s1,s2…), écrit danstimeline.jsà la racine du projet :window.TL = { s1: { start: 0, title: 0.3, items: [1.2, 1.45, 1.7], exit: 3.6 }, s2: { start: 3.4, drawOn: 3.5, hook: 5.2, end: 8 }, };Dans
index.html, chargeztimeline.jsavec<script src="timeline.js"></script>avant tous les scripts de composition. -
Les paramètres de position GSAP doivent toujours être extraits de
TL(TL.s1.title,TL.s1.exit + 0.05pour les notations relatives) ; ne codez pas en dur les secondes dans les scènes. -
Les attributs
data-start/data-durationde l'enveloppe de la scène doivent correspondre aux limites des scènes dansTL. Pour un recalage temporel, modifiez d'abordtimeline.js, puis synchronisez ces deux attributs. -
Les sons et la narration sont placés avec
<audio data-start="…">sur les mêmes battements. Les temps de capture du review-loop sont également extraits deTL, donc l'image, le son et les vérifications bougent ensemble. -
Toutes les images sont exclusivement déterminées par le temps (voir section 0).
2. Easing
Les quatre courbes de l'original sont reconstruites précisément dans GSAP avec CustomEase. Chargez gsap@3/dist/CustomEase.min.js, puis enregistrez-le avec gsap.registerPlugin(CustomEase) :
CustomEase.create("enter", "0.16,1,0.3,1"); // easeOut
CustomEase.create("exit", "0.6,0,0.9,0.35"); // easeIn
CustomEase.create("move", "0.65,0,0.35,1"); // easeInOut
CustomEase.create("land", "0.55,0,0.2,1.12"); // overshoot
| Courbe | Utilisation | Équivalent intégré le plus proche |
|---|---|---|
enter = bezier(0.16, 1, 0.3, 1) | Entrée, révélation, tout ce qui « arrive » | expo.out (presque identique) |
exit = bezier(0.6, 0, 0.9, 0.35) | Sortie : rapide, sans traîner | Environ power3.in |
move = bezier(0.65, 0, 0.35, 1) | Mouvement entre deux états (retournement, ancrage, transformation) | power2.inOut (exactement identique) |
land = bezier(0.55, 0, 0.2, 1.12) | Valeur qui « se pose » (curseur qui s'arrête sur une position) | Pas de bon équivalent intégré, utilisez CustomEase |
ease: "none" (linéaire) est réservé aux mouvements continus : rotation, dérive, particules, aiguille des secondes.
Pour qu'une animation suive une autre valeur (ex. sous-titres suivant la position d'un curseur), utilisez un même tween pour piloter un objet proxy, puis dérivez dans onUpdate, sans lui donner une autre horloge indépendante.
3. Élasticité
L'original utilisait des ressorts physiques dans Remotion ; GSAP n'en a pas. Le tableau ci-dessous donne les approximations choisies pour cette version (Ajout de cette version, pas des chiffres de l'original) : après le rendu, vérifiez la sensation avec le review-loop :
| Sensation | Réglage GSAP | Utilisation |
|---|---|---|
| Pose par défaut | back.out(1.2), 0.6 s | Entrée UI générale |
| Lourd, stable | power3.out, 0.8–1.0 s | Grand panneau, retournement |
| Curseur s'arrête sur une cranture | back.out(1.7), 0.35 s | Contrôle qui saute à une position |
| Jaillissement | back.out(2.2), 0.45 s | Annotation, badge, point de succès |
| Accent élastique | elastic.out(1, 0.4), 0.9 s | Moment culminant, une seule fois par vidéo |
Les objets avec une sensation physique (UI, objets) utilisent l'élasticité ; le texte et les mouvements de type caméra utilisent des courbes de Bézier.
4. Rythme
- Décalage : mot anglais environ 0.09 s ; caractère chinois environ 0.04–0.05 s, mot chinois environ 0.09 s (partie chinoise ajoutée dans cette version) ; éléments de liste et étiquettes environ 0.2–0.25 s ; anneaux et points environ 0.06 s.
- Révélation de texte environ 0.8 s, avec un masque : conteneur externe
overflow: hidden, contenu interneyPercent: 100 → 0avec une légère rotation (rotation: 3 → 0). - La sortie dure environ la moitié de l'entrée (0.35–0.55 s contre 0.7–1.25 s), en utilisant la courbe
exit. - Les scènes doivent se chevaucher : la scène suivante commence à peindre avant que la précédente ne soit complètement partie (ex.
s2.drawOnà 4.02 s avants1.flipEndà 4.4 s). Un passage à blanc donne l'impression de « chargement ». - Frappe environ 0.035 s par caractère, curseur clignotant à environ 2.4 Hz au repos (utilisez
stepsousetsur la timeline, pas de timer). - Pause de lecture : chaque état à lire doit marquer un arrêt après s'être posé. Phrase courte au moins 1 s ; au-delà de trois mots, ajoutez environ 0.25 s par mot supplémentaire ; en chinois, ajoutez environ 0.25 s tous les 4 caractères supplémentaires (Ajout de cette version). La dernière phrase finale doit durer au moins 2 s. La version de 22 secondes de l'original existe parce que les caractères dans la version de 15 secondes défilaient trop vite : en cas de doute, posez plus longtemps, animez moins.
5. Polices de caractères
- Maximum trois familles : une police avec empattement pour l'affichage, une police sans empattement pour l'interface, une police à chasse fixe (pour étiquettes, prompts, chiffres).
- Anglais (original) : Instrument Serif / Inter / JetBrains Mono.
- Chinois traditionnel (Ajout de cette version) : Noto Serif TC / Noto Sans TC, avec JetBrains Mono pour les chiffres et les étiquettes. Les fichiers de polices se trouvent dans
assets/fonts/du projet, chargés avec@font-face; ne dépendez pas des polices système (qui diffèrent d'un ordinateur à l'autre).
- Le texte d'affichage anglais doit être grand (environ 138 px sur un canevas de 1080 de large), avec un crénage serré (
-0.02em),line-height: 1. - Texte d'affichage chinois (Ajout de cette version) : 1080 de large, environ 96–120 px, pas plus d'environ 12 caractères par ligne,
letter-spacing: 0à0.02em(pas de crénage négatif en chinois),line-height: 1.15–1.25. - Un point fort par ligne : en anglais, un mot en italique avec une couleur d'accentuation ; en chinois, pas de véritable italique, utilisez une couleur d'accentuation et un poids gras pour porter l'accent (Ajout de cette version).
- Étiquettes à chasse fixe : en majuscules,
letter-spacing: 0.2–0.24em, couleur atténuée. Ce ne sont que des décorations ; si le public doit absolument lire quelque chose, agrandissez-le. - Test mobile : à 360 px de large (taille réelle vue dans les flux sociaux), les informations clés doivent rester lisibles. Vérifiez avec une planche contact.
6. Palette de couleurs
- (Ajout de cette version) Toute la vidéo est définie par trois couleurs, comme un modèle de présentation déterminé par l'utilisateur : couleur de fond
bg, couleur principalefg(texte et traits), couleur d'accentuationaccent, écrites danstheme.jsondu projet, appliquées avec letheme.pydu skillmotion-explainer(ou sa version avec imagesmotion-explainer-images). La couleur d'accentuation est réservée aux « réponses, conclusions, chiffres clés, cartes de chapitre ». - Les nuances sont définies comme des variables CSS dans
:root(--bg,--ink,--muted,--accent…) ; aucune nouvelle valeur de couleur ne doit apparaître dans les scènes. - Une seule couleur d'accentuation, et elle a un sens : l'élément qui change, la réponse, le gagnant. Si tout est accentué, rien ne l'est.
- Les halos sont pilotés par l'état, pas par le temps (
glow = effort) : la lumière doit raconter une histoire.
7. Texture : rien n'est complètement immobile
- Grain de pellicule : une couche de filtre SVG
feTurbulence, opacité d'environ 0.09, change deseedtoutes les deux images (planifié avecsetsur la timeline, la graine étant calculée à partir du numéro d'image). - Vignettage + grille de points, dérive de quelques pixels par seconde : vignettage en
radial-gradient, grille avec un tween linéaire sur toute la vidéo. - « Tremblement de ligne » dessiné à la main (
feTurbulence+feDisplacementMap, change également de graine toutes les deux images) : utilisé pour les états d'ébauche, faiblement achevés ; fondu lorsque la qualité s'améliore. - Les éléments inactifs doivent respirer : horloge qui tourne, curseur qui clignote, rotation lente.
8. Continuité et transitions
- Mieux vaut faire durer un objet que de le couper brutalement. Dans l'original, la barre d'invite, les étincelles et le curseur traversent les scènes et changent de rôle : c'est la différence entre « conçu » et « assemblé ». Dans HyperFrames, les objets qui traversent les scènes sont placés dans la composition racine, pas à l'intérieur d'une scène.
- Chaque transition doit être amenée par un objet à l'écran (cinq points de résultats se fondent en un seul, qui devient un cercle lumineux). N'utilisez pas de transitions de balayage standard.
- Utilisez la vélocité : les traînées, les compressions sont dérivées de « la différence de valeur entre cette image et la précédente », ne les simulez pas artificiellement.
- Chaque vidéo a un moment culminant (cercle lumineux + impact). Construisez jusqu'à lui ; ne l'utilisez pas trop tôt.
9. Anti-patrons
- Tout ce qui fondu en même temps, ou tout ce qui a la même durée.
- Des objets qui démarrent et s'arrêtent avec un easing linéaire.
- Texte encore en mouvement alors qu'il devrait être lu.
- Plus d'un point focal dans une même image.
- Contenu à moins d'environ 60 px du bord de l'image (zone de sécurité), sauf recadrage intentionnel.
- La première image est vide ou entièrement noire : lors de la lecture automatique en muet sur les réseaux sociaux, la première image est la vignette.
- (Ajout de cette version) Contrôle de la lecture audio/vidéo ou de l'affichage des clips dans un script, utilisation d'animations CSS, utilisation de
Math.random()sans graine (voir section 0).
Flux de travail
- Écrivez d'abord les battements dans
timeline.js(storyboard avec des chiffres), confirmez le rythme avec l'utilisateur avant de commencer. - Initialisez le projet avec
hyperframes_initde kinocut ; chaque scène est une composition danscompositions/, les composants partagés et les objets transversaux sont placés dansindex.html. - Après chaque modification significative, exécutez le skill
review-loop. - Traitez le son une fois les timings images verrouillés : sons et musique avec
<audio data-start>sur les battements deTL. L'accent et l'émotion de la narration en chinois sont laissés à l'appréciation de l'utilisateur à l'oreille ; ne les remplacez pas par des scores ASR ou de similarité (Ajout de cette version).