RSS

第 5 章 / 共 9 章

让场景动起来:动画、转场与节奏

约 9 分钟 更新于

第4章你学会了读动画代码,这一章要学会「导」动画:把脑子里的「感觉」,翻译成 Codex 能执行、你能验收的一条条指令。我们会把贯穿示例从「一张静态标题卡」升级成一条有节奏的三场景短片:开场标题入场 → 卖点逐条浮现 → 收尾。这一章的核心不是某个炫技 API,而是一套**「动效配方 → 迭代 → 防抖防闪」**的工作方法——它能让你和 Codex 的每一轮对话都越改越准。

5.1 先写「动效配方」再让 Codex 动手

新手让 Codex 做动画,常说「让它动起来、高级一点」。这句话和「剪好看点」一样无效。动画之所以难沟通,是因为它包含太多自由变量:谁动、怎么动、动多久、从哪开始、和上一个动作怎么衔接。

解决办法是每次动手前,先写一张动效配方卡,把每个动作拆成五个固定问题:

配方字段要回答的问题示例(开场标题入场)
对象谁在动?主标题「山雾乌龙」整块
属性动它的什么?透明度 + 垂直位移 + 轻微缩放
时机从第几帧开始、持续几帧?0–40 帧内完成入场
节奏匀速、缓入缓出,还是带弹跳?轻微弹簧感,最后稳稳停住
终点动画结束时的静止状态?完全可见、居中、无位移

写配方卡时,不需要写代码——用自然语言把「谁、动什么、什么时候、什么节奏、停在哪」讲清楚即可。Codex 的工作,就是把这个配方翻译成 interpolate、spring 和样式。而你的验收,就是对照配方逐项看预览:它弹了吗?弹得够不够?是不是 40 帧内停稳的?

5.2 一次典型迭代:标题从底部弹入

假设你对 Codex 说(这是任务卡与配方卡的合并用法):

继续在 src/ 里做动画,不装新依赖。

目标:给「山雾乌龙」标题卡加入场动画,让它有「从底部弹上来再停稳」的感觉。
动效配方:
- 对象:标题整块(主标题+副标题一起);
- 属性:垂直位移从 90px 到 0,透明度从 0 到 1;
- 时机:composition 第 0 帧开始,约 35 帧内完成主体运动;
- 节奏:希望带一点「过头再回弹」的弹簧感,不要纯匀速;
- 终点:第 35 帧后完全静止、完整可见、不遮挡其他元素。
验收标准:
1. 播放前 2 秒,标题应从下方进入并停在中央,不回弹到屏幕外;
2. 动画结束后画面必须稳定,不能继续抖动;
3. 不要改动 Root.tsx 里的时长与画幅;
4. 改完告诉我你用了哪个函数(interpolate 还是 spring)以及为什么。
先看现有代码,给出 3 行以内的实现思路,再动手。

Codex 大概率会用 spring() 实现弹跳感。你验收时重点看三处:是否「过头再回弹」(弹簧感)、是否 35 帧左右稳定、回弹过程是否跑出画布。如果它给的是纯匀速的 interpolate,你回一句:

现在更像匀速上浮,没有「轻微回弹」的弹簧感。请改用带弹性的方案(可查 remotion.dev 的 spring 文档,注意传入 fps),让主体运动在 35 帧内完成、后续只有很小的回弹,并且回弹不要超出画布。

注意这段反馈的结构:先描述你看到的实际效果(匀速上浮),再说你要的目标效果(带回弹),最后给技术方向与约束(查 spring 文档、注意 fps、别出画布)。这比「感觉不对,再改改」高效得多。一次成功的动画迭代,通常就是这样 2–4 轮「看 → 描述差异 → 让它改」完成的;你要做的是把差异描述得越来越精确,而不是替它写代码。

5.3 转场:场景与场景之间怎么接

单卡动画做完,就该处理「场景之间的衔接」——也就是转场。Remotion 里没有剪辑软件那种时间轴,场景衔接完全是代码层面的时间安排,最常见的两种做法:

  • 硬切:一个 Sequence 结束,下一个 Sequence 立刻开始。干净,零成本,适合节奏快的短视频;
  • 交叉淡化:前一个场景末尾透明度渐隐、后一个场景开头透明度渐显,两段在时间上故意重叠。这是最通用的柔和转场。

做交叉淡化不需要额外依赖,本质就是让两个场景重叠的那几十帧里,各自按帧号做透明度插值。代码层面你的验收重点是重叠窗口:比如卖点段从第 90 帧开始,标题段要让出画面,你可以让标题在 75–105 帧渐隐,而卖点从 90 帧开始渐显,于是 90–105 帧之间两段同时半透明——这就是「交叉淡化」的时间结构。让 Codex 动手时,你只需要在配方卡里写清:「场景 A 在结束前 15 帧开始淡出;场景 B 从开始后 15 帧淡入到全不透明;总时长不变,Sequence 时间自行协调」。

如果项目里已经装了 Remotion 官方的转场包(@remotion/transitions 等),也可以让 Codex 按官方文档使用现成转场——但提醒一句:先让它在文档里核对当前用法再写,别让它凭记忆。另外要养成一个时间纪律:视频总时长是你的硬约束(540 帧就是 540 帧),加转场不能偷偷把片子变长;Codex 改完时间安排后,你要核对总帧数没有被改。

第5章:三场景的时间节奏
图 5.1:把一条片子在时间轴上画出来,动画节奏立刻变清晰。图中三场景各有「入场(实心进入) — 稳定(平台期) — 让位(渐隐)」三个状态,场景之间用重叠的交叉淡化衔接。注意看横轴刻度:一切都以「帧」为单位,30 帧 = 1 秒。你在验收动画时,脑子里就应有这样一条时间轴。

5.4 渲染一致性:为什么视频里不能有「随机」

普通网页允许「每次打开都不一样」:今天的时间、实时数据、随机数、网络图片,都无所谓。视频渲染不允许——因为渲染器要一帧一帧地生成 540 帧画面,而且经常要「分帧渲染、并发加速」。如果某帧的画面取决于「此刻几点钟」或「一个真随机数」,那么:同一帧被渲染两次可能得到不同画面;你预览看到的画面,和最终成片里的画面,可能对不上。这就是 Remotion 强调渲染确定性的原因,也是你验收 Codex 代码时必须盯防的一类 bug:

  • 不要依赖系统时钟:代码里不该用 Date.now()、new Date() 之类去决定画面(除非你确实想渲染「此刻的时间」这类内容);
  • 不要依赖真随机:动画抖动、颜色变化若需要随机感,应使用 Remotion 提供的确定性随机工具(它按帧号等固定输入生成「看起来随机但每次一致」的数值),而不是 Math.random();
  • 不要依赖运行时网络:背景图、字体、音频要在渲染前就绪(第7章细讲),渲染时再去联网拉资源是事故高发区;
  • 警惕「运行时 API」:像 setTimeout、requestAnimationFrame 这类异步机制和「逐帧确定」的模型冲突,除非明确用于预加载等待,否则不该出现在画面逻辑里。

你不需要背这些规则的实现细节,但要在验收时养成一问:「Codex,这段代码里有没有依赖时间、随机或网络的东西?如果有,如何保证每一帧是确定的?」 让它自己解释,再对照上面四条检查——这比你自己逐行读代码快得多,也让 Codex 养成「写确定性代码」的习惯。毕竟,一条渲染两次结果不一致的视频,在交付那天一定会背叛你。

5.5 行动:把开场做成三段式动画

到这一步,你的小片已经有了节奏和动感,但内容还是写死的:三条卖点的文案、图片全在代码里。如果下周要换三条内容,难道要 Codex 再改一遍代码?第6章解决这个问题——把内容从代码里拿出来,让一条片子变成「一条模板 + 一份数据」。