Motion
用代码编写动态图形:每个颜色、时间和边距都来自品牌文件,且未经用户预览2-3帧草图绝不渲染。以下规则来源于实际修改经验;每条都说明了其存在的原因。
用途
| 类型 | 说明 |
|---|---|
| 动画 Broll | 用全屏场景或图形覆盖一段配音 |
| Alpha | 带有透明通道的图形,叠加在视频上方或人物背后 |
| 弹窗 | 一个数据点,进入、停留约1秒后消失 |
| 字幕 | 无框字幕,每句突出一个关键词;或动态字幕(仅关键词) |
| 聊天模拟 | 可信且可读的即时通讯应用对话 |
| 屏幕 | 一个网页或桌面应用,以4:3卡片形式呈现,带有标题 |
| 封面 | Reel 的第0帧 |
在排版前,决定采用以下两种方式之一:
- 展示数据或产品内部(面板、指标、收件箱):平面密集界面,所有内容同时可读,卡片内使用真实照片和视频,摄像机几乎静止(缩放 1.00 → 1.02)。状态在当前位置变化:行已存在,仅其标签改变。画面要充实。
- 讲述一个场景:以素材为主。大景别,摄像机真实运动,少量装饰,仅一个句子。
流程图不是一种图形类型:如果想法可以用箭头图表示,则直接通过展示产品来实现。
准备
- 一个 Remotion 项目(
npx create-video@latest),Node 和 ffmpeg。 - 品牌代码 放在
src/marca/:tokens.ts(颜色、字体、圆角、边距),movimiento.ts(时间和曲线),以及一个useMarca()钩子,将所有内容按比例输出。如何构建,请参考示例:referencias/tokens.md。 - 每个图形类型一个入口(
src/piezas/<pieza>.tsx,包含其registerRoot和Composition):这样包很小,且一个图形不会破坏另一个。 - 画布为 1080×1920,30 fps,除非序列另有指定:在开始前,先读取序列的分辨率和帧率。
工作流程
- 简报。 序列中的确切区间(入点 → 出点),该区间配音内容,允许的数据及其来源,可用的素材以及不想要的内容。如果缺少任何信息,请询问。
- 配音。 逐词转录配音,必须依据时间线上的实际内容,而非原始文件(referencias/subtitulos.md)。实际拍摄的配音通常与脚本不同。
- 时长。 区间的长度,保存在一个常量中,注释中包含时间码,再加1帧缓冲:
export const DURACION = 157; // 00:00:51:22 → 00:00:56:29。 - 设计。 视觉内容必须与配音逐句对应。动画和声音共享的时刻(每条消息进入、每个节拍)保存在一个常量中,由合成和效果脚本读取。
- 草图。 使用
remotion still生成2-3个关键帧,并绘制安全区域参考线。展示给用户并等待确认。 - 渲染 带背景或带 Alpha(见下文)。
- 音效。 所有动画都附带其音效:将时间点传递给
sonido技能。 - 检查与交付(见本页末尾)。
不可违背的规则
- 任何颜色或尺寸都不能直接在组件中硬编码: 全部从令牌中获取。原因: 改变色调只需修改一个文件,没有人会为每个图形发明一个新的灰色。
- 每帧只突出一个元素, 使用品牌强调色:标题中的一个词 或 一个按钮,不能同时出现。原因: 如果两个东西都在“喊叫”,则都不可读。(模拟界面本身的颜色不算。)
- 没有弹跳效果。 入场和退场使用令牌中定义的时间和曲线;禁止使用
spring()。原因:spring()会过头再弹回,这看起来像玩具。 - 时间以秒为单位,绝不用帧。 原因: 如果使用帧作为延迟单位,从30 fps切换到60 fps会使速度加倍。
- 安全区域,留白(数字表格)。可读内容距离边缘约100像素,距离顶部约290像素:54和224是不可触碰的界线,而非设计基准线。原因: 应用界面会遮挡边缘,紧贴边界会显得“所有东西都太靠边”。
- 合成中心位于 x 540。 不要为了避开应用按钮而移动设计:落在该高度的内容将对称地收窄。原因: 偏移的合成比叠加上去的图标更显眼。
- 每个对象完整显示在画面内。 不得被边缘裁剪;不主导画面的内容应通过淡出移开。原因: 被裁剪的手机或卡片看起来像错误。
- Broll 必须有事发生: 摄像机必须移动,并且发生一个具体的动作,该动作就是配音中的那句话,而非主题。原因: “什么都没发生”是最常见的驳回理由。例外是客户的实际产品:它被播放,而非重新创作或为其发明动作。
- 最多每4秒出现新内容, 且不得连续出现两个相同的运动。原因: 两个连续的拉近会模糊剪辑点。
- 结尾不能静止: 在最后一段使用极慢的推近。原因: 冻结的画面看起来像渲染错误。
- 上升的数字是图表;出现的数字是标签。 在 Alpha 中,每个数字都带有其动画对象(计数器、测量仪、进度条、作用中的图标),文字相伴。原因: 视频上方的纯文本看起来像字幕。
- 长镜头、深度和细节。 摄像机遍历场景而非离散入场,对象位于不同深度,每个元素都有名称、时间和状态。原因: 那些空白过多的图表类图形曾被拒绝为“过于简单”。
- 无框字幕,每句突出一个词; 切勿放在 Broll 上或图形已表达相同内容的地方(referencias/subtitulos.md)。
- 模拟聊天必须可读: 手机居中,整个应用均匀放大,一次显示一条消息,并留有阅读时间;要突出显示时,模糊其余部分,而非使用暗色遮罩(referencias/alfas-y-chats.md)。
- 画面中的真实屏幕具有最高优先级: 任何元素不得覆盖其文字或头部;弹窗应放在空白区域。
- 无黑色边缘或硬边: 如果摄像机在素材上移动,最小缩放为 1.04(如果画面横向移动则为 1.18);使用平滑步进渐变和圆角。原因: 缩小时露出黑色,或阶梯状渐变,看起来像画框。
- 不得编造数据或重复使用图形。 数字、名称和截图必须来自用户;模拟聊天不得展示真实客户数据。每个图形应带有自己的图表:重复使用其他图形的图表会很明显。
- 动画必须适配配音, 绝不能反过来:不得为了配合图形而在配音中插入静音。
- 修改后不渲染整个画面: 仅渲染发生变化的片段,拼接后使用新文件名(referencias/3d-y-trampas.md)。原因: 已放置的版本不会被覆盖,也不会为了三秒钟而浪费一小时渲染时间。
数值
| 项目 | 数值(1080×1920 画布) |
|---|---|
| 两侧 | 每边 54 像素(可读内容距边缘约 100 像素) |
| 顶部 | 可读内容不高于 y 224(可读内容从约 y 290 开始) |
| 可读区域 | y 420 到 y 1495 |
| 按钮列 | 从 x 897 开始,从 y 1228 向下;在该高度,可读内容位于 x 183–897 内 |
| 大而宽的数字 | 完全位于 y 1228 上方 |
| 特写中的手机 | 最多占画面宽度的 0.8 |
| 全景中的集合 | 最多宽 1080 − 2 × 54 |
| 弹窗 | 屏幕停留略多于 1 秒,然后消失(如果停留,8 秒后会有六条,一条都读不了) |
| 节奏 | 每 4 秒或更短时间出现新内容 |
| 摄像机在素材上移动的最小缩放 | 1.04(横向移动时为 1.18) |
| 数据类图形的填充率 | 约 75% 的可用空间;低于 50% 看起来像草图 |
| 场景类图形的填充率 | 40–60% |
| 封面裁剪 | 信息流 4:5:y 285–1635 · 个人资料 3:4:y 240–1680 |
填充率指可用空间中被非背景内容占据的部分;基于静态图像测量,而非肉眼判断。
渲染
# 草图:单帧
npx remotion still src/piezas/mi-pieza.tsx MiPieza out/boceto_f45.png --frame=45
# 带背景(不透明:覆盖下方画面)
npx remotion render src/piezas/mi-pieza.tsx MiPieza out/mi-pieza_FONDO.mov \
--codec=prores --prores-profile=4444 --pixel-format=yuv444p10le
# 带 Alpha(透明:下方视频可见)
npx remotion render src/piezas/mi-pieza.tsx MiPieza-Alfa out/mi-pieza_ALFA.mov \
--codec=prores --prores-profile=4444 --pixel-format=yuva444p10le --image-format=png
# 任何包含 3D(CSS 或 three.js)的图形,在静态图和渲染中:--gl=angle
- 背景和 Alpha 是同一个合成,通过一个
transparente属性区分;Alpha 版本不绘制画布,其 ID 以-Alfa结尾。 - 仅
--prores-profile=4444并不保证 Alpha。 验证方法:ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt -of csv=p=0 out/mi-pieza_ALFA.mov必须以yuva开头。 - Alpha 模式下无画布:每个文本都需要自己的表面,否则会在暗色素材上消失。
- 如果磁盘空间紧张:带 Alpha 的 ProRes 4444 在 1080 分辨率下每分钟约占用 1.35 GB。通过 ffmpeg 转换为 MOV 内的 PNG(
ffmpeg -i x.mov -c:v png -pix_fmt rgba y.mov)无损,保留 Alpha,且体积约为原来的七分之一。 - 带透视的界面渲染后文字模糊:使用
--scale=2渲染,然后通过 lanczos 降至 1080。 - 需要生成多张静态图时,使用一次性 bundle 的脚本,完成后删除(referencias/3d-y-trampas.md)。
第0帧封面
- 封面是导出 Reel 的第一帧:
<Sequence durationInFrames={1}>包含封面,整个 Reel 放在<Sequence from={1}>中。平台从视频帧中选择封面;这样可以避免产生单独的文件。如果选择器没有选中第0帧,则设为两帧。 - 人物居中: 中心线 x 540,人物中心约在 y 900–960,且完整位于 4:5 和 3:4 裁剪范围内,标题也在范围内。原因: 个人资料网格和信息流会裁剪封面,而缩略图决定了点击。
- 角落避免大型装饰。交付前,生成一个带有模拟裁剪的版本(4:5 外的遮罩,3:4 线和中心线)并检查。
- 如果通过 ffmpeg 从 JPG 拼接封面,注意色彩范围(referencias/3d-y-trampas.md)。
可选样式:玻璃质感(liquid glass)
iOS 风格玻璃质感,用于卡片和按钮,浅色背景。此样式仅在存在可折射物体、整个场景只有一个光源且内部有动态内容时才有效;否则“看起来像宣传册”。规则和数值见 referencias/cristal.md,该文件还解释了如何遮盖素材中烧录的文字。没有样式是永久的:每个图形都应带来前一个图形没有的东西。
最昂贵的陷阱
- 冻结视频: 在第0帧之后才入场的
<OffthreadVideo>必须放在 `<Sequence from={entrada} layout=