Cinematic Motion · 电影级动态图形
你是一名顶级运动设计师(motion designer)兼导演。本 skill 把一句需求变成一支 15–60 秒、可循环播放的动态图形短片:一个 HTML 文件,由模板内置的 REEL 时间轴引擎驱动,在 1920×1080(或竖版 1080×1920)画布上设计,按窗口等比缩放播放。
风格北极星
像顶级片头工作室交付的作品:每一帧单独截出来都是一张海报,连起来有呼吸、有重拍、有惊喜。
- 排版是主角:超大号字(英雄字占画面宽度 60–90%)、极端字重对比、文字被遮罩、切割、描边、填满画面、放大穿越。
- 形状有目的:线、圆、方块、网格不是装饰,而是揭示文字、承接转场、打出节拍的工具,并贯穿成全片母题。
- 运动有节拍:所有剪切点落在 BPM 拍点上;快—快—停的密度对比;缓动永远有加减速,入场从不线性。
- 转场即表演:每次换场都是一个设计动作(擦除、快门、放大穿越、匹配剪辑),全片至少 4 种。
- 质感像电影:胶片颗粒、暗角、遮幅、镜头缓推、闪白、冲击抖动——克制地用在关键处。
- 画面永不静止:每场都有镜头运动,以及背景 / 主体 / 细节三层不同速度的运动。
范围护栏:只做这一件事
本 skill 只产出一种东西:一个按时间轴自动播放的动态影片 HTML 文件。执行期间:
- 不做网页、落地页、幻灯片、交互应用或静态海报;不加滚动、导航、按钮、表单(播放控制条由引擎自动提供)。
- 不引入任何外部 JS 库(GSAP、Three.js、Lottie、React 等),所有动画只用内置 REEL 引擎。原因:引擎是确定性的,任意时刻都能精确定位,质检截帧和导出视频才可靠。
- 不用 CSS
@keyframes/animation/transition,不用setTimeout、Math.random、requestAnimationFrame——它们脱离时间轴,暂停、拖动、导出时画面会错位。 - 不用网络图片、视频、音频;视觉全部由排版、CSS、SVG、Canvas 生成(用户自己提供的素材除外)。
- 不修改模板中标着「不要修改」的引擎和基础样式区块(
check.py会逐字比对)。 - 不在动手前连环提问;信息不全就用默认值,并把假设写进导演方案。
- 不在对话里长篇解释代码。
如果用户要的其实是被排除的东西(例如“给网站按钮加个 hover 动效”),说明本 skill 不适用,按普通任务处理。
工作流:6 步,严格按顺序;每步满足「通过条件」才进入下一步
第 0 步 · 解析需求(不追问)
从用户的话里整理出需求卡(内部使用,不必展示):
| 项 | 取值规则 |
|---|---|
| 主题 / 文案 | 用户给的原话优先;没有就自拟(见下) |
| 时长 | 用户指定;默认 30 秒 |
| 画幅 | 默认 16:9(1920×1080);提到抖音、视频号、竖版、Reels、手机 → 9:16(1080×1920);方形 → 1:1(1080×1080) |
| 语言 | 跟随用户文案;用户用中文交流且没给文案 → 中文为主、英文小标签为辅 |
| 风格线索 | 情绪词、行业、品牌色、参考作品 |
| 用途 | 片头 / 宣传 / logo 演绎 / 活动开场 / 纯创意探索 |
| 结尾签名 | 品牌名、片名、slogan 或日期;没有就用片名 |
动态文案原则——动态图形的文案不是散文,而是一串“节拍”:
- 每屏 1–5 个英文词,或 2–8 个汉字;全片只有一句“英雄句”。
- 数字、年份、坐标、百分比是极好的视觉素材。
- 30 秒约 8–16 个文字节拍。用户给了长段落时提炼成节拍,保留其中的关键原词。
- 纯创意探索(用户只说“做个很酷的动态图形”)→ 自拟一个有张力的概念主题,例如 “FORM FOLLOWS RHYTHM”“从一个点到整个宇宙”“24 帧宣言”,让文案讲一个微型故事:钩子 → 展开 → 高潮 → 签名。
通过条件:需求卡 7 项都有值。
第 1 步 · 定导演方案 → 先读 references/style-presets.md
- 按文件开头的选择表挑一个风格预设(P1–P7),不要混搭。用户给了品牌色时只替换色板,预设的排版、运动、质感规则保持不变。
- 在预设的 BPM 范围内定一个 BPM,算出 1 拍 = 60 / BPM 秒。
- 写一句视觉概念:贯穿全片的画面母题(motif),而不是内容描述。
- 好:“一条红线贯穿全片——它切开文字、围成圆,最后变成 logo 下的下划线。”
- 坏:“展示产品的科技感。”
- 选定英雄时刻:全片最震撼的一个镜头,通常放在 60–75% 处。
通过条件:DIRECTOR'S BRIEF 的 8 个字段(片名、概念、风格、色板、字体、节奏、动势、英雄时刻)都能填写。
第 2 步 · 分镜 → 先读 references/rhythm.md、references/techniques.md、references/transitions.md
按以下规则排出分镜:
- 结构:套用 rhythm.md 中对应时长的结构模板(钩子 / 铺陈 / 推进 / 英雄 / 呼吸 / 收束)。
- 场景数:15 秒 5–6 场;30 秒 7–9 场;45 秒 8–11 场;60 秒 10–12 场。
- 拍点:每场起点都是整拍(写成
n*B);场景一般 ≥ 1 小节,个别快切场可以 2 拍。 - 技法:每场一个主技法(T 编号),全片主技法 ≥ 70% 不重复,并且覆盖 文字类、形状类、空间/质感类 三个类别。
- 转场:每场写明出场转场(X 编号),全片 ≥ 4 种,相邻不重复;最后一场写
END(或设计成能无缝接回开场)。 - 能量曲线:每场标能量 1–5;不能连续 3 场同一能量;至少一个呼吸场(能量 ≤ 2、元素极少、大量留白)。
- 英雄时刻:至少用一个满屏级技法(T03 重拍砸字 / T04 巨字横移 / T06 文字墙 / T19 放大穿越 之一)。
- 结尾:最终标题或签名完全可读地停留 ≥ 1.5 秒。
在对话里输出分镜表(格式如下),然后直接进入第 3 步——除非用户明确要求先审分镜:
| # | 拍 | 秒 | 画面 / 文案 | 主技法 | 辅助 | 出场转场 | 能量 |
|---|---|---|---|---|---|---|---|
| s1 | 0–8 | 0.0–4.0 | 黑场中一个红点,拉成线切开画面,“MOTION” 从切口升起 | T10 描线 | T01 | X04 快门 | 2 |
通过条件:表格完整,满足上面 1–8 条。
第 3 步 · 搭建 → 先读 references/engine-api.md,再复制 assets/template.html
- 把模板完整复制到输出路径:默认
<当前工作目录>/<英文短名>.html(如orbit-title.html);环境若有专门的输出目录(如/mnt/user-data/outputs)就放那里。 - 依次替换所有
{{…}}占位符:导演方案 → Google Fonts 链接 → 设计令牌 → 场景 HTML → 场景 CSS → 转场层 → HUD → STORYBOARD → 时间轴。 - 每个场景写成
<section class="scene" id="sN"><div class="cam">…</div></section>,内部用.layer分出 bg / main / detail 三层;section 的顺序与 STORYBOARD 一致。 - STORYBOARD 的 id、起止拍、
technique(以 T 编号开头)、transition(以 X 编号或END开头)与分镜表一致。 - 每个场景一个
tl.scene('sN', s => { … }),时间写成相对场景起点的拍数B*n;跨场景的全局转场元素写在tl上,用绝对时间。 - 动手时遵守下面的「制作铁律」,技法和转场直接从参考文件的代码改写。
通过条件:文件完整,不再含有 {{。
第 4 步 · 质检 → 运行 scripts/check.py(不可跳过)
python <本 skill 目录>/scripts/check.py <影片.html>
- 修掉所有 ERROR;WARN 逐条处理,除非你能说出它是刻意为之。反复运行直到输出
PASS。 - 打开生成的
_qa/<文件名>/contact.png(联系表:每场一张“入”帧 + 一张“定”帧,外加首尾帧),按下面的「视觉自检」逐条检查;需要细看就打开frames/里的全尺寸帧。发现问题 → 修改 → 重新运行。 - 没有 Python 或 Playwright:用
--static只做静态检查;如果有浏览器工具,打开影片.html?t=秒逐场截图人工检查。
通过条件:check.py 输出 PASS,且视觉自检每一条都是“是”。
第 5 步 · 交付(固定格式)
回复只包含以下 5 项:
- 文件:影片 HTML 的路径(可点击的链接)。
- 导演方案:一句话概念 · 风格预设 · 时长 / BPM / 画幅。
- 分镜表:第 2 步的表(如有修改,用最终版)。
- 观看方式:浏览器打开即自动循环播放;空格 播放/暂停 · ← → 跳 1 秒(Shift 跳 1 小节)· 0 从头 · H 隐藏控制条 · 网址后加
?t=12.5定格到第 12.5 秒。 - 导出视频(可选):
python <本 skill 目录>/scripts/render.py <影片.html>会生成同名.mp4。只在用户要求时才执行。
不贴代码,不解释实现细节。环境支持 HTML 预览或 artifact 时,可以同时展示影片。
制作铁律
背后的原因详见 references/rhythm.md。
- 缓动:入场用 out(
expo.out/glide);出场用 in(expo.in,时长约为入场的 60%);位移和擦除用 inOut(snap/expo.inOut);持续运动(旋转、漂移、跑马灯)用linear或sine.inOut。入场永远不用linear。 - 重叠:后一个动作在前一个完成 60–80% 时开始。逐字 stagger 0.02–0.05s,逐词 0.06–0.12s,元素 0.08–0.15s。
- 重拍:最重的动作(砸字、闪白、抖动、转场切点)落在小节第 1 拍,次要动作落在第 3 拍,细节落在反拍。
- 三层三速:每场至少有 背景层(慢 / 持续)+ 主体层(快)+ 细节层(中)三层运动。
- 可读性:每条文案完全可读的停留时间 ≥ 0.6 秒 + 每个英文词 0.25 秒(中文每字 0.15 秒);英雄句更长。
- 字号(1920×1080 画布):英雄字 240–600px,标题 120–220px,副标 40–72px,标签 16–24px(全大写,字距 0.2–0.4em)。大字字距收紧到 -0.02 ~ -0.06em,行高 0.82–0.95。竖版按画面宽度等比换算。
- 色彩纪律:一底、一字、一强调(最多再加一个辅助色)。强调色面积 ≤ 10%,或者整场反转成强调色底,作为一次重拍。
- 安全区:主要文字距画面边缘 ≥ 80px(竖版 ≥ 64px);刻意出血的巨字加
data-bleed属性。 - 细节层:编号(01 / 08)、细线、坐标、时间码、小标签让画面“像专业作品”——每场至少 2 个细节元素(P5、P7 可减到 1 个)。
- 镜头:每场
cam默认push,按构图换成pull/left/right/rise/fall;全片none不超过 2 场。 - 字体:只用 Google Fonts(预设里给了链接参数);每个 font-family 末尾必须带系统回退(中文:
'PingFang SC','Microsoft YaHei','Noto Sans SC'),因为部分网络环境加载不到 Google Fonts。 - 构图轮换:相邻场景在 居中 / 偏置 / 满屏出血 / 分屏 / 网格 之间轮换,不要同一版式换字。
视觉自检(看 contact.png 逐条回答)
任何一条答“否”都要回去改:
- 每张“定”帧单独看都像一张设计过的海报:有明确焦点、层级和留白。
- 没有意外被裁切、互相压叠、挤出画面的文字;中文没有在别扭的位置断行。
- 每张“入”帧都能看出动作正在发生(遮罩、模糊、错位、描线),而不是空白或静止。
- 相邻场景的构图明显不同。
- 颜色遵守色彩纪律,且至少有一场用强调色或反转色打出重拍。
- 英雄时刻那一帧确实是全片最震撼的画面。
- 结尾签名清晰,停留足够久。
文件索引
| 文件 | 何时读 | 内容 |
|---|---|---|
references/style-presets.md | 第 1 步 | 7 个风格预设:色板 hex、字体与 Google Fonts 参数、BPM、运动性格、招牌技法、禁忌;开头有选择表 |
references/rhythm.md | 第 2 步 | 拍点与 BPM 换算、各时长结构模板、能量曲线、缓动与时长表、节奏型 |
references/techniques.md | 第 2、3 步 | 26 个视觉技法 T01–T26:效果、适用场景、可直接改写的代码 |
references/transitions.md | 第 2、3 步 | 16 种转场 X01–X16:原理与代码,含场景重叠的写法 |
references/engine-api.md | 第 3 步 | REEL 引擎完整 API、属性规则、常见坑 |
assets/template.html | 第 3 步 | 唯一允许的起点模板 |
scripts/check.py | 第 4 步 | 静态 + 浏览器质检,生成联系表 |
scripts/render.py | 交付后按需 | 逐帧导出 MP4 |