OpenMontage HyperFrames 机械类转场实战:Shutter 快门与 Clock Wipe 时钟扫场的 GSAP 实现解析
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
本文基于 OpenMontage 仓库中的技能文档 css-mechanical.md,完整解析 HyperFrames 多场景合成中"机械类(Mechanical)"转场的两个标准实现——Shutter(上下快门)与 Clock Wipe(时钟扫场),覆盖完整 GSAP 时间轴代码、clip-path 九点多边形插值原理、缓动函数选择、多场景合成的硬性规则,以及转场代码在确定性与可 seek 渲染约束下的编写规范。读完本篇,你可以在 1920×1080 的 HyperFrames 合成中直接写出可复现、可回退(seek-safe)的机械类转场,并理解其背后"定位新场景 → 动画退出 → 换场 → 清理覆盖层"的通用骨架。
文档定位:hyperframes-animation 技能中的转场知识体系
OpenMontage 将 AI Agent 的视频制作知识组织为技能文件(skill),其中 SKILL.md 是整个动画技能的路由入口,声明了"rules(原子动效规则)/ blueprints(多相位场景模板)/ transitions(场景间转场)/ techniques / adapters(七种运行时适配)"的知识分层。转场知识集中在transitions/子目录,分三层协作:
| 文件 | 职责 |
|---|---|
| overview.md | 转场选型:能量/情绪 → 转场类型映射、预设、叙事位置、CSS 与 Shader 取舍 |
| catalog.md | 转场硬性规则、1920×1080 场景模板、各分类的代码入口 |
css-*.md(12 个分类) | 每个分类的逐行实现代码,机械类即 css-mechanical.md |
catalog.md 给出全部转场分类的完整路由表,机械类是其中一员:
| 类型 | 转场 | 参考文件 |
|---|---|---|
| Push | Push slide, vertical push, elastic push, squeeze | css-push.md |
| Radial / Shape | Circle iris, diamond iris, diagonal split | css-radial.md |
| 3D | 3D card flip | css-3d.md |
| Scale / Zoom | Zoom through, zoom out | css-scale.md |
| Dissolve | Crossfade, blur crossfade, focus pull, color dip | css-dissolve.md |
| Cover | Staggered blocks, horizontal blinds, vertical blinds | css-cover.md |
| Light | Light leak, overexposure burn, film burn | css-light.md |
| Distortion | Glitch, chromatic aberration, ripple, VHS tape | css-distortion.md |
| Mechanical | Shutter, clock wipe | css-mechanical.md |
| Grid | Grid dissolve | css-grid.md |
| Other | Gravity drop, morph circle | css-other.md |
| Blur | Blur through, directional blur | css-blur.md |
| Destruction | Page burn | css-destruction.md |
机械类的定位在 overview.md 的"情绪 → 转场"表中很明确:Shutter 属于"冷峻/临床"与"编辑/杂志感"情绪(内容被机械地压缩、裁切、分栏,"像翻一页或切一个版面,干净的方向性运动");Clock Wipe 属于"俏皮/趣味"与"复古/模拟"情绪(旋转、步进、有机不完美)。
编写约定:场景模板与old/new/T三符号
css-mechanical.md 中的代码不依赖任何具体场景 ID,它约定了三枚符号(见 catalog.md 的"CSS Transitions"一节):
old:退出场景(outgoing scene-inner)的选择器;new:进入场景(incoming)的选择器;T:转场开始时间(秒)。
而每一处转场都遵循同一条硬规则,catalog.md 原文:"position new scene → animate outgoing → swap → animate incoming → clean up overlays"(定位新场景 → 动画退出 → 换场 → 动画进入 → 清理覆盖层)。Shutter 与 Clock Wipe 的代码正是这一骨架的两次具体化。
catalog.md 同时给出了所有 CSS 转场共享的 1920×1080 场景模板,可直接复制运行:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> <style> body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: #000; font-family: "YOUR FONT", sans-serif; /* compiler embeds supported fonts automatically */ } .scene { position: absolute; top: 0; left: 0; width: 1920px; height: 1080px; overflow: hidden; } #scene1 { z-index: 1; background: #color; } #scene2 { z-index: 2; background: #color; opacity: 0; } </style> </head> <body> <div id="root" >tl.to("#shutter-top", { y: 0, duration: 0.25, ease: "power3.in" }, T); tl.to("#shutter-bot", { y: 0, duration: 0.25, ease: "power3.in" }, T); tl.set(old, { opacity: 0 }, T + 0.25); tl.set(new, { opacity: 1 }, T + 0.25); tl.to("#shutter-top", { y: -540, duration: 0.25, ease: "power3.out" }, T + 0.3); tl.to("#shutter-bot", { y: 540, duration: 0.25, ease: "power3.out" }, T + 0.3);面板几何:540 = 1080 / 2
代码中的±540不是魔法数字。合成高度为 1080px,快门由两块1920×540的面板组成:#shutter-top占据上半屏(top: 0),#shutter-bot占据下半屏(top: 540)。两块面板的初始状态用y位移推出画外(顶部面板y: -540、底部面板y: +540),因此y: 0恰好是"完全闭合"位置,y: ±540恰好是"完全打开"位置。这也印证了 SKILL.md 中"空间运动只用 GSAP 变换别名(x/y/scale/rotation),且布局常量必须预先计算"的约束——540 是写死的常量,而不是在 tween 时测量 DOM 得来。
时间轴结构:换场藏在闭合的 0.05s 缓冲里
| 时间 | 动作 | 说明 |
|---|---|---|
T | 两块面板y → 0,0.25s,power3.in | 合拢:先慢后快的"拍合"手感 |
T + 0.25 | tl.set(old, { opacity: 0 })与tl.set(new, { opacity: 1 }) | 画面完全被快门遮挡的瞬间完成场景互换 |
T + 0.3 | 两块面板y → ∓540,0.25s,power3.out | 重新打开,露出新场景 |
两个值得注意的工程细节:
T + 0.25换场、T + 0.3才开合:闭合完成到重新打开之间有 0.05s 的"全黑保持"。这保证在任意 seek 采样点上,opacity互换都不会发生在面板尚未完全闭合的帧上,杜绝了新旧场景穿帮。tl.set而非gsap.set:所有状态切换都带时间参数挂在时间轴上。SKILL.md 的 Non-Negotiable Rules 明确禁止对后续场景使用裸gsap.set(加载即执行、seek 回退后状态失真);带时间参数的tl.set是时间轴成员,可随渲染器逐帧定位而完全复现。Shutter 代码全程只用tl.set,是这一约束的标准写法。
缓动选择也严格对应 gsap-easing-and-stagger.md 的约定".in用于退场、.out用于入场":合拢是"旧画面的退场",用power3.in加速拍合;打开是"新画面的入场",用power3.out减速停稳。整个 Shutter 总时长约 0.55s,落在 overview.md 能量表中"Medium(企业、SaaS、科普)0.3–0.5s"与"开场 0.4–0.6s"的区间内。
Clock Wipe 时钟扫场:九点多边形与四象限步进
Clock Wipe 的视觉定义:以画面中心为圆心、按象限步进展开的径向多边形扫描,模拟时钟指针 12→3→6→9→12 的顺时针 sweep。完整实现见 css-mechanical.md#L20-L29:
tl.set(new, { opacity: 1, zIndex: 10 }, T); var d = 0.1; // duration per quadrant tl.set(new, { clipPath: "polygon(50% 50%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0%)" }, T); tl.to(new, { clipPath: "polygon(50% 50%, 50% 0%, 100% 0%, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 50%)", duration: d, ease: "none" }, T); tl.to(new, { clipPath: "polygon(50% 50%, 50% 0%, 100% 0%, 100% 50%, 100% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%)", duration: d, ease: "none" }, T + d); tl.to(new, { clipPath: "polygon(50% 50%, 50% 0%, 100% 0%, 100% 50%, 100% 100%, 50% 100%, 0% 100%, 0% 50%, 0% 50%)", duration: d, ease: "none" }, T + d*2); tl.to(new, { clipPath: "polygon(50% 50%, 50% 0%, 100% 0%, 100% 50%, 100% 100%, 50% 100%, 0% 100%, 0% 50%, 0% 0%)", duration: d, ease: "none" }, T + d*3); tl.set(new, { clipPath: "none", zIndex: "auto" }, T + d*4 + 0.02); tl.set(old, { opacity: 0, zIndex: "auto" }, T + d*4 + 0.02);为什么必须是 9 个点
这是本文件最核心的技术点,也是 catalog.md 硬性规则中专门列出的一条:"Clock wipe: 9-point polygon with intermediate edge positions. Step through 4 quadrants with separate tweens."(九点多边形、带中间边缘位置;四个象限各用一个独立 tween。)
原因在 GSAP 对clip-path: polygon()的插值机制:两个关键帧的多边形点数必须一致才能逐点插值。四个角(12/3/6/9 点方向)只描述出 5 个点(含中心),无法表达扫场的中间状态。因此模板固定为 9 个点——第 1 点恒为中心(50% 50%),其余 8 个点沿边框顺时针排布,未到达的点位与已到达的点位重合堆叠在同一坐标上(例如初始帧第 2–9 点全部压在(50% 0%)即 12 点钟位置)。这些重合点就是原文档说的 "intermediate edge positions"(中间边缘位置),它们让每一步 tween 都能平滑地"移动"一部分点到新的角点,而不是跳变。
四个 tween 的展开轨迹(每步d = 0.1s):
| 步骤 | 时间 | 多边形覆盖 | 时钟隐喻 |
|---|---|---|---|
初始tl.set | T | 仅中心 + 12 点方向一条零面积线 | 指针停在 12 点 |
| tween 1 | T → T+d | 右上象限(3 点方向两角展开) | 12 → 3 |
| tween 2 | T+d → T+2d | 右半屏(下移到 6 点) | 3 → 6 |
| tween 3 | T+2d → T+3d | 四分之三(进入左下象限) | 6 → 9 |
| tween 4 | T+3d → T+4d | 全幅(末点落到 9→12) | 9 → 12,满屏 |
每步用ease: "none"(线性):gsap-easing-and-stagger.md 明确把线性缓动的适用场景写为"camera moves with timed counterpoint,mechanical motion"。四个等时、等速的象限步进,正是机械钟摆/秒针的离散节律——这正是"Mechanical"分类名下的动效性格。
层级与清理:zIndex: 10和+0.02缓冲
T时刻tl.set(new, { opacity: 1, zIndex: 10 }):新场景提到顶层,旧场景留在下方透过 clip-path 可见——扫到哪、看到哪;- 收尾在
T + d*4 + 0.02:clipPath: "none"、双方zIndex: "auto"、old置opacity: 0。+0.02同样是 seek 安全缓冲——清理动作严格晚于最后一个 tween 结束,任何采样点都不会出现"扫描尚未满屏就还原 clip-path"的中间态; - 与 catalog.md 的 z-index 硬规则对照:Gravity drop、zoom out、diagonal split 要求退出场景在上层(
zIndex: 10);而 Clock Wipe 是"覆盖式揭示",要求进入场景在上层。两个方向都是"谁在被揭示,谁在底层"这一原则的体现。
缓动选型小结:机械感从何而来
对照 overview.md 的能量/预设表与 gsap-easing-and-stagger.md 的缓动词汇表,机械类转场的两个实现分别示范了两种"机械"语言:
| 转场 | 缓动组合 | 手感 |
|---|---|---|
| Shutter | 合拢power3.in/ 打开power3.out,各 0.25s | 有重量感的拍合与停稳,接近"戏剧性预设"(dramatic:power3.in → out,0.5s) |
| Clock Wipe | 四段none(线性),每段 0.1s | 无加减速的等时步进,纯机械钟感 |
overview.md 的预设表可直接作为调参起点:
| 预设 | 时长 | 缓动 |
|---|---|---|
snappy | 0.2s | power4.inOut |
smooth | 0.4s | power2.inOut |
gentle | 0.6s | sine.inOut |
dramatic | 0.5s | power3.in → out |
instant | 0.15s | expo.inOut |
luxe | 0.7s | power1.inOut |
如果整片能量偏高(promo、体育、发布会),Shutter 的 0.25s/段可以整体压缩向snappy/instant靠拢;如果是复古、编辑感的成片,则保持甚至放宽到gentle区间。
选型与叙事位置:什么时候该用机械转场
overview.md 给出了一套完整的决策表,机械类在其中有明确的槽位:
情绪 → 转场(节选机械类相关行):
| 情绪 | 可选转场 | 为什么有效 |
|---|---|---|
| 冷峻 / 临床 | Squeeze, zoom out, blinds,shutter, grid dissolve | 内容被机械地压缩、缩小、裁切、栅格化 |
| 编辑 / 杂志 | Push slide, vertical push, diagonal split,shutter | 像翻页或切版面,干净的方向性运动 |
| 俏皮 / 趣味 | Elastic push, 3D flip, circle iris, morph circle,clock wipe | 过冲、回弹、旋转、展开 |
| 复古 / 模拟 | Film burn, light leak, VHS,clock wipe | 有机的不完美 |
叙事位置 → 用法(全表继承自原文档):
| 位置 | 用法 | 原因 |
|---|---|---|
| 开场 | 全片最有辨识度的转场,0.4–0.6s | 奠定整片的视觉语言 |
| 相关要点之间 | 主力转场,保持一致,0.3s | 不打断——内容在延续 |
| 话题切换 | 换一种与主力不同的转场:staggered blocks、shutter、squeeze | 提示"新章节",观众大脑重置 |
| 高潮 / 主角亮相 | 最重的 accent,最快或最戏剧化 | 这是 payoff,把最好的转场花在这里 |
| 收尾段 | 回到轻柔:blur crossfade、crossfade,0.5–0.7s | 让观者在高潮后喘口气 |
| 片尾 | 最慢最简单:crossfade、color dip to black,0.6–1.0s | 收束,结尾不引入新能量 |
配套的总原则(overview.md 原文):**全片只选 1 个主力转场(占 60–70% 的场景切换)加 1–2 个 accent,绝不为每个场景换一种转场。**Shutter 适合承担"话题切换"这个结构角色,Clock Wipe 则更适合作为复古/趣味成片的开场签名。
与自动化转场注入的关系:TRANSITION-REGISTRY 的边界
仓库中还有一个机器可读的转场注册表 TRANSITION-REGISTRY.md,供 PLV(product-launch-video)流水线的确定性注入器读取,自动向主时间轴 stamped 转场模板。需要区分的是:该注册表是精选的 Tier-B 子集(crossfade、blur-crossfade、push-slide、zoom-through、squeeze 五个),其准入标准是"只动两个场景 clip 包装器的 transform/opacity/filter、不注入额外 DOM 覆盖层"。Shutter 依赖两块额外 DOM 面板、Clock Wipe 依赖多帧 clip-path 关键帧,均属于需要手工编排在场景脚本内的转场——即本篇 css-mechanical.md 所承载的作者路径。注册表文档也明确说明:覆盖类(staggered blocks、blinds、light leak、grid dissolve、page burn)与 shader 转场"推迟到后续阶段"。因此,机械类转场目前应在遵循 catalog.md 场景模板与硬规则的前提下手工编写,而五个 Tier-B 转场可交由注入器按__OLD__/__NEW__/__T__/__DUR__占位符自动 stamped。
实践要点清单
- 骨架不变:任何转场都按"定位新场景 → 动画退出 → 换场 → 动画进入 → 清理覆盖层"编写,
old/new/T三符号约定保证代码可移植; - 一切状态切换用
tl.set带时间参数,杜绝裸gsap.set;换场点放在完全遮蔽的瞬间,并留 0.02–0.05s 缓冲; - 布局常量预计算(如 540 = 1080/2),tween 期间不测 DOM;空间运动只用
x/y/scale/rotation别名; - clip-path 多边形关键帧点数必须一致,用重合点表达"中间边缘位置",这是 Clock Wipe 可用可插值的根本前提;
- 缓动即性格:机械感 =
power3.in/power3.out的重量拍合 +none的等时步进,与情绪表(冷峻/编辑/俏皮/复古)对号入座; - 全片转场预算 2–3 种,Shutter 做话题切换的 accent,Clock Wipe 做开场签名,避免每场一种的"廉价感"。
以上全部代码与规则可在仓库中直接查证:转场实现见 css-mechanical.md,硬性规则与场景模板见 catalog.md,选型决策表见 overview.md,缓动语义见 gsap-easing-and-stagger.md。
【免费下载链接】OpenMontageWorld's first open-source, agentic video production system. 12 production pipelines, 100+ tools, 700+ agent skill and production-knowledge files. Turn your AI coding assistant into a full video production studio.项目地址: https://gitcode.com/GitHub_Trending/op/OpenMontage
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考