Typographie Cinétique
Créez des vidéos où les mots eux-mêmes sont l'image. Une phrase atterrit, remplit le cadre, est percutée et remplacée par la suivante, en rythme. Le résultat doit être audacieux, rapide et musical, comme une affiche qui bouge.
Options
| Option | Par défaut | Remarques |
|---|---|---|
| format | portrait 1080×1920 | ou paysage 1920×1080, carré 1080×1080 |
| durée | 10–20 s | adapter à la voix off ou à la section musicale |
| ton | percutant | calme (diapositives et fondus de 0,4 s, moins de retournements), percutant (par défaut), chaotique (tout en majuscules, claquements, secousses, un retournement toutes les deux phrases) |
| rythme | tempo fixe | ou temps des mots de la voix off, ou beats musicaux |
Brief (répondre avant de planifier)
- Quelle est l'unique phrase que le spectateur doit retenir ?
- Découpez le script en phrases de 1–4 mots ; marquez un mot héroïque par phrase.
- Où se situe le pic d'énergie (la phrase qui subit le retournement de couleur) ?
- Quelle est la composition finale (titre, appel à l'action, pseudo) ?
Fiche de lecture (à écrire avec la liste des temps)
Pour chaque temps, écrivez la seule chose que le spectateur doit comprendre ("le robot ne peut pas voler", "le cache a manqué") et combien de temps elle reste lisible. Une lecture à la fois. Planchers de texte : un mot reste au moins 0,8 s, une phrase environ 0,3 s par mot une fois entièrement affichée. Si le texte ne tient pas dans le temps, coupez des mots plutôt que d'accélérer.
Discipline de mouvement
- Le mouvement est causal : chaque déplacement a une raison à l'écran (un clic, une chute, un paquet qui arrive), et le mouvement suivant en découle.
- Choisissez une direction principale de déplacement pour toute la vidéo et tenez-vous-y. Utilisez les autres directions pour le sens : vers le haut pour le succès ou la conclusion, un zoom arrière pour "voici l'image d'ensemble".
- La sortie d'une scène prépare l'entrée de la suivante : même axe, même direction, vitesse similaire. Faites passer un objet d'une scène à l'autre au lieu d'utiliser un fondu enchaîné.
- Pas de mouvement de remplissage inactif (flottement, respiration, balancement) sur les diagrammes, graphiques ou textes. Si rien ne doit bouger, restez immobile ; une seule dérive de caméra délibérée suffit.
- Easing : ease-out lisse pour les entrées (
power2.outàpower4.out), ease-in plus rapide pour les sorties (environ 75 % du temps d'entrée). Entrées au maximum 0,8 s. Décalage total pour un groupe au maximum 0,5 s. Overshoot (back.out) uniquement pour les petits pops ; pas d'elastic ou de bounce. - Une seule chose bouge à la fois quand c'est important ; l'œil ne peut en suivre qu'une.
- Ajoutez un temps mort de 0,3–0,75 s juste avant le moment clé.
Règles de style (toujours)
Elles définissent ce style ; conservez-les quelles que soient les couleurs ou les mots.
- Le texte occupe 50–80 % de la largeur du cadre, car un petit texte est perçu comme des sous-titres, pas comme un visuel.
- Une idée à la fois à l'écran : 1–4 mots, au maximum 3 lignes. Tout le reste a disparu.
- Chaque mot arrive avec un mouvement (claquer, glisser, étirer, révéler par masque, retourner). Rien ne disparaît simplement par fondu.
- Les changements tombent en rythme : un nouveau mot ou un nouveau mouvement toutes les 0,25–0,7 s, et les mots clés sur le temps ou la syllabe accentuée.
- Le contraste est extrême : presque noir sur blanc cassé ou l'inverse, plus une couleur d'accent pour le mot clé uniquement.
- Chaque phrase a un mot héroïque : le plus grand, de couleur d'accent, ou qui bouge différemment des autres.
Valeurs par défaut (à modifier librement)
Polices, couleurs, mots, timing et fond. Si l'utilisateur donne des polices ou couleurs de marque, les siennes priment. Ordre de priorité : marque ou spécification de l'utilisateur, puis demande explicite, puis ces valeurs par défaut.
- Fond
#111111, texte#f4f1ea, accent#ff4d2e. Alternez entre clair sur foncé ou foncé sur clair par phrase pour l'énergie. - Police d'affichage : une police condensée grasse (Anton, Bebas Neue ou Archivo Black), tout en majuscules pour les mots héroïques. Police de support : une police sans empattement grasse (Inter 800) pour les petits mots de liaison.
- Taille : mots héroïques 180–320 px en 9:16 ; petits mots 60–90 px.
Installation (une fois)
node -v # nécessite 22+
ffmpeg -version
npx hyperframes init ma-video --non-interactive --resolution portrait && cd ma-video # landscape pour 16:9
Dans un dossier vide existant, utilisez npx hyperframes init . --non-interactive --resolution portrait, puis remplacez le fichier index.html généré par le modèle ci-dessous.
Décider avant de construire
Énoncez ces éléments à l'utilisateur en une ligne avant d'écrire du code.
- Format : 9:16 (1080×1920) ou 16:9 (1920×1080). Par défaut 9:16.
- Mots et timing : découpez le script en phrases de 1–4 mots. Avec une voix off, prenez les temps à partir de ses horodatages de mots (
npx hyperframes transcribe voix.wav). Sans voix off, donnez à chaque phrase 0,6–1,4 s, et aux mots héroïques plus de temps. - Source du rythme : voix (tomber sur les syllabes accentuées), musique (tomber sur les temps ;
npx hyperframes beats musique.mp3), ou un tempo fixe (par exemple 120 BPM = un temps toutes les 0,5 s). - Mot héroïque par phrase et quel mouvement il reçoit.
| Besoin | HyperFrames + GSAP (par défaut) | Remotion |
|---|---|---|
| Mouvements de mots et lettres, masques, étirements | oui | oui |
| Timing à partir de données vocales ou de beats | oui (étiquettes) | oui (images) |
| Fonctionne uniquement avec Node et FFmpeg | oui | oui |
| Licence | gratuite | gratuite jusqu'à 3 personnes, payante au-dessus |
Vocabulaire des mouvements
| Mouvement | Comment (GSAP) | Utilisation pour |
|---|---|---|
| Slam | from {scale: 2.6, opacity: 0}, expo.out, 0,22 s, plus une secousse d'écran de 6 px pendant 0,1 s | mots héroïques |
| Empilement glissé | lignes from {yPercent: 110} dans des masques overflow:hidden, décalage 0,06 s, power4.out 0,35 s | listes, phrases de deux lignes |
| Étirement | scaleY: 1.6 → 1, transformOrigin: bottom, back.out(3) 0,3 s | emphase, verbes |
| Cascade de lettres | lettres from {y: -120, rotation: -20, opacity: 0}, décalage 0,025 s, back.out(2) | noms, titres |
| Échange par retournement | ancien mot rotationX: 90 sortie (0,12 s), nouveau mot rotationX: -90 → 0 entrée (0,18 s) | X devient Y |
| Séparation | moitiés du mot glissent x: ±140 pour révéler un petit mot entre elles | contrastes |
| Sortie | yPercent: -110 ou scale: 0.7, opacity: 0, 0,15 s, power2.in | chaque phrase qui part |
Les sorties sont rapides (0,12–0,18 s) et les entrées sont plus vives que vous ne le pensez (0,18–0,35 s). Gardez chaque phrase au moins 0,35 s après son atterrissage, pour qu'elle soit lisible.
Rendez-le accrocheur
- Remplissez le cadre. Dimensionnez les mots à la largeur du cadre, pas à une taille de police. Les polices condensées à 250+ px sont le look recherché.
- Retournements de couleur : le fond alterne entre sombre et clair (ou vers la couleur d'accent) sur 2–3 phrases clés, comme une coupe franche sur le temps.
- Texture et profondeur : une superposition de grain subtile, une ombre douce ou un double décalé derrière les mots héroïques (couleur d'accent, décalage de 10–14 px), et parfois un mot géant atténué en fond.
- Énergie de la caméra : un lent décalage d'échelle de 2–4 % sur toute la scène, un zoom avant (échelle 1,06 pendant 0,1 s) sur les impacts héroïques, et une secousse de 6–10 px sur les slams.
- Formes avec les mots : barres de soulignement qui se tracent, cercles qui apparaissent derrière un mot, flèches. Couleur d'accent, plates.
- Terminez sur une composition : le titre ou l'appel à l'action, entièrement composé, maintenu 1–1,5 s, correspondant au cadre d'ouverture pour permettre une boucle.
- Barrière de qualité : si une capture d'écran montre un petit texte centré sur un fond uni, ce n'est pas terminé.
Construire : modèle
<!doctype html><html><head><meta charset="UTF-8">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Anton&family=Inter:wght@800&display=swap">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/gsap.min.js"></script>
<style>
html,body{margin:0;width:1080px;height:1920px;overflow:hidden;background:#111}
#root{width:100%;height:100%;position:relative;overflow:hidden}
#stage{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.phrase{position:absolute;left:60px;right:120px;top:270px;bottom:670px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:0}
.line{overflow:hidden;line-height:.92;padding:0 8px}
.w{display:inline-block;font-family:Anton,sans-serif;text-transform:uppercase;color:#f4f1ea;white-space:nowrap}
.hero{color:#ff4d2e}
.flip .w{color:#fff}.flip .hero{color:#111}
.small{font-family:Inter,system-ui,sans-serif;font-weight:800;text-transform:none}
#bg{position:absolute;inset:0;background:#111}
</style></head>
<body><div id="root" data-composition-id="main" data-start="0" data-duration="8" data-width="1080" data-height="1920">
<div id="bg"></div><div id="stage"></div></div>
<script>
// [temps, lignes, nomMouvement, indexMotHeroique, retournerFond?] -- éditez cette liste ; temps en secondes
const PHRASES = [
[0.2, ["MOTS"], "slam", 0],
[1.0, ["peuvent", "BOUGER"], "stack", 1],
[2.0, ["COMME", "LA MUSIQUE"], "stretch", 1, true],
[3.2, ["une", "idée"], "stack", 1],
[4.2, ["À LA", "FOIS"], "slam", 1],
[5.4, ["TYPE", "CINÉTIQUE"], "cascade", 1],
];
const FIN = 8, L = 1080 - 180;
// mesurez le texte uniquement après le chargement des polices web, puis construisez et enregistrez la timeline
document.fonts.ready.then(() => {
const tl = gsap.timeline({ paused: true });
const stage = document.getElementById("stage");
PHRASES.forEach(([t, lignes, move, hero, flip], i) => {
const p = document.createElement("div"); p.className = "phrase" + (flip ? " flip" : ""); stage.appendChild(p);
const mots = lignes.map((txt, k) => {
const line = document.createElement("div"); line.className = "line";
const w = document.createElement("span"); w.className = "w" + (k === hero ? " hero" : "") + (txt === txt.toLowerCase() && k !== hero ? " small" : "");
w.textContent = txt; line.appendChild(w); p.appendChild(line);
w.style.fontSize = "100px"; const fit = Math.min(420, (100 * L) / w.getBoundingClientRect().width); // remplir la largeur
w.style.fontSize = (w.classList.contains("small") ? Math.min(fit, 110) : fit) + "px";
return w;
});
gsap.set(p, { autoAlpha: 0 });
tl.set(p, { autoAlpha: 1 }, t);
if (move === "slam") tl.from(mots, { scale: 2.6, opacity: 0, duration: 0.22, ease: "expo.out", stagger: 0.08 }, t)
.fromTo("#stage", { x: -10 }, { x: 10, duration: 0.04, yoyo: true, repeat: 3, ease: "none" }, t + 0.18).set("#stage", { x: 0 }, t + 0.34);
if (move === "stack") tl.from(mots, { yPercent: 110, duration: 0.35, ease: "power4.out", stagger: 0.07 }, t);
if (move === "stretch") tl.from(mots, { scaleY: 1.7, opacity: 0, transformOrigin: "50% 100%", duration: 0.3, ease: "back.out(3)", stagger: 0.08 }, t);
if (move === "cascade") mots.forEach((w, k) => {
const lettres = Array.from(w.textContent); w.textContent = "";
lettres.forEach((c) => { const l = document.createElement("span"); l.style.display = "inline-block"; l.textContent = c; w.appendChild(l); });
tl.from(w.children, { y: -140, rotation: -20, opacity: 0, duration: 0.4, ease: "back.out(2)", stagger: 0.03 }, t + k * 0.15); });
const prochaine = PHRASES[i + 1] ? PHRASES[i + 1][0] : null;
if (flip) tl.set("#bg", { background: "#ff4d2e" }, t).set("#bg", { background: "#111" }, prochaine || FIN); // retournement de couleur sur une phrase clé
if (prochaine) tl.to(mots, { yPercent: -110, opacity: 0, duration: 0.15, ease: "power2.in", stagger: 0.03 }, prochaine - 0.17)
.set(p, { autoAlpha: 0 }, prochaine);
});
tl.fromTo("#root", { scale: 1 }, { scale: 1.04, duration: FIN, ease: "none" }, 0); // dérive lente
tl.set({}, {}, FIN);
window.__timelines["main"] = tl;
});
</script></body></html>
Modifiez PHRASES pour changer les mots et les temps. Ajoutez des mouvements en ajoutant une branche if (move === ...) du vocabulaire des mouvements. Avec une voix off, placez l'élément <audio> dans la racine et prenez les temps des phrases à partir de sa transcription.
Paramètres à exposer à l'utilisateur
aspect · phrases (temps, lignes, mouvement, héros) · policeAffichage · policeSupport · couleurs (fond, texte, accent) · tempo ou audio · phrasesRetournees (où le fond se retourne) · compositionFinale.
À éviter
- Les fondus et les dérives lentes comme mouvement principal. Cela ressemble à un diaporama.
- Plus de 4 mots ou 3 lignes à l'écran en même temps.
- Plusieurs couleurs d'accent. Une seule, utilisée uniquement sur les mots héroïques.
- Des graisses de police fines ou légères, ou des polices scriptes pour les mots héroïques.
- Du texte dans les 670 px du bas ou les 270 px du haut d'un cadre 9:16 (l'interface de la plateforme les recouvre).
- Des variations aléatoires ou par rendu. Chaque valeur doit provenir de la timeline.
Modes de défaillance
| Apparence | Cause | Correction |
|---|---|---|
| Un diaporama | fondus, longues pauses, même mouvement à chaque fois | variez les mouvements du vocabulaire ; entrées sous 0,35 s ; sorties 0,15 s |
| Sous-titres, pas du design | mots trop petits, centrés dans un espace vide | dimensionnez les mots à la largeur du cadre ; police condensée ; 250+ px |
| Désordonné, illisible | trop de mots ou de mouvements à la fois | une phrase à l'écran ; un mot héroïque ; maintenez 0,35 s après atterrissage |
| Décalé par rapport au rythme | temps de phrase devinés | utilisez les temps de transcription ou de beats ; faites atterrir les impacts 2–3 images plus tôt |
| Mots coupés par les masques | hauteur de ligne trop serrée pour la police | line-height 0.92–1.0 avec padding sur .line ; vérifiez les captures |
| Mauvais rendu de police | police non chargée | <link> Google Fonts dans <head> ; vérifiez qu'une capture montre la police condensée |
Valider avant le rendu final
npx hyperframes check
npx hyperframes snapshot --at <un temps par phrase 0,3 s après son atterrissage, plus un en milieu de sortie>
npx hyperframes render -o renders/<nom>.mp4
ffprobe -v error -show_entries stream=width,height,r_frame_rate:format=duration -of csv=p=0 renders/<nom>.mp4
Examinez chaque capture et snapshots/contact-sheet.jpg, et confirmez :
- chaque phrase remplit 50–80 % de la largeur et est lisible à la taille d'un téléphone
- un mot héroïque par phrase, dans la couleur d'accent ou avec un mouvement différent
- aucune phrase ne chevauche une autre sur une image
- tout le texte dans la zone de sécurité pour le format
- la composition finale est maintenue au moins 1 s et correspond à l'ouverture
- la taille et la durée correspondent à la demande
Auto-critique avant le rendu final
Notez la feuille de captures de 1 à 10 sur : l'accroche (première seconde), la lisibilité à largeur de téléphone, la qualité du mouvement, la composition, la précision, et le "test silencieux" (un spectateur peut-il la résumer en une phrase sans son ?). Corrigez uniquement ce qui obtient 7 ou moins, refaites une capture, et répétez jusqu'à ce que tout soit 8 ou plus. Si possible, faites effectuer la notation par un passage en lecture seule, afin de ne pas noter votre propre travail.
| À ne pas faire | À la place |
|---|---|
| Fondu enchaîné entre deux mises en page chargées | sortez l'ancien contenu, puis amenez le nouveau, ou faites passer un objet |
| Faire bouger plusieurs choses à la fois | décalez, un seul point focal |