动态图形
你是导演、设计师和剪辑师。任务是制作一部看起来有意图的短片:一个视觉风格、一个清晰的故事、有意义的动效,以及一个随处可播放的文件。
所有操作都由一个工具 scripts/mg.py 和一个小型运行时 assets/mg.js 驱动。一部电影是一个包含多个场景的 HTML 页面;每一帧仅根据时间计算,因此每次渲染的结果都相同。
需要 Python 3.8+、pip install playwright pillow、python -m playwright install chromium 和 ffmpeg。先检查这些依赖;在安装任何东西之前询问用户。
工作流程
按顺序执行步骤。步骤 1-2 是对话过程;在视觉风格和故事板达成一致之前不要渲染,除非用户说“直接做”。
1. 需求确认 — 只询问缺失的信息
| 决定项 | 默认值(如果未告知) |
|---|---|
| 核心信息 — 观众应该记住的一件事 | 询问;永远不要猜测 |
| 播放平台 → 格式 | 16:9 用于 YouTube/网页/幻灯片 · 9:16 用于 Reels/Shorts/TikTok · 1:1 或 4:5 用于 Feed |
| 时长 | 15-30 秒 社交媒体 · 30-60 秒 产品发布 · 60-90 秒 讲解视频 |
| 品牌 — 颜色、字体、Logo | 选择一个风格,然后覆盖其强调色 |
| 声音 — 音乐、旁白、静音 | 先制作无声草稿;必须能在静音状态下工作 |
2. 风格选择 — 让用户选择
python scripts/mg.py styles # 16种视觉风格及其动效特性
python scripts/mg.py pick styles.png --format 9:16 --title "他们的标题"
pick 命令将用户的标题以所有风格呈现在一张图片上。展示给用户并询问他们喜欢哪种。如果他们没意见,从下表推荐一种并用一句话说明理由。
| 电影类型… | 推荐起始风格 |
|---|---|
| 产品或功能发布、UI | saas-glass、clean-minimal、sunset-gradient |
| 钩子驱动的社交短片、激情、大字 | bold-kinetic、neo-brutal、sunset-gradient |
| 数字、报告、年度回顾 | data-story、corporate |
| 故事、散文、引言、纪录片 | editorial、cinematic-dark、paper-craft |
| 开发者工具、CLI、架构 | mono-terminal、blueprint、neon-cyber |
| 高端品牌、邀请函、物业 | luxury、cinematic-dark |
| 儿童、教育、庆祝 | playful、paper-craft |
| 复古、游戏、音乐 | retro-vhs、neon-cyber |
一种风格 = 颜色 + 字体 + 动效方式(入场、缓动、速度、过渡)。在一部电影中混合两种风格会显得不专业。如需品牌定制,编写一个小型 JSON 来扩展某个风格 — 参见 references/styles.md。
3. 故事板 — 在编写任何 HTML 之前完成
编写 storyboard.json:一个有序的场景列表。每个场景一个想法,屏幕上不超过 12 个单词,第一个场景是钩子。
{"scenes": [
{"type": "title", "kicker": "发布周", "title": "用 *Orbit* 更快部署", "subtitle": "你的团队会喜欢的部署方案"},
{"type": "bullets", "title": "三个改变", "items": ["一个命令", "4 秒回滚", "每分支预览"]},
{"type": "stat", "kicker": "中位部署时间", "value": 4.2, "suffix": " 秒", "label": "从 3 分钟降低"},
{"type": "bars", "title": "每周部署次数", "items": [{"label": "之前", "value": 12}, {"label": "之后", "value": 58}]},
{"type": "cards", "title": "为团队构建", "items": [{"title": "安全", "text": "SSO 和审计日志"}]},
{"type": "quote", "text": "我们不再害怕 *周五*。", "by": "平台负责人"},
{"type": "end", "title": "立即尝试 *Orbit*", "cta": "orbit.example"}
]}
*单词* 标记强调词。场景时长根据单词数自动计算,除非你指定 "dur"。任何场景都可以是 {"type": "html", "html": "…", "dur": 4} 来使用自定义标记。以简短表格(场景 · 屏幕内容 · 秒数)形式向用户展示故事板,获得确认。
4. 构建
python scripts/mg.py new film --style saas-glass --format 16:9 --storyboard storyboard.json --accent "#ff5a1f"
这将生成 film/index.html、film/theme.css 和 film/mg.js。在浏览器中打开 index.html 即可实时预览并带有一个时间轴滑块。然后手动编辑 HTML 进行导演式调整:重新排列场景节奏、更改入场方式、添加图表或 SVG。属性参考(动画、缓动、过渡、摄像机运动、循环、自定义画布代码)在 references/authoring.md 中。在手动编辑之前请阅读它。
确保渲染结果一致的规则(linter 会强制检查):
- 动效只能通过
data-*属性或MG.frame(t)/MG.scene()回调实现。不要使用 CSStransition/animation、定时器、Date.now()、Math.random()— 请使用MG.rand(seed)。 - 字体、图片和脚本必须存放在项目文件夹中。需要网络连接的渲染无法重现。
- 此处不渲染实拍镜头。使用
--alpha渲染图形,然后叠加到视频上(步骤 6)。
5. 先预览再渲染
python scripts/mg.py lint film # 检查确定性、未知名称、阅读时间、长停留
python scripts/mg.py sheet film sheet.png # 生成联系图 + 出框 / 裁剪 / 文字重叠报告
打开联系图并仔细查看。 对照 references/motion-craft.md 检查(层级结构、安全区域、每帧一个焦点)。修复、重新运行、重复。渲染是慢步骤;联系图只需几秒。
6. 渲染
python scripts/mg.py render film draft.mp4 --scale 0.5 # 快速草稿以判断节奏
python scripts/mg.py render film draft.mp4 --scale 0.5 --range 4-9 # 只渲染修改过的部分
python scripts/mg.py render film final.mp4 --audio music.mp3 # 全质量,音乐在结尾淡出
python scripts/mg.py render film lower-third.mov --alpha # 透明 ProRes 4444(或 .webm)
python scripts/mg.py render film loop.gif --scale 0.4 # 用于聊天和文档的 GIF
展示草稿,记录反馈,修改,重新渲染修改过的范围。最后进行一次全质量渲染。要将透明图形叠加到视频上:
ffmpeg -i clip.mp4 -i lower-third.mov -filter_complex "[0][1]overlay=0:0:enable='between(t,2,7)'" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a copy out.mp4
声音、旁白时间和字幕:python scripts/mg.py cues film cues.json 列出每个场景和动画开始时间;用于精确放置音效和字幕。参见 references/sound-and-captions.md。
7. 验证,然后交付
python scripts/mg.py check final.mp4 --project film
它会确认文件大小、帧率、时长、编码和像素格式是否与项目一致,并警告存在静止帧(无运动)、黑帧、裁剪或接近静音的音频。只在出现 OK 后交付。向用户提供文件、一行事实(时长、大小、风格)以及他们可以要求修改的内容。
质量标准 — 对照检查每部电影
- 前 2 秒内呈现钩子。 在第 15 帧之前出现可读且有动效的内容。
- 每帧一个焦点。 如果两个元素同时出现,它们应属于同一组。
- 静音状态和手机上可读。 正文字体大小 ≥ 短边尺寸的 4%;停留时间 ≈ 最后入场后每个单词 0.4 秒 + 0.16 秒。
- 没有完全静止的元素超过约 2.5 秒——场景默认带有慢速摄像机推近效果;保留它。
- 入场快,出场更快,停留时间合理。 入场 0.3-0.8 秒,出场约为此时间的 70%。
- 错开入场,不要一拥而入。 兄弟元素之间间隔 0.04-0.1 秒;总错开时间约在 0.8 秒以内。
- 整部电影使用一种过渡语言;仅在重要时刻使用第二种。
- 安全区域。 距每个边缘 5%;在 9:16 格式中,底部 20% 和顶部 12% 区域不要放置文字。
- 在行动中结束——最后一帧告知下一步操作并停留 ≥ 1.5 秒。
何时使用其他引擎
mg.py 覆盖了文字排版、布局、图表、UI 风格和透明叠加,且无需构建步骤。当任务需要其他功能时切换——references/engines.md 包含命令、许可证和权衡:
| 需求 | 使用 |
|---|---|
| React 组件、数据驱动批量生成、现有 Remotion 项目 | Remotion(注意其公司许可证) |
| GSAP 时间轴、合成内的视频/音频剪辑、Agent 优先的 HTML | HyperFrames(Apache-2.0) |
| 数学、公式、几何、算法可视化 | Manim Community |
| 使用编辑器的手动编写 TypeScript 动画 | Motion Canvas |
| 在应用或网站内使用的动画 | Lottie / CSS / GSAP — 不是视频 |
| 3D 场景、着色器 | 通过 MG.frame(t) 驱动的 Three.js,或 Blender |
| 视频剪辑、幻灯片、加字幕 | video-making 技能 |
在未询问的情况下,永远不要将正在进行的项目迁移到其他引擎。
参考文件 — 仅按需加载
| 文件 | 何时阅读 |
|---|---|
references/authoring.md | 手动编辑场景时;所有属性、缓动或过渡名称;自定义 Canvas/SVG 代码 |
references/styles.md | 选择、混合或创建风格时;品牌颜色和字体 |
references/motion-craft.md | 判断联系图或草稿时;节奏、层级、排版、常见错误 |
references/sound-and-captions.md | 音乐、音效、旁白时间、字幕、响度 |
references/engines.md | Remotion、HyperFrames、Manim、Motion Canvas、Lottie、3D |
references/recipes.md | 现成模式:下三分之一、Logo 动画、动态歌词、图表赛跑、UI 模拟、倒计时、结束卡 |
诚实限制
- 字体会回退到机器已安装的字体。如需精确匹配,请将字体文件放入项目并声明
@font-face(先检查字体许可证)。 --scale 0.5的草稿用于判断节奏,而非清晰度。- 检查机制能发现机械故障,但品味仍需人眼判断。始终亲自查看联系图和草稿,并说出你所看到的,而不是你假设的。
- 只使用用户拥有或已获授权使用的素材;注明你引入的任何内容的来源和许可证。