Installation du plugin : Avant les commandes de configuration ou de fraîcheur, suivez les règles d'exécution du plugin lorsque cette compétence se trouve à l'intérieur d'un plugin HyperFrames. Les installations autonomes conservent les instructions de mise à jour ci-dessous.
Cœur HyperFrames
Pièges à éviter par l'agent (lire en premier) :
- Centrer avec flex/
inset, pas avectransform: translate(-50%,-50%)CSS sur un nœud que vous animez ensuite avec GSAPx/y. Lint :gsap_css_transform_conflict. UtilisezfromToouxPercent/yPercent. - N'ajoutez pas de
tl.set(..., {visibility:"hidden"})en sortie de scène. Le runtime masque déjà les clips temporisés. Les fondus d'opacité sur les nœuds internes (ouopacitysur.clip) suffisent. Les arrêts brusques de légendes sont une règle différente. window.__timelines["id"]doit correspondre à la racinedata-composition-id.- Après
render, lisez la deuxième ligne du résumé :beginframevsscreenshot, mode GPU, timings d'étape.screenshot+software gpusur Linux est le chemin lent.
HyperFrames génère une vidéo à partir de HTML. Une composition est un fichier HTML dont le DOM déclare le timing avec des attributs data-*, dont le runtime d'animation est accessible (seekable), et dont la lecture multimédia est gérée par le framework.
Cette compétence est le contrat technique — comment construire un projet hyperframes. Le corps ci-dessous est le guide de construction ; les détails par sujet se trouvent dans references/ (index ci-dessous), à lire à la demande. Les documents de processus (brief, storyboard, revue, production, dispatch, frame-worker) se trouvent dans /hyperframes → references/. Les autres préoccupations se trouvent dans les compétences de domaine sœurs — hyperframes-animation, hyperframes-creative, media-use, hyperframes-cli, hyperframes-registry. La carte des capacités dans /hyperframes indique ce que couvre chaque compétence.
Références
| Fichier | Lisez-le pour… |
|---|---|
references/minimal-composition.md | partir du plus petit squelette de composition rendable |
references/composition-patterns.md | choisir monolithique vs modulaire ; structurer un index.html modulaire ; choisir un archétype de sous-comp |
references/data-attributes.md | rechercher tout data-* (racine / clip / hôte sous-comp / alias hérités) ; utiliser class="clip" |
references/tracks-and-clips.md | comprendre ce que data-track-index contrôle (et ne contrôle pas), z-index, temporiser un clip par rapport à un autre ; lister chaque piste et clip avec npx hyperframes timeline |
references/creator-editing-recipes.md | copier des recettes de coupe/recadrage/réorganisation/re-temporisation/gel/caméra/masque/fondu enchaîné/audio fiables et leurs limites |
references/sub-compositions.md | câbler une sous-composition (attributs hôte, <template>, variables par instance) et animer à l'intérieur |
references/variables-and-media.md | déclarer des variables ; placer <video>/<audio>, régler le volume, rogner |
references/determinism-rules.md | construire une timeline accessible (seekable) ; interdictions de déterminisme ; mise en page / ajustement du texte |
references/full-screen-motion.md | créer un mouvement plein écran avec arrière-plans partagés |
references/tailwind.md | travailler dans un projet Tailwind v4 (init --tailwind ; le contrat d'exécution diffère du v3 de Studio) |
Pour les spécificités du runtime d'animation (API GSAP, Lottie, Three.js, etc.), allez dans hyperframes-animation → adapters/<runtime>.md.
Construction d'une composition
Deux formes racines (non interchangeables)
- Autonome (
index.htmlde premier niveau) :<div data-composition-id="…">se trouve directement dans<body>, pas de wrapper<template>. Envelopper une racine autonome cache tout le contenu etlintle rejette (standalone_composition_wrapped_in_template, erreur). - Sous-composition (chargée via
data-composition-src) : enveloppez la racine dans<template>. C'est la forme à écrire : le chargeur accepte aussi un document complet et se rabat sur son<body>, mais la forme template est celle que les exemples et les outils supposent.
⚠ Règle de transport : pour une sous-composition template l'assembleur supprime les propres
<head><style>/<script>du fichier (packages/core/src/compiler/compositionAssembly.ts, le portillonhasTemplate), donc placez<style>/<script>à l'intérieur du template.<link>est remonté dans les deux cas. ⚠ Convention d'ID hôte : donnez à l'emplacement hôte, au template interne et à la cléwindow.__timelines["<id>"]le même id. Un ID local différent est supporté (l'assembleur se rabat sur la première racine du fichier) mais la non-concordance est silencieuse, donc faites-les correspondre sauf si vous avez une raison de ne pas le faire.
Forme du fichier, câblage hôte et liste de contrôle pré-rendu → references/sub-compositions.md.
La racine doit être dimensionnée (bug de mise en page silencieux)
La racine autonome utilise width/height: 100%. La taille du canevas est data-width/data-height. Le runtime applique ces pixels à la racine de composition. Ne codez pas en dur 1920px/1080px sur #root. Squelette → references/minimal-composition.md.
Une timeline en pause
Chaque composition enregistre exactement une gsap.timeline({ paused: true }) à window.__timelines["<id>"] (clé = racine data-composition-id). La construire dans un callback asynchrone (document.fonts.ready) est supporté ; ce qui compte c'est que vous enregistriez seulement après la fin de la construction. La durée du rendu est celle de la racine data-duration, pas la longueur de la timeline : une timeline qui la dépasse est coupée, et une qui se termine tôt conserve sa dernière image. Omettez la data-duration racine et la durée est déduite à la place (timeline, fenêtre média ou adaptateur). Vous n'avez pas besoin de window.__timelines = window.__timelines || {} : le runtime crée le registre avant que vos scripts en ligne ne s'exécutent, et lint ne le demande plus. N'imbriquez pas manuellement de sous-timelines dans l'hôte ; le runtime auto-imbrique les timelines enfants enregistrées. Contrat complet (y compris les runtimes non-GSAP) → references/determinism-rules.md + hyperframes-animation/adapters/.
Pièges lint de premier passage (un échec de première construction garanti)
Règles que lint attrape, mais seulement après coup. Écrivez-les correctement du premier coup :
- Ne jumelez jamais un
transformCSS initial avec un tween GSAP sur la même propriété — la valeur CSS et le début du tween se battent etlintle rejette avecgsap_css_transform_conflict. Définissez l'état initial à l'intérieur du tween avecgsap.fromTo(el, { x: -40 }, { x: 0 })au lieu d'untransform: translateX(-40px)CSS. - Ne mettez jamais
crossoriginsur<video>/<audio>.lintle rejette inconditionnellement avecmedia_crossorigin_breaks_preview(erreur), y compris pour la lecture canvas/WebGL/WebAudio. Il n'y a pas de suppression. - Ne donnez jamais à un
<video data-start>un ancêtre qui porte aussidata-start.lintle rejette avecvideo_nested_in_timed_element(erreur). Chronométrez le wrapper ou la vidéo, pas les deux. - Chaque
<audio>a besoin d'unid.lintle rejette avecmedia_missing_id, et un<audio>sans id n'est jamais pris en charge par le mixeur, donc le rendu est silencieux. - Ne tweenez jamais un
.clipavecautoAlphaouvisibility—lintle rejette avecgsap_animates_clip_element. Animez un enfant à la place. - Une
font-familyCSS nommée a besoin d'un@font-facedans le fichier vers un fichier local livré, oulintdéclenchefont_family_without_font_face. - La
#rootd'une sous-composition utilisewidth/height: 100%(ouinset: 0), pas du1920px/1080pxen dur. La taille du canevas estdata-width/data-height.
Une erreur de lint désactive aussi les audits de mise en page et de contraste : check rapporte alors 0 sample(s) et 0/0 text checks, ce qui ressemble à un fichier propre mais signifie que rien n'a tourné. Supprimez les erreurs lint avant de faire confiance à ces chiffres.
Règles non négociables (bugs silencieux que les portails automatisés peuvent manquer)
Surfacées ici ; justification complète dans la référence liée. Ne violez pas :
- Pas d'horloges en temps de rendu /
Math.randomnon ensemencé / réseau / état d'entrée ; pas derepeat: -1(utilisez un nombre fini). →determinism-rules.md - Ne tweenez jamais
display,visibilityouautoAlphasur un élément.clip. Le framework possède la visibilité des clips, etlintle rejette (gsap_animates_clip_element). Animez un enfant à la place. →determinism-rules.md - Pas de
<br>dans le texte du corps ; les éléments transformés doivent être de niveau bloc + dimensionnés ; les décorations absolues pulsantes ont besoin d'un dégagement maximal. →determinism-rules.md <video>/<audio>sont trouvés par une requête plate du document, donc le framework les cherche et les décode à n'importe quelle profondeur d'imbrication (y compris à l'intérieur d'un<template>ou wrapper de sous-comp). Une limite stricte :linterre si un<video data-start>se trouve à l'intérieur d'un autre élément simple qui a aussidata-start, et l'échec est réel (mauvaises images source, puis le clip disparaît en milieu de créneau), donc mettez le timing sur le wrapper ou sur la vidéo, jamais les deux. Les hôtes de sous-composition sont exemptés : les médias à l'intérieur d'une sous-composition sont rendus correctement. L'autre mise en garde concerne les timelines, pas le placement : une timeline de sous-comp ne peut pas animer les éléments racine de l'hôte. →variables-and-media.md- Gardez chaque
idunique sur la page assemblée (préfixez les id de sous-comp avec l'id de composition,#<id>-hero) afin que vos propres appels CSS#idetgetElementByIdrésolvent correctement. L'injection d'image n'en dépend plus : le compilateur appose undata-hf-render-idunique au document sur chaquevideo[src]/audio[src]/img[src]. Les médias qui utilisent des enfants<source>au lieu d'un attributsrcne sont pas marqués, donc les id uniques comptent toujours là. →composition-patterns.md - Un remplissage plein écran sur la racine de la composition est acceptable sur un rendu normal. Il est supprimé uniquement sur le chemin composite en couches (contenu HDR, ou composition utilisant des transitions shader), où le moteur force chaque racine de composition à être transparente pour que la couche en dessous apparaisse. Si votre composition utilise des transitions shader ou des médias HDR, mettez le remplissage sur un enfant à fond perdu (
position:absolute; inset:0). →composition-patterns.md
Édition de compositions existantes
- Lisez les fichiers d'abord. Préservez le timing, les pistes, les IDs, les variables, les chemins médias non liés.
- Pour savoir ce qui se trouve sur la timeline d'un projet (pistes, clips, débuts, fins, ce qui est lu), exécutez
npx hyperframes timeline [--json]au lieu de lireindex.htmlet chaque fichier de sous-composition. - Faites correspondre les IDs de composition et les clés de timeline existants.
- Ajout d'un clip : définissez son
data-start/data-durationintentionnellement par rapport aux clips environnants.data-track-indexest une voie d'affichage Studio, pas une contrainte de timing, donc elle n'a pas besoin d'être libre. - Un clip qui se termine après la
data-durationracine est coupé : étendez ladata-durationracine jusqu'à la fin du clip dans la même modification (lintprévientclip_ends_past_root_duration). data-hiddensur n'importe quel élément de composition le masque à la fois dans l'aperçu ET le rendu, remplaçant sa fenêtre temporelle ; il est non destructif/réversible et basculé par l'icône d'œil de la timeline Studio.- Ajout d'une sous-composition : vérifiez sa
data-composition-idinterne avant de câbler l'hôte.
Validation
Utilisez hyperframes-cli pour les détails des commandes
-
npx hyperframes checkpasse (0 résultats sur lint, runtime, mise en page, mouvement et contraste) - Projets avec sous-compositions :
npx hyperframes snapshot --at <midpoints>et inspectez chaque image -
npx hyperframes preview --backgroundpour la révision (l'utilisateur peut éditer n'importe quoi dans la timeline Studio, et le serveur survit à la commande invocatrice) -
npx hyperframes renderseulement après approbation de l'utilisateur