Comment créer un studio de motion 2.5D avec Opus 5.5

Un prompt, un fichier HTML, un exporteur de 25 lignes : construisez un studio d'animation 2.5D dans le navigateur avec Opus 5.5 pilotant Claude Code, effectuez le rendu en MP4, puis testez l'appel API de shot-list d'Opus 5.5 avec l'Apidog CLI.

Ahmed Waheed

Ahmed Waheed

12 November 2026

Comment créer un studio de motion 2.5D avec Opus 5.5

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

Vous pouvez construire un studio d'animation 2.5D avec Opus 5.5 en une seule session Claude Code : un fichier HTML unique qui empile des calques plats à différentes profondeurs, déplace une caméra animée par images clés à travers eux avec des courbes d'easing, et un script Playwright de 25 lignes qui capture chaque image et l'envoie à ffmpeg. Notre build a rendu un MP4 720p de 6 secondes (180 images) en environ 20 secondes sur un ordinateur portable.

Ce guide présente les prompts, le code écrit par l'agent, les bugs rencontrés, et comment vérifier les appels à l'API Opus 5.5 derrière une fonctionnalité « décrire un plan » avec Apidog CLI.

Qu'est-ce qu'un studio d'animation 2.5D ?

Un studio d'animation 2.5D est un outil d'animation qui place des calques 2D plats (ciel, collines, ville, carte de titre, feuillage au premier plan) à différentes profondeurs dans un espace 3D, puis déplace une caméra virtuelle à travers eux. Les calques proches de la caméra glissent plus vite que ceux au loin, ce qui produit du parallaxe et une sensation de profondeur sans aucun modèle 3D.

Trois éléments transforment cela en véritable studio plutôt qu'en animation ponctuelle :

  1. Un graphe de scène : des calques avec une profondeur z, une taille, une position et un contenu HTML.
  2. Une timeline : des images clés pour la caméra (dolly, travelling latéral, orbite) et pour chaque calque (opacité, échelle, position), chacune avec une courbe d'easing.
  3. Un moteur de rendu déterministe : une fonction renderAt(t) qui dessine l'image exacte pour n'importe quel instant t, afin que l'export ne dépende jamais de la vitesse de lecture de la machine.

C'est ce troisième point que la plupart des tutoriels négligent, et c'est lui qui détermine si votre MP4 saccade ou non.

Configurer Claude Code avec Opus 5.5

Opus 5.5 est le modèle idéal pour ce type de travail. La présentation des modèles d'Anthropic le décrit comme « pour le codage agentique et le travail sur les connaissances de longue durée », avec une fenêtre de contexte d'un million de tokens, une sortie maximale de 128K, et des tarifs de 4 $ / 20 $ par million de tokens d'entrée / sortie.

Épinglez le modèle pour qu'un changement d'alias ne le remplace pas en cours de projet :

claude --model claude-opus-5-5 --effort high

Opus 5.5 utilise par défaut l'effort medium, selon la documentation sur l'effort. Passez à high pour la première construction, lorsque l'agent doit getionner correctement les calculs de projection. Redescendez à medium pour les petits ajustements d'images clés et de couleurs. Si vous voulez d'abord découvrir le modèle, lisez qu'est-ce que Claude Opus 5.5 et comment le prompt caching modifie son coût.

Le prompt qui construit le studio

Un prompt précis vaut mieux que cinq vagues. Voici notre cahier des charges, rédigé en un seul prompt :

Build a 2.5D motion studio as one file, studio.html, with no dependencies.
- Scene: 6 layers (sky, moon, hills, city skyline, a title card "Ship it.",
  foreground foliage), each at its own z depth, using CSS perspective and
  preserve-3d.
- Camera: keyframes for x, y, z (dolly) and yaw (orbit around the card).
- Per-layer tracks: opacity, scale, y. Easings: linear, easeInOutCubic,
  easeInOutSine, easeOutBack.
- A timeline bar with keyframe markers, a playhead, click to scrub,
  space to play or pause.
- renderAt(t) must be pure in t. Expose window.__seek(t) that resolves after
  the frame paints, and a ?capture mode that hides the UI.
Then write export.mjs: Playwright opens ?capture, seeks every frame at 30 fps,
screenshots it and pipes PNGs to ffmpeg as H.264.

Les deux dernières lignes sont les plus importantes : elles font de l'export une partie de la conception, pas un ajout après coup.

Le code écrit par l'agent

Le studio fait environ 150 lignes. Trois morceaux comptent.

Images clés et easing

Chaque piste est une liste triée d'images clés. sample() trouve les deux clés encadrant t, applique l'easing de la clé sortante et interpole chaque champ numérique :

function sample(keys, t) {
  if (t <= keys[0].t) return keys[0];
  for (let i = 0; i < keys.length - 1; i++) {
    const a = keys[i], b = keys[i + 1];
    if (t <= b.t) {
      const p = (easings[a.ease] || easings.linear)((t - a.t) / (b.t - a.t));
      const out = {};
      for (const k in b) if (typeof b[k] === 'number' && k !== 't') out[k] = a[k] + (b[k] - a[k]) * p;
      return out;
    }
  }
  return keys[keys.length - 1];
}

L'astuce de la profondeur

La caméra ne bouge jamais. C'est le monde qui se déplace en sens inverse. Chaque calque reçoit alors une translation en z plus une échelle de compensation :

const PERSPECTIVE = 1200; // must match #viewport perspective
world.style.transform =
  `translate3d(${-cam.x}px, ${-cam.y}px, ${cam.z}px) rotateY(${-cam.yaw}deg)`;
const comp = 1 - L.z / PERSPECTIVE;
el.style.transform = `translate(-50%,-50%) ` +
  `translate3d(${x * comp}px, ${y * comp}px, ${L.z}px) scale(${comp * s})`;

Avec la propriété CSS perspective réglée à 1200px, un calque à z = -900 est rendu à 1200 / 2100, soit 57 % de sa taille. En multipliant son échelle et ses décalages x/y par 1 + 900/1200 = 1,75, on annule cet effet. Chaque calque apparaît à la taille et à la position définies par l'auteur quand la caméra est au repos, et se déplace toujours à sa propre vitesse quand la caméra bouge. C'est toute l'illusion.

Le studio d'animation 2.5D dans le navigateur : une carte de titre devant une lune, des collines et une skyline, avec une timeline affichant les images clés de la caméra en bleu, celles des calques en jaune et une tête de lecture rouge à 2,10 s

Le bug qu'il faut connaître

La première version mettait à l'échelle chaque calque mais pas son décalage, si bien que les collines montaient jusqu'à couvrir les deux tiers du ciel. La correction : multiplier aussi x et y par comp. Nous l'avons repéré grâce à une seule image rendue, pas en lisant le code : demandez donc à votre agent de rendre des captures aux moments initial, intermédiaire et final avant de faire confiance à un mouvement de caméra.

Exporter la timeline en MP4

La lecture en temps réel utilise requestAnimationFrame, qui perd des images quand la machine est occupée. L'export ne le peut pas. L'exportateur pilote donc le temps à partir de l'index d'image et attend que chaque image soit peinte avant de prendre une capture d'écran Playwright :

import { chromium } from 'playwright';
import { spawn } from 'node:child_process';
import { pathToFileURL } from 'node:url';

const out = process.argv[2] || 'out.mp4';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
await page.goto(pathToFileURL('studio.html').href + '?capture');

const { duration, fps } = await page.evaluate(() => window.__scene);
const ffmpeg = spawn('ffmpeg', ['-y', '-f', 'image2pipe', '-framerate', String(fps),
  '-i', '-', '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-crf', '18', out],
  { stdio: ['pipe', 'ignore', 'inherit'] });

const frames = Math.round(duration * fps);
for (let i = 0; i < frames; i++) {
  await page.evaluate(t => window.__seek(t), i / fps);
  ffmpeg.stdin.write(await page.screenshot({ type: 'png' }));
}
ffmpeg.stdin.end();
await new Promise(r => ffmpeg.on('close', r));
await browser.close();

window.__seek(t) se résout après deux images d'animation, de sorte que chaque capture voit les nouvelles transformations. image2pipe (voir la documentation des formats ffmpeg) lit les PNG depuis stdin, et yuv420p garantit que le fichier reste lisible dans les navigateurs.

Notre exécution : 180 images, 1280x720, 30 fps, 6,0 secondes, un MP4 de 420 Ko, en 20 secondes de temps réel. Exécutez npx playwright install chromium une fois si Playwright n'a pas encore de navigateur.

Trois images du MP4 exporté à 0,3 s, 2,5 s et 5,9 s : la caméra avance vers la carte de titre tandis que la skyline et la colline au premier plan se décalent à des vitesses différentes, puis orbite si bien que la carte s'incline

Les tours de la ville se décalent moins que la colline sombre au premier plan, qui finit par sortir complètement du cadre. C'est cela, le parallaxe.

Ajouter une fonctionnalité « décrire un plan » avec l'API Opus 5.5

Ensuite, permettons à un rédacteur de saisir une description de plan et de recevoir des images clés en retour. Le studio appelle directement l'API Messages :

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2026-10-21" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 4096,
    "output_config": { "effort": "low" },
    "system": "Return only JSON: {\"camera\": [{\"t\",\"x\",\"y\",\"z\",\"yaw\",\"ease\"}], \"tracks\": {}}. Times in seconds, 0 to 6.",
    "messages": [{ "role": "user", "content": "Slow push-in, slight orbit right, title fades up in the first second." }]
  }'

Deux détails de la documentation sur l'effort comptent ici. output_config.effort est l'endroit où se place le niveau d'effort dans une requête à l'API Messages. Et Opus 5.5 utilise toujours le raisonnement adaptatif (une requête avec thinking: {"type": "disabled"} renvoie une erreur 400), donc les tokens de raisonnement comptent dans max_tokens. Réglez-le trop bas et le JSON est coupé en plein milieu d'un tableau avec stop_reason: "max_tokens". Une liste de plans est une tâche courte et bien spécifiée, donc l'effort low est un réglage de départ raisonnable ; faites votre propre comparaison avant de le fixer.

Laisser Claude Code tester l'appel API avec Apidog CLI

Une réponse tronquée ou bavarde casse sample() au moment du rendu, donc cet appel a besoin d'un test de contrat. La même session Claude Code peut l'écrire et l'exécuter avec Apidog CLI.

Installez et connectez-vous une fois :

npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
apidog skill install

Puis donnez à l'agent un seul prompt :

In Apidog project <projectId>, create an endpoint for POST /v1/messages and a
test case that sends the "describe a shot" request above with model
claude-opus-5-5. Assert: status 200, body.model is "claude-opus-5-5",
stop_reason is not "max_tokens", and content[0].text parses as JSON with a
non-empty camera array whose t values rise from 0 to 6. Use an environment
with base URL https://api.anthropic.com and the key in a variable. Run it and
summarize failures.

L'agent lit les schémas de charge utile au lieu de les deviner, valide ses fichiers, puis crée et exécute tout :

apidog cli-schema get endpoint-create
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog environment create anthropic --project <projectId> --base-url https://api.anthropic.com
apidog endpoint create --project <projectId> --file endpoint.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json

Passez la clé au moment de l'exécution avec --env-var "api_key=$ANTHROPIC_API_KEY" pour qu'elle ne figure jamais dans le projet. Réexécutez le cas de test quand vous modifiez le prompt système ou le niveau d'effort, car les deux changent ce qui est renvoyé. Le même apidog run avec -r junit s'intègre dans un pipeline CI ; voir le guide CI/CD d'Apidog CLI et Apidog CLI dans Claude Code. Le plan gratuit d'Apidog couvre jusqu'à 4 utilisateurs.

Où faire évoluer le studio ensuite

FAQ

Que signifie 2.5D en motion graphics ? Cela désigne des illustrations 2D plates placées à différentes profondeurs et filmées par une caméra en mouvement. Vous obtenez du parallaxe et des indices de profondeur sans modèles 3D, éclairage ni moteur 3D.

Pourquoi utiliser Opus 5.5 plutôt qu'un modèle plus petit pour ce build ? La première construction mélange calculs de projection, moteur d'images clés et pipeline de capture en une seule passe. Anthropic positionne Opus 5.5 pour le codage agentique de longue durée, et notre session a obtenu un studio fonctionnel à partir d'un seul prompt plus une série de corrections. Pour les petites modifications ensuite, un niveau d'effort plus bas suffit.

Pourquoi ne pas simplement enregistrer l'écran au lieu de capturer les images ? L'enregistrement d'écran suit le temps réel, donc toute image lente devient une image perdue ou dupliquée. Se positionner à i / fps et capturer chaque image rend le résultat identique sur toutes les machines.

Puis-je utiliser la fonctionnalité « décrire un plan » sans clé API ? Non. Cette fonctionnalité appelle l'API Messages, qui requiert votre propre clé API Anthropic. Le reste du studio et l'export MP4 fonctionnent localement sans clé.

Quel niveau d'effort l'appel de liste de plans devrait-il utiliser ? Commencez avec low, car la tâche est courte et le schéma de sortie est fixe. Augmentez-le seulement si votre test Apidog révèle des images clés mal formées ou hors sujet.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API