HyperFrames

Compétences de composition vidéo HTML avec animations GSAP pour Minis.

Qu'est-ce que HyperFrames ?

HyperFrames est une compétence avancée pour la création de compositions vidéo à partir de HTML, CSS et animations GSAP. Conçue pour les développeurs et créateurs de contenu, elle permet de construire des séquences vidéo complexes en définissant une structure de compositions, des sous-compositions, et des transitions temporelles via des attributs `data-*`. La compétence impose une approche rigoureuse : définir d'abord une identité visuelle (via un fichier DESIGN.md), construire la mise en page finale en CSS avant d'ajouter les animations, et respecter des règles strictes pour éviter les chevauchements involontaires. Elle prend en charge les clips vidéo, audio, images et divs, avec un système de pistes (`data-track-index`) pour la synchronisation. L'outil est pensé pour fonctionner au sein de l'écosystème Minis, avec des scripts de vérification d'environnement et d'installation. Utile pour produire des vidéos programmatiques, des présentations animées ou des habillages dynamiques, HyperFrames offre un contrôle fin sur le rendu final.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add OpenMinis/MinisSkills

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

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

Documentation

Que fait HyperFrames ?

Première fois ? Lancez la vérification d'environnement avant de commencer :

python3 /var/minis/skills/hyperframes-cli/scripts/check-env.py

Ceci vérifie que minis-browser-use, ffmpeg, et les compétences requises sont installées. Si la compétence hyperframes-cli est manquante, installez-la :

python3 /var/minis/skills/hyperframes-cli/scripts/install-skill.py \
  hyperframes-cli --repo heygen-com/hyperframes --subdir skills

Le HTML est la source de vérité pour la vidéo. Une composition est un fichier HTML avec des attributs data-* pour le timing, une timeline GSAP pour l'animation, et du CSS pour l'apparence. Le framework gère la visibilité des clips, la lecture multimédia et la synchronisation de la timeline.

Approche

Avant d'écrire du HTML, réfléchissez à un niveau élevé :

  1. Quoi — quelle expérience le spectateur doit-il vivre ? Identifiez l'arc narratif, les moments clés et les temps émotionnels.
  2. Structure — combien de compositions, lesquelles sont des sous-compositions ou intégrées, quelles pistes transportent quoi (vidéo, audio, superpositions, sous-titres).
  3. Timing — quels clips déterminent la durée, où se situent les transitions, quel est le rythme.
  4. Disposition — construisez d'abord l'état final. Voir "Disposition avant Animation" ci-dessous.
  5. Animer — ajoutez ensuite du mouvement en utilisant les règles ci-dessous.

Pour les petites modifications (corriger une couleur, ajuster un timing, ajouter un élément), passez directement aux règles.

Porte d'Identité Visuelle

Vérifiez dans cet ordre :

  1. Un fichier DESIGN.md existe-t-il dans le projet ? → Lisez-le. Utilisez ses couleurs, polices, règles de mouvement et contraintes "À ne PAS faire".
  2. Un fichier visual-style.md existe-t-il ? → Lisez-le. Appliquez son style_prompt_full et ses champs structurés. (Note : visual-style.md est un fichier spécifique au projet. visual-styles.md est la bibliothèque de styles avec 8 préréglages nommés — fichiers différents.)
  3. L'utilisateur a nommé un style (ex : "Swiss Pulse", "dark and techy", "luxury brand") ? → Lisez visual-styles.md pour les 8 préréglages nommés. Générez un DESIGN.md minimal avec : ## Style Prompt (un paragraphe), ## Couleurs (3-5 valeurs hexadécimales avec rôles), ## Typographie (1-2 familles de polices), ## À ne PAS faire (3-5 anti-patrons).
  4. Aucun des cas ci-dessus ? → Posez 3 questions avant d'écrire du HTML :
    • Quelle est l'ambiance ? (explosive / cinématographique / fluide / technique / chaotique / chaleureuse)
    • Fond clair ou sombre ?
    • Y a-t-il des couleurs de marque, polices ou références visuelles spécifiques ? Générez ensuite un DESIGN.md minimal à partir des réponses.

Chaque composition doit faire remonter sa palette et sa typographie à un DESIGN.md, un visual-style.md ou une direction utilisateur explicite. Si vous utilisez #333, #3b82f6, ou Roboto — vous avez sauté cette étape.

Pour les valeurs par défaut du mouvement, le dimensionnement, les motifs d'entrée et l'assouplissement — suivez house-style.md. Le style maison gère COMMENT les choses bougent. Le DESIGN.md gère À QUOI les choses ressemblent.

Disposition avant Animation

Positionnez chaque élément là où il doit être à son moment le plus visible — l'image où il est complètement entré, correctement placé, et pas encore en sortie. Écrivez ceci en HTML+CSS statique d'abord. Pas encore de GSAP.

Pourquoi c'est important : Si vous positionnez les éléments à leur état de départ animé (hors écran, échelle 0, opacité 0) et les animez jusqu'à où vous pensez qu'ils devraient arriver, vous devinez la disposition finale. Les chevauchements sont invisibles jusqu'au rendu de la vidéo. En construisant l'état final d'abord, vous pouvez voir et corriger les problèmes de disposition avant d'ajouter tout mouvement.

Le processus

  1. Identifiez l'image principale pour chaque scène — le moment où le plus d'éléments sont simultanément visibles. C'est la disposition que vous construisez.
  2. Écrivez le CSS statique pour cette image. Le conteneur .scene-content DOIT remplir toute la scène en utilisant width: 100%; height: 100%; padding: Npx; avec display: flex; flex-direction: column; gap: Npx; box-sizing: border-box. Utilisez le padding pour pousser le contenu vers l'intérieur — JAMAIS position: absolute; top: Npx sur un conteneur de contenu. Les conteneurs de contenu en position absolue débordent lorsque le contenu est plus haut que l'espace restant. Réservez position: absolute uniquement pour les éléments décoratifs.
  3. Ajoutez les entrées avec gsap.from() — animez DEPUIS hors écran/invisible VERS la position CSS. La position CSS est la vérité de base ; l'interpolation décrit le chemin pour y arriver.
  4. Ajoutez les sorties avec gsap.to() — animez VERS hors écran/invisible DEPUIS la position CSS.

Exemple

/* scene-content remplit la scène, le padding positionne le contenu */
.scene-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 120px 160px;
  gap: 24px;
  box-sizing: border-box;
}
.title {
  font-size: 120px;
}
.subtitle {
  font-size: 42px;
}
/* Le conteneur remplit toute taille de scène (1920x1080, 1080x1920, etc.).
   Le padding positionne le contenu. Flex + gap gère l'espacement. */

FAUX — dimensions codées en dur et positionnement absolu :

.scene-content {
  position: absolute;
  top: 200px;
  left: 160px;
  width: 1920px;
  height: 1080px;
  display: flex; /* ... */
}
// Étape 3 : Animez VERS ces positions
tl.from(".title", { y: 60, opacity: 0, duration: 0.6, ease: "power3.out" }, 0);
tl.from(".subtitle", { y: 40, opacity: 0, duration: 0.5, ease: "power3.out" }, 0.2);
tl.from(".logo", { scale: 0.8, opacity: 0, duration: 0.4, ease: "power2.out" }, 0.3);

// Étape 4 : Animez HORS de ces positions
tl.to(".title", { y: -40, opacity: 0, duration: 0.4, ease: "power2.in" }, 3);
tl.to(".subtitle", { y: -30, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.1);
tl.to(".logo", { scale: 0.9, opacity: 0, duration: 0.3, ease: "power2.in" }, 3.2);

Compositions multi-scènes : un conteneur par scène

Lorsqu'une composition a plusieurs scènes qui apparaissent séquentiellement (A sort, puis B entre), ne mettez jamais tous les éléments de toutes les scènes dans un seul conteneur flex partagé. Même si chaque élément commence avec opacity: 0, flex alloue toujours de la hauteur pour chaque enfant. Avec 5 scènes de contenu dans un seul conteneur, la hauteur totale du conteneur dépasse largement la hauteur de la scène — justify-content: center centre alors le contenu par rapport à ce conteneur surdimensionné, poussant le contenu visible hors du cadre de capture.

FAUX — toutes les scènes dans un seul conteneur flex :

<div class="scene-content"> <!-- flex column, height:100% -->
  <!-- Éléments de la scène A -->
  <div id="title-a" style="opacity:0">Titre A</div>
  <div id="body-a"  style="opacity:0">Corps A</div>
  <!-- Éléments de la scène B — prennent aussi de la hauteur flex même quand invisibles -->
  <div id="title-b" style="opacity:0">Titre B</div>
  <div id="body-b"  style="opacity:0">Corps B</div>
  <!-- Scène C ... -->
</div>

CORRECT — chaque scène est sa propre couche absolue :

<!-- Scène A -->
<div class="scene" id="scene-a">
  <div id="title-a" style="opacity:0">Titre A</div>
  <div id="body-a"  style="opacity:0">Corps A</div>
</div>
<!-- Scène B — aucun impact en hauteur sur la scène A -->
<div class="scene" id="scene-b">
  <div id="title-b" style="opacity:0">Titre B</div>
  <div id="body-b"  style="opacity:0">Corps B</div>
</div>
/* Chaque scène remplit la scène indépendamment */
.scene {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 80px 120px;
  box-sizing: border-box;
  z-index: 2;
  gap: 24px;
}

C'est le seul motif correct pour des scènes séquentielles. Le position: absolute; inset: 0 sur chaque conteneur de scène n'entre PAS en conflit avec la directive "Disposition avant Animation" — cette directive interdit le positionnement absolu des éléments de contenu (titres, cartes, statistiques) avec des décalages en pixels codés en dur. Les conteneurs de scène qui remplissent toute la scène via inset: 0 sont corrects et requis.

Quand les éléments partagent l'espace dans le temps

Si l'élément A sort avant que l'élément B n'entre dans la même zone, les deux doivent avoir des positions CSS correctes pour leurs images principales respectives. L'ordre de la timeline garantit qu'ils ne coexistent jamais visuellement — mais si vous sautez l'étape de disposition, vous ne détecterez pas le cas où ils se chevauchent accidentellement à cause d'une erreur de timing.

Ce qui compte comme chevauchement intentionnel

Les effets en couches (lueur derrière le texte, éléments d'ombre, motifs d'arrière-plan) et les conceptions empilées en Z (piles de cartes, couches de profondeur) sont intentionnels. L'étape de disposition consiste à détecter les chevauchements non intentionnels — deux titres atterrissant l'un sur l'autre, une statistique couvrant une étiquette, un contenu débordant du cadre.

Attributs de Données

Tous les Clips

AttributRequisValeurs
idOuiIdentifiant unique
data-startOuiSecondes ou référence d'ID de clip ("el-1", "intro + 2")
data-durationRequis pour img/div/compositionsSecondes. Vidéo/audio par défaut : durée du média.
data-track-indexOuiEntier. Les clips d'une même piste ne peuvent pas se chevaucher.
data-media-startNonDécalage de coupe dans la source (secondes)
data-volumeNon0-1 (par défaut 1)

data-track-index n'affecte pas la superposition visuelle — utilisez le CSS z-index.

Clips de Composition

AttributRequisValeurs
data-composition-idOuiID de composition unique
data-startOuiHeure de début (composition racine : utilisez "0")
data-durationOuiPrioritaire sur la durée de la timeline GSAP
data-width / data-heightOuiDimensions en pixels (1920x1080 ou 1080x1920)
data-composition-srcNonChemin vers un fichier HTML externe

Structure de Composition

Les sous-compositions chargées via data-composition-src utilisent un wrapper <template>. Les compositions autonomes (le fichier index.html principal) n'utilisent PAS <template> — elles placent la div data-composition-id directement dans <body>. Utiliser <template> sur un fichier autonome cache tout le contenu au navigateur et casse le rendu.

Structure de sous-composition :

<template id="my-comp-template">
  <div data-composition-id="my-comp" data-width="1920" data-height="1080">
    <!-- contenu -->
    <style>
      [data-composition-id="my-comp"] {
        /* styles limités à la portée */
      }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
    <script>
      window.__timelines = window.__timelines || {};
      const tl =

Skills associés