Motion Canvas
Verificado em 2026-10: @motion-canvas/core, /2d, /ffmpeg 3.17. Requer Node 16+.
Remotion vs Motion Canvas: Remotion = React, frame → UI, escalável para vídeos orientados a dados/templatizados e renderização em servidor. Motion Canvas = linha do tempo imperativa (yield* um passo após o outro) com um editor para ajustar o tempo em relação a uma narração. Escolha um por vídeo; não misture.
Configuração
npm init @motion-canvas/latest # nome, TypeScript, escolha o exportador "Video (FFmpeg)"
npm install
npm run serve # editor em http://localhost:9000
src/project.ts # makeProject({ scenes: [...] })
src/scenes/*.tsx # um arquivo por cena
// src/project.ts
import {makeProject} from '@motion-canvas/core';
import intro from './scenes/intro?scene'; // sufixo ?scene é obrigatório
export default makeProject({scenes: [intro]});
Cena
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( // em paralelo, espera todos
circle().position.x(300, 1).to(-300, 1), // tween: prop(valor, segundos), encadeie com .to()
circle().fill('#e6a700', 1).to('#e13238', 1),
);
yield* waitUntil('titulo'); // evento nomeado no tempo, arrastado na linha do tempo do editor
yield* circle().scale(2, 0.6, easeInOutCubic);
});
- Coordenadas: origem no centro da visualização;
x,y,size,width,height,rotation,scale,opacity,fill,stroke,lineWidth. - Componentes:
Rect(radiuspara cantos arredondados),Circle,Line/Spline(points,endpara desenhar gradualmente),Txt,Img,Video,Layout(flexbox:layout direction gap),Code,Latex. - Uma propriedade chamada com um valor a define; com
(valor, segundos[, easing])ela faz um tween e deve ser precedida poryield*; sem argumentos, lê o valor.
Fluxo
| Chamada | Efeito |
|---|---|
all(...t) | executa juntos, espera todos |
any(...t) | executa juntos, espera o primeiro |
chain(...t) | um após o outro |
sequence(0.2, ...t) | inicia cada um 0,2 s após o anterior (sem esperar) |
delay(0.5, t) | inicia após 0,5 s |
loop(3, () => t) | repete |
waitFor(1.5) | pausa por 1,5 s |
waitUntil('evento') | pausa até o evento nomeado no editor — use isso para sincronizar com narração |
useDuration('evento') | duração de um evento nomeado, como duração de um tween |
Renderização
- Editor → Painel de renderização: resolução, taxa de quadros (24/30/60), intervalo, exportador. Clique em RENDER.
- A saída vai para
/output. O exportador padrão gera uma sequência de imagens; para MP4 com áudio, adicione o exportador 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()]});
Em seguida, escolha Video (FFmpeg) nas Configurações de Vídeo.
- Alterações de resolução não escalam o layout; decida o tamanho final (ex.: 1920×1080 ou 1080×1920) antes de posicionar os elementos.