Communitygithub.com

phido0410/motion-canvas

Motion Canvas — 使用 TypeScript 生成器场景(makeScene2D, yield*, refs, signals, all/chain/sequence/waitUntil)创建代码驱动的 2D 解说/动画视频,包含实时编辑器,并可渲染为图像序列或 MP4(@motion-canvas/ffmpeg)。当用户请求 Motion Canvas 或需要制作与画外音同步的解说动画(非 Remotion 实现)时使用。

motion-canvas 是什么?

Motion Canvas 是一个代码驱动的动画框架,专为开发者设计,用于通过 TypeScript 生成器函数创建精确控制的 2D 解说视频和动画。它提供了一种声明式但命令式的编程模型,核心是通过 `yield*` 操作符在时间线上逐个步骤地执行动画,并内置了 `all`、`chain`、`sequence` 等丰富的流程控制 API,让时间线编排清晰直观。与 Remotion 不同的是,Motion Canvas 更注重“按顺序播放”的叙事方式,并包含一个可视化编辑器,可让您精确地将动画事件与画外音或音频时间点对齐(通过 `waitUntil` 和命名事件)。该工具集成了实时预览编辑器,支持图像序列和 FFmpeg 导出直出 MP4 视频,并原生支持 SVG、代码高亮、LaTeX 公式等 2D 组件。它适用于 Node 16+ 环境,通过 `npm init @motion-canvas/latest` 快速搭建项目,是创建技术解说、代码演示、教学视频和动态信息图的理想选择。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/phido0410/claude-video-skills/tree/HEAD/skills/motion-canvas

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Motion Canvas

检查时间 2026-10: @motion-canvas/core, /2d, /ffmpeg 3.17 版本。需要 Node 16+。

Remotion 对比 Motion Canvas:Remotion = React,帧 → UI,适用于数据驱动/模板视频和服务器端渲染。Motion Canvas = 命令式时间线(yield* 一步步执行),并带有用于画外音时间对齐的编辑器。每个视频选择其一,不要混合使用。

设置

npm init @motion-canvas@latest   # 命名,选择 TypeScript,选择 "Video (FFmpeg)" 导出器
npm install
npm run serve                    # 编辑器在 http://localhost:9000
src/project.ts        # makeProject({ scenes: [...] })
src/scenes/*.tsx      # 每个文件一个场景
// src/project.ts
import {makeProject} from '@motion-canvas/core';
import intro from './scenes/intro?scene';   // ?scene 后缀是必需的
export default makeProject({scenes: [intro]});

场景

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(                                   // 并行执行,等待所有完成
    circle().position.x(300, 1).to(-300, 1),     // 补间:prop(值, 秒数),用 .to() 链式调用
    circle().fill('#e6a700', 1).to('#e13238', 1),
  );
  yield* waitUntil('title');                    // 命名时间事件,可在编辑器时间线中拖动
  yield* circle().scale(2, 0.6, easeInOutCubic);
});
  • 坐标:原点在视图中心;x, y, size, width, height, rotation, scale, opacity, fill, stroke, lineWidth。
  • 组件:Rect(radius 用于圆角),Circle,Line / Spline(points, end 用于绘制),Txt,Img,Video,Layout(flexbox:layout direction gap),Code,Latex。
  • 属性:用值调用则设置该值;用 (值, 秒数[, 缓动函数]) 调用则进行补间动画,且必须被 yield*;无参调用则读取当前值。

流程

调用效果
all(...t)一起执行,等待全部完成
any(...t)一起执行,等待第一个完成
chain(...t)依次执行
sequence(0.2, ...t)每个比前一个晚 0.2 秒开始(不等待前一个完成)
delay(0.5, t)延迟 0.5 秒后开始
loop(3, () => t)重复执行
waitFor(1.5)暂停 1.5 秒
waitUntil('event')暂停直到编辑器中的命名事件触发——用于画外音同步
useDuration('event')返回命名事件的时长,用作补间动画的持续时间

渲染

  • 编辑器 → 渲染面板:分辨率,帧率(24/30/60),范围,导出器。点击 RENDER。
  • 输出文件位于 /output 目录。默认导出器输出图像序列;如需输出带音频的 MP4,请添加 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()]});

然后在视频设置中选择 Video (FFmpeg)。

  • 分辨率更改不会缩放布局;请在布局之前确定最终大小(例如 1920×1080 或 1080×1920)。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相关技能