Styles d'animation
Un projet Remotion avec 39 styles d'animation fabriqués à la main. Chaque style redessine une histoire fixe, ce qui permet de les comparer côte à côte et de les réutiliser comme modèles : une bouilloire entre, s'incline, verse du chai dans un kulhad (tasse en argile), la tasse se remplit, la bouilloire sort, la vapeur monte. 150 images, 30 ips, 1080×1350 (4:5), silencieux. Rendu avec --scale=2, il obtient 2160×2700.
Tout est dessiné en code : SVG avec des filtres, ou un <canvas> peint à chaque image. Aucun modèle d'image, vidéo ou séquence d'archives n'est impliqué, donc la sortie est originale et reproductible.
Le projet se trouve dans le dossier de cette compétence (le dossier contenant ce fichier, appelé <skill> ci-dessous). Exécutez les commandes à partir de là.
0. Première fois dans une session
cd <skill>et vérifiez quenode_modules/existe. Sinon, exécuteznpm install(environ une minute, nécessite Node 18+).npm run listaffiche les 39 styles avec leur numéro, slug et un aperçu d'une ligne.- Le premier rendu télécharge une fois un Chrome sans tête (environ 100 Mo). Il nécessite une connexion Internet.
La demande habituelle : "fais une vidéo de 5 secondes de <idée> dans le style "
C'est la tâche principale (et l'invite du message qui amène les gens ici). Faites-la de bout en bout sans vous arrêter pour poser des questions, sauf si l'idée n'est pas claire :
- Dossier de travail : utilisez
animation-films/dans le dossier de travail actuel de l'utilisateur. S'il n'existe pas, créez-le à partir de ce dossier avecnode <skill>/scripts/new-project.mjs animation-films, puiscd animation-films && npm install(rapide après la première fois). S'il existe (suite), réutilisez-le tel quel. - Choisissez le style dans la demande (section 1). Pas de style nommé ? Suggérez-en trois qui correspondent à l'idée et demandez.
- Planifiez l'histoire sur les six battements (section 3) dans un court tableau. Affichez-le en un seul message et continuez ; n'attendez pas sauf si quelque chose est ambigu.
- Les formes d'abord : placez les objets de l'utilisateur (l'acteur, le contenant, ce qui coule, ce qui monte) dans
src/films/<idée>-shapes.tssous forme de chemins SVG dans les mêmes coordonnées quePdansstory.ts, avec le tableau des battements en commentaire en haut. Chaque version de style de cette idée importe depuis ce seul fichier. - Construisez
src/films/<idée>-<style>.tsxà partir du composant du style (section 3), en utilisant le fichier de formes, et enregistrez-le danssrc/films/index.tsavec l'identifiant<idée>-<style>. - Vérifiez :
npm run render -- <idée>-<style> --frameset regardez les six images (section 5). Corrigez et répétez. - Livrez :
npm run render -- <idée>-<style> --finalet donnez à l'utilisateur le chemin complet deout/<idée>-<style>.mp4. Mentionnez qu'il peut demander un autre style ("maintenant fais-le en pixel art").
Suivi de restylage ("maintenant fais-le en pixel art", "essaie l'aquarelle", "pareil en gravure sur bois") : restez dans le même dossier animation-films/, conservez la même idée, le même tableau de battements et le même fichier de formes, et construisez un nouveau src/films/<idée>-<nouveau-style>.tsx à partir du composant du nouveau style. Enregistrez-le à côté de la version précédente (ne l'écrasez jamais), vérifiez les images, effectuez le rendu final et donnez le nouveau chemin. Si l'utilisateur nomme un style de manière approximative ("8-bit", "vieux film", "craie"), associez-le avec la section 1. Les styles d'aspect 3D (57, 58, 59, 62, 80) construisent les objets comme des maillages 3D, donc l'échange de nouveaux objets demande plus de travail dessus : transformez les formes en simples maillages de tour ou de boîte avec les aides dans src/styles/3d/mesh.ts.
1. Choisir un style
Demandez à l'utilisateur quel style il veut s'il ne l'a pas dit. S'il ne sait pas, montrez npm run list regroupé par famille et la galerie dans README.md (chaque style a un aperçu animé dans media/thumbs/ et un MP4 720×900 dans media/videos/). Associez de manière approximative : "estampe japonaise" → 33 Ukiyo-e, "craie" → 02 Tableau noir, "8-bit" ou "jeu rétro" → 64 Pixel art RPG, "argile" → 62 Claymation, "comme Lego" → 58 Jouet en brique (ne l'appelez jamais Lego à l'écran), "vieux film" → 70 Film muet ou 71 Actualités, "écran sci-fi" → 84 Hologramme HUD.
| Famille | Styles (numéro, slug) |
|---|---|
| Dessiné sur un tableau | 01 whiteboard · 02 chalkboard · 05 notepad-doodle · 06 blueprint |
| Dessiné à la main et peint | 08 hand-drawn · 09 urban-sketch · 10 crayon-book · 11 watercolour · 13 one-line · 16 cel-line-boil |
| Dessin animé | 17 flat-vector · 21 cel-anime-80s · 22 stick-figure |
| Papier et marionnettes | 23 cut-out · 24 red-papercut · 25 paper-pop-up · 27 shadow-puppet |
| Imprimé et artisanal | 28 woodcut · 29 engraving · 31 silkscreen-poster · 33 ukiyo-e · 34 art-deco · 35 stained-glass |
| Graphique et explicatif | 39 memphis-diorama · 51 sticker-explainer · 52 math-diagram |
| Aspect 3D | 57 low-poly-island · 58 brick-toy · 59 glass-product · 62 claymation · 80 lidar-survey |
| Époques du cinéma | 70 silent-film · 71 newsreel |
| Écrans et science | 64 pixel-art-rpg · 81 microscope · 84 hologram-hud · 85 circuit-board |
| Abstrait | 87 liquid-motion · 89 generative-abstract |
src/catalog.ts est la liste unique : numéro, identifiant de composition (33-ukiyo-e), nom, famille, aspect, les mots à l'écran qu'un style affiche, et le fichier où se trouve son code.
2. Afficher un style intégré tel quel
npm run render -- 33 # Aperçu 720x900 -> out/33-ukiyo-e_preview.mp4 (quelques secondes à une minute)
npm run render -- 33 --final # Master 2160x2700 -> out/33-ukiyo-e.mp4 (crf 16)
npm run render -- 33 --frames # 6 images de vérification -> out/33-ukiyo-e_frames/ (+ une planche contact si ffmpeg est installé)
npm run render -- 33 --still 75 # Un PNG de l'image 75
Un style peut être nommé par numéro, identifiant, slug ou une partie de son nom (ukiyo, pixel, stained). Les vidéos prêtes à l'emploi en 720×900 sont déjà dans media/videos/, et les masters complets en 2160×2700 sont sur la page de version GitHub, donc pour simplement montrer un style, vous n'avez pas du tout besoin de faire un rendu.
3. Le raconter avec l'histoire ou l'objet de l'utilisateur
L'histoire est fixée dans src/story.ts. Conservez son timing et modifiez ce qui est dessiné. C'est ce qui fait qu'un nouveau film sort correctement du premier coup : chaque style sait déjà comment mettre en scène ces battements.
Les battements (images à 30 ips, ne les déplacez jamais pour un film de 5 secondes) :
| Images | Battement | Valeur de storyAt(f) |
|---|---|---|
| 0–24 | l'acteur entre par la droite | kx, ky |
| 24–42 | il se prépare (s'incline) | tilt (0 → −38°) |
| 42–96 | l'action principale (le versement) | streaming, stream (un chemin SVG du tip dans la tasse) |
| 44–100 | le résultat grandit (la tasse se remplit) | level 0 → 1, surface (l'ellipse du chai) |
| 96–126 | il se termine et sort | tilt revient à 0, kx glisse dehors |
| 104–150 | les conséquences (la vapeur monte) | steam[0..2] 0 → 1, dessiné avec steamPath(i, p, t0) |
P dans story.ts contient les chemins SVG pour la tasse (kulhadBody, kulhadOutline, rim) et la bouilloire (kettleBody, kettleLid, kettleSpout, kettleHandle, kettleBand, plus KNOB). La bouilloire est dessinée autour de sa propre origine et placée avec translate(kx, ky) rotate(tilt).
Adaptez d'abord l'histoire de l'utilisateur sur les six mêmes battements, dans un court tableau, et montrez-le-lui. Exemples :
| Idée de l'utilisateur | Acteur (bouilloire) | Action (verser) | Résultat (remplir) | Conséquences (vapeur) |
|---|---|---|---|---|
| Café dans une tasse | cafetière | flux de café | la tasse se remplit | vapeur |
| Arroser une plante | arrosoir | gouttes d'eau | le sol s'assombrit, une pousse grandit avec level | deux feuilles s'ouvrent |
| Économiser de l'argent | une main avec une pièce | la pièce tombe | la tirelire se remplit (level → pile de pièces) | des étincelles |
| Peinture dans une boîte | pot de peinture | peinture épaisse | la boîte se remplit | une goutte se dépose |
| Téléchargement de données (styles abstraits ou d'info) | un nuage | les paquets voyagent le long de stream | une barre ou un indicateur se remplit avec level | une coche monte |
Ensuite construisez-le :
- Travaillez dans un projet séparé pour que la compétence installée reste propre : par défaut
animation-films/dans le dossier actuel de l'utilisateur (voir "La demande habituelle" ci-dessus), créé avecnode <skill>/scripts/new-project.mjs <folder>puisnpm installà l'intérieur. Ne construisez jamais les films de l'utilisateur à l'intérieur de<skill>lui-même. - Copiez le composant du style choisi depuis son fichier (voir
src/catalog.ts) danssrc/films/<nom-du-film>.tsx, avec les aides qu'il importe. Ne modifiez jamais les 39 originaux sur place : ils sont la référence. - Remplacez les formes, pas le timing : échangez les chemins de la bouilloire et de la tasse par les objets de l'utilisateur (conservez à peu près la même taille et position : tasse centrée à x 540, bord à y ≈ 800 ; acteur au repos vers (796, 324) avec son "bec" au point local (−251, −62)), recolorez le liquide, changez ce qui monte. Conservez les propres matériaux du style, la logique de palette, les filtres, la texture et le caractère de mouvement (par pas de deux ou trois pour les médias faits à la main, lisse pour le numérique, scintillement pour le film).
- Si le style affiche des mots (listés dans le champ
textdu catalogue : 51, 52, 64, 70, 71, 84 et 85 affichent des mots), réécrivez-les pour la nouvelle histoire : courts, en anglais simple, uniquement sur l'histoire. - Enregistrez le film dans
src/films/index.tset effectuez son rendu (section 4).
Une histoire plus longue ou différente (plus de battements, deux acteurs, un mouvement de caméra) : écrivez un nouveau fichier d'histoire à côté de story.ts (par exemple src/films/mon-histoire.ts) avec son propre storyAt(f) qui retourne chaque valeur dont le dessin a besoin, listez les nouveaux battements dans un tableau en haut de ce fichier, définissez durationInFrames sur le film, et respectez la règle "le fichier d'histoire possède tout le timing, le fichier de style possède tous les aspects". Quantifiez les images (Math.floor(f / 2) * 2) uniquement là où le style est censé avoir l'air fait à la main.
Règles pour le code : déterministe uniquement (pas de Math.random(), pas de Date ; utilisez des fonctions ensemencées de l'image ou de l'index), des identifiants uniques pour les filtres et clipPath, des polices uniquement via @remotion/google-fonts/<Font> avec loadFont() au niveau du module, et rien d'installé au-delà de package.json.
4. Rendu
| Besoin | Commande |
|---|---|
| Aperçu rapide | npm run render -- <film-ou-style> (720×900, crf 23) |
| Final | npm run render -- <film-ou-style> --final (2160×2700, crf 16) |
Un film depuis src/films | npm run render -- <film-id> --final (les mêmes indicateurs fonctionnent : --frames, --still 75) |
| Édition en direct | npm run studio ouvre Remotion Studio dans le navigateur |
Les styles d'aspect 3D (57, 58, 59, 62, 80) peignent une scène rendue par logiciel sur un canvas à 1,5× (1,25× pour 80) de 1080 de large, puis l'étirent à 2160, donc ils sont légèrement plus doux et plus lents que les autres. Pour un final plus net, augmentez le second argument de glView(...) dans src/catalog.ts (2 = 4K natif, environ deux fois plus lent).
5. Vérifiez la sortie avant de la remettre
Exécutez npm run render -- <id> --frames et regardez chaque image (lisez les PNG). Corrigez et refaites le rendu. Autorisez deux ou trois passages.
- Histoire lisible : à l'image 50, quelque chose coule clairement, à 75 le récipient se remplit visiblement, à 149 les conséquences sont visibles.
- Rien de coupé aux bords de l'image ; l'acteur entre complètement et sort complètement.
- Superposition : le liquide reste à l'intérieur du récipient, le flux entre dedans (pas devant le bord proche), la vapeur commence à la surface.
- Le style se lit sur une seule image : quelqu'un qui connaît le style devrait pouvoir le nommer à partir d'un arrêt sur image. Deux styles ne devraient jamais ressembler à une simple recoloration l'un de l'autre.
- Contraste : le liquide et le flux sont visibles sur l'arrière-plan, rien n'est boueux.
- Caractère du mouvement : par pas là où le médium est fait à la main, lisse là où il est numérique ; pas de scintillement que vous n'avez pas voulu.
- Texte : seulement les mots que vous avez prévus, bien orthographiés, à l'intérieur de l'image.
- Règles de contenu (ci-dessous) toutes respectées. Enfin, regardez la vidéo d'aperçu MP4 une fois en entier, puis effectuez le rendu final.
6. Règles de contenu (toujours)
- Pas de vraies marques, logos, produits, personnes, noms de chaînes ou réseaux de télévision, et pas de noms déposés à l'écran. "Jouet en brique" est une brique de jouet générique, jamais une marque nommée.
- Pas de vraies cartes, lieux ou frontières nationales, et pas de drapeaux, symboles politiques ou slogans. Un paysage, s'il y en a, est inventé sans géographie reconnaissable.
- Pas de copie d'un film, d'une émission, d'un générique, d'un jeu, d'un personnage ou de la silhouette ou des sprites d'un personnage connu. Un style ou un genre est acceptable ; une œuvre existante particulière ne l'est pas.
- Pas de faits inventés : pas de fausses statistiques, prix, dates, citations ou sources. Un style de données trace les propres valeurs de l'histoire (comme le niveau de remplissage) et rien d'autre.
- Texte seulement lorsque le style est typographique, de diffusion ou une interface utilisateur de jeu, et alors en anglais court à propos de l'histoire elle-même.
- Gardez-le original : l'histoire de l'utilisateur, vos propres dessins, le style en tant que technique.
Fichiers
| Chemin | Quoi |
|---|---|
src/story.ts | L'histoire : taille, timing, battements, les chemins des objets, storyAt(f) et steamPath() |
src/kit.tsx | Aides partagées : Stage (une scène SVG), Paper (grain de papier), Rough (déformation oscillante), region |
src/catalog.ts | Les 39 styles : numéro, identifiant, nom, famille, aspect, mots à l'écran, fichier, composant |
src/styles/<family>/ | Le code de dessin, regroupé par technique |
src/films/ | Les propres films de l'utilisateur |
src/Root.tsx, src/index.ts | Enregistre chaque style et film comme une composition Remotion |
scripts/render.mjs | npm run list / npm run render |
scripts/new-project.mjs | npm run new -- <folder> copie le code vers un nouveau projet |
media/videos/, media/thumbs/ | Un MP4 720×900 et un WebP animé de chaque style |