Animation line art
Composants d'illustration animée : tout est dessiné avec un seul stylo fin sur du papier, construit en direct en SVG à partir de TypeScript, ce qui reste net à n'importe quelle taille, répond au pointeur et peut être parcouru image par image pour la vérification ou l'export vidéo.
Cette compétence fournit une petite bibliothèque (lib/), deux exemples (examples/walker, une seule
figure en ~150 lignes ; examples/village, une scène complète) et des outils (scripts/).
Lisez l'exemple le plus proche de la demande avant d'écrire quoi que ce soit.
Comment les gens jugent ce travail
Ils le regardent comme le ferait un animateur : image par image, zoomé, comparé à la réalité ou à une référence. Tous ces éléments ont été rejetés dans la pratique, et chacun a une règle ci-dessous :
- des marches qui oscillent sur une sinusoïde, des pieds qui glissent, des allures accélérées pour tenir dans un timelapse
- des membres dessinés comme des tubes fermés ; des lignes parfaitement droites ; des vêtements rigides qui ignorent les jambes
- un ensemble complet de composants construits en une seule fois qui se ressemblent tous ("AI slop")
- des interactions qui ressemblent à une interface utilisateur plutôt qu'à un monde qui réagit
- une page dont l'arrière-plan change avec la scène ("on dirait une vidéo, pas un composant")
- réutiliser des personnages d'un clip de référence quand on demande quelque chose de nouveau
- des accessoires laissés là que personne n'a demandés (ils ont demandé de retirer le linge qui sèche)
Flux de travail
- Fixez le look avant que quoi que ce soit ne bouge. Lisez
references/style.md. Décidez le poids du trait, la couleur du papier, les proportions des figures et la ou les deux couleurs d'accent plates. - Configurez le projet. Copiez
lib/dans le projet (ce sont quatre fichiers.tssans dépendance) et utilisez Vite + TypeScript (package.json,tsconfig.jsonetvite.config.tsdans ce dépôt montrent la configuration). Les composants sont en DOM/SVG pur — aucun framework nécessaire. - Construisez d'abord une figure ou un coin et montrez-le (capture d'écran ou petit clip, à côté de la référence s'il y en a une). Obtenez un oui avant de construire le reste. Un ensemble complet construit en une fois revient générique ; une bonne pièce montre le niveau.
- Faites-le bouger avec
references/motion.md:gait()pour la marche et la course,spring()/pendulum()pour tout ce qui est attaché ou suspendu, poses clés aveccurve()ousequence()pour les gestes. N'animez jamais une figure avec des sinusoïdes libres. - Composez la scène avec
references/scenes.md: une carte autonome sur un fond de page fixe, des calques, une palette horaire depuislib/daynight.ts, des lumières, du vent, des personnes arrivant selon des horaires, des interactions qui sont des réactions. - Vérifiez avec
references/verify.mdavant de montrer quoi que ce soit : vérification de type,?debugpas à pas, bandes d'images zoomées de chaque chose en mouvement, interactions déclenchées et parcourues, 60 fps dans un onglet réel. - S'il y a un clip de référence à reproduire, suivez
references/matching.md— mesurez le timing et les poses depuis le clip au lieu de deviner, et vérifiez avec une superposition. - S'ils veulent une vidéo, suivez
references/video.md(capture headless déterministe avecscripts/capture.ts, puis ffmpeg).
Règles qui font que ça marche
- Les membres sont deux traits ouverts.
limb()dessine une bande remplie de papier entre deux traits de plume qui s'arrêtent avant de se toucher à l'extrémité. C'est la signature du style. - Les lignes sont courbes. Les articulations sont arrondies, les bords sont légèrement incurvés, rien n'est parfaitement droit.
- Dessinez chaque figure dans son propre espace — ~95 unités de haut, pieds sur y = 120, faisant face à +x,
debout à x = 40 — et placez-la avec
place(g, x, y, dir, scale). Les proportions, le poids du trait et les préréglages de démarche supposent tous cet espace. - Les vêtements sont dessinés autour du squelette. Résolvez les jambes (même si cachées), puis dessinez l'ourlet du manteau ou du kimono à partir du genou avant et des chevilles pour que le tissu s'ouvre et se ferme avec l'enjambée. Les manches, écharpes et sacs se balancent avec des ressorts.
- Les pieds sont plantés. Déplacez un marcheur exactement de
gait.speed × scalepar seconde et le pied d'appui reste immobile au sol. N'accélérez pas une démarche pour correspondre à une horloge compressée ; compressez les arrivées à la place. - L'encre est
currentColor, le papier est.pp. Recolorez tout le dessin avecapplyPalette()(jour : encre foncée sur papier chaud ; nuit : encre pâle sur indigo, fenêtres chaudes). Les remplissages de couleur unie des membres doivent utilisersolid(), sinon le CSS du papier gagne. - Le composant est une carte. La page autour ne change jamais de couleur.
- Les interactions sont le monde qui réagit : une personne s'incline ou soulève son chapeau, un chat se réveille et s'étire, une lanterne se balance, les oiseaux s'envolent, un poisson saute. Le mouvement du pointeur est le vent. Pas de boutons dans la scène ; une seule ligne d'indication très légère suffit.
- Nouveau signifie nouveau. Si la consigne est "comme ceci mais nouveau", gardez le médium, le stylo, les proportions et la sensation du timing ; inventez les personnages, les activités et les accessoires.
Aperçu de la bibliothèque
| module | ce qu'il vous donne |
|---|---|
lib/ink.ts | pen shape blot paint limb solid joint hang curve shoe place toScene inkDefs run |
lib/gait.ts | `gait({ kind: 'walk' |
lib/motion.ts | spring pendulum pointerWind sequence seeded wobble ease minJerk … |
lib/daynight.ts | palette(τ) → ciel, papier, encre, lamp, night, sunset ; applyPalette nightTint |
run(draw) pilote tout avec draw(t, dt). Deux indicateurs d'URL importent pour la vérification :
?t=1.25 fige le temps ; ?debug désactive le rAF et expose window.__step(seconds)
pour un pas à pas exact (les onglets en arrière-plan et headless limitent le rAF, donc vérifiez toujours en mode debug).
Scripts
scripts/capture.ts <url?debug> <outDir> <frames> <fps> [w] [h] [setupJs] [frameJs]— images PNG déterministes depuis Chrome headlessscripts/clip.ts period|blobs …— longueur de boucle d'une région ; suivi des blobs sombres par imagescripts/frames.sh <clip> x y w h outDir— images avec grille superposée pour lire les poses d'un clip
Tous s'exécutent avec Node ≥ 22.18 (TypeScript est éliminé nativement) plus ffmpeg ; capture.ts
trouve un Chrome/Chromium local ou utilise $CHROME.