Motion Canvas
Vérifié 2026-10 : @motion-canvas/core, /2d, /ffmpeg 3.17. Nécessite Node 16+.
Remotion vs Motion Canvas : Remotion = React, image → UI, adapté aux vidéos pilotées par des données et au rendu serveur. Motion Canvas = timeline impérative (yield* une étape après l'autre) avec un éditeur pour synchroniser le timing avec une voix off. Choisissez l'un ou l'autre par vidéo ; ne les mélangez pas.
Configuration
npm init @motion-canvas@latest # nom, TypeScript, choisir l'exportateur "Video (FFmpeg)"
npm install
npm run serve # éditeur sur http://localhost:9000
src/project.ts # makeProject({ scenes: [...] })
src/scenes/*.tsx # un fichier par scène
// src/project.ts
import {makeProject} from '@motion-canvas/core';
import intro from './scenes/intro?scene'; // le suffixe ?scene est obligatoire
export default makeProject({scenes: [intro]});
Scène
import {Circle, Rect, Txt, makeScene2D} from '@motion-canvas/2d';
import {all, chain, createRef, easeInOutCubic, sequence, waitFor, waitUntil} from '@motion-canvas/core';
export default makeScene2D(function* (view) {
const circle = createRef<Circle>();
view.add(<Circle ref={circle} x={-300} size={240} fill="#e13238" />);
yield* all( // en parallèle, attendre toutes
circle().position.x(300, 1).to(-300, 1), // interpolation : prop(valeur, secondes), enchaîner avec .to()
circle().fill('#e6a700', 1).to('#e13238', 1),
);
yield* waitUntil('title'); // événement temporel nommé, déplaçable dans la timeline de l'éditeur
yield* circle().scale(2, 0.6, easeInOutCubic);
});
- Coordonnées : origine au centre de la vue ;
x,y,size,width,height,rotation,scale,opacity,fill,stroke,lineWidth. - Composants :
Rect(radiuspour les coins arrondis),Circle,Line/Spline(points,endpour l'effet de dessin),Txt,Img,Video,Layout(flexbox :layout direction gap),Code,Latex. - Une propriété appelée avec une valeur l'affecte ; avec
(valeur, secondes[, ease])elle s'interpole et doit être préfixée paryield*; sans argument, elle lit la valeur.
Flux
| Appel | Effet |
|---|---|
all(...t) | exécuter ensemble, attendre toutes |
any(...t) | exécuter ensemble, attendre la première |
chain(...t) | l'une après l'autre |
sequence(0.2, ...t) | démarrer chaque 0,2 s après la précédente (sans attendre) |
delay(0.5, t) | démarrer après 0,5 s |
loop(3, () => t) | répéter |
waitFor(1.5) | pause de 1,5 s |
waitUntil('event') | pause jusqu'à l'événement nommé dans l'éditeur — à utiliser pour la synchronisation avec la voix off |
useDuration('event') | durée d'un événement nommé, utilisée comme durée d'interpolation |
Rendu
- Éditeur → Panneau de rendu : résolution, fréquence d'images (24/30/60), plage, exportateur. Cliquez sur RENDER.
- La sortie se trouve dans
/output. L'exportateur par défaut écrit une séquence d'images ; pour du MP4 avec audio, ajoutez l'exportateur FFmpeg :
npm install --save @motion-canvas/ffmpeg
// vite.config.ts
import {defineConfig} from 'vite';
import motionCanvas from '@motion-canvas/vite-plugin';
import ffmpeg from '@motion-canvas/ffmpeg';
export default defineConfig({plugins: [motionCanvas(), ffmpeg()]});
Choisissez ensuite Video (FFmpeg) dans les paramètres vidéo.
- Les changements de résolution ne redimensionnent pas la mise en page ; décidez de la taille finale (par ex. 1920×1080 ou 1080×1920) avant de commencer la disposition.