HyperFrames Keyframes 关键帧动画实战指南:pose contract、seek-safe 运行时与 CLI 像素级验证
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
导读
本文围绕 HyperFrames 项目的hyperframes-keyframes技能文档,系统讲解在 HTML 组合(composition)中编写 2D/3D 关键帧动画的完整方法论:从"关键帧即姿态契约(pose contract)"的核心思想、创作者编辑边界、GSAP/CSS/Anime.js/WAAPI 的 seek-safe 运行时规则,到hyperframes keyframesCLI 的调试与洋葱皮(onion-skin)像素验证流程。读完本文,你将掌握 punch-in/punch-out、Ken Burns 运镜、路径运动、SVG 描边/形变、3D 景深与 Canvas/WebGL 关键帧等场景的落地写法,并能用 CLI 诊断命令独立证明"动画真的如你所想"。
本文主体依据 skills/hyperframes-keyframes/SKILL.md,机制细节参考其配套的 references/keyframe-patterns.md,实现证据来自 CLI 命令 packages/cli/src/commands/keyframes.ts、运行时适配器 packages/core/src/runtime/adapters/gsap.ts 与全局契约 packages/core/src/inline-scripts/runtimeContract.ts。
一、关键帧是一种"姿态契约"
HyperFrames 中,关键帧不是"锦上添花的动效",而是一份可被验证的四要素契约:
- 可见状态(visible states):动画中间过程必须由明确的姿态(pose)构成,而不是依赖随机或时间触发;
- 连续的主体同一性(continuous subject identity):当连续性重要时,必须是同一个元素在运动,而不是用替身元素做交叉淡入淡出;
- seek-safe 运行时(seek-safe runtime):动画可以在任意时间点被精确跳转(seek)到指定帧,逐帧渲染与预览表现一致;
- 验证像素(verified pixels):最终以渲染出的画面为准——"信任画出来的像素,而不是日志"。
因此,技能文档开篇即强调分工边界:宽泛的场景动画配方使用hyperframes-animation,完整命令文档使用hyperframes-cli,而references/keyframe-patterns.md只在你需要选择具体实现机制(而非视觉风格)时阅读。这一分层可见于技能路由表 skills/hyperframes/SKILL.md,其中将"Seek-safe GSAP、CSS、Anime.js、WAAPI、FLIP、paths、masks、SVG、3D keyframes,或hyperframes keyframes诊断"明确路由到本技能。
关键帧与剪辑的边界:谁拥有什么
关键帧只拥有视觉运动,不拥有剪辑装配。源片段硬切、裁剪、拼接、重排属于hyperframes-core:
- 每个保留区间只放置一个媒体元素,用
data-start与data-duration定位,用data-media-start选择源偏移; - 相邻区间构成硬切;
- 交叉淡化(crossfade)=不同轨道上重叠的剪辑 + 视觉透明度关键帧;
- 声音淡化走
hyperframes-audio。
这条边界在技能中反复强调:视觉过渡或裁剪处理不是时间轴上的源裁剪或拼接。hyperframes-core拥有时间轴、剪辑时序与源区间,关键帧只负责在这些剪辑内部的包装层(wrapper)上动画可见的手势或裁剪。核心库对时序属性的支持可在 packages/core/src/compiler/timingCompiler.test.ts 与 packages/core/src/runtime/playbackRate.ts 中印证。
创作者请求 → 真实机制对照表
下表是技能文档给出的"诉求 → 应采用机制"权威映射,写作时应当直接按此选择方案:
| 创作者诉求 | 真实机制 |
|---|---|
| Punch-in / punch-out | 在剪辑内部的非时序视觉/裁剪包装层上,用x/y或百分比位移配合scale关键帧;硬性 punch 用极短 tween,平滑移动用 tween |
| 平滑多状态缩放或重取景 | 保持一个主体包装层存活,把多个缩放/重取景状态写成带分段缓动的姿态阶梯(pose ladder) |
| 平移、重取景或 Ken Burns 运镜 | 动画包装层的位移加缩放;几何是手工编排的,不是人脸追踪或自动语义重取景 |
| 链式运镜 | 在一条已注册的 seek-safe 时间轴上链接带标签的变换节拍 |
| 匹配剪辑或 whip pan | 视觉交接由hyperframes-animation负责,原语由hyperframes-registry提供;关键帧保留已编排的几何、方向与速度;不存在自动匹配帧发现 |
| 裁剪与遮罩重取景 | 在内部视觉包装层上插值clip-path或遮罩,不改变源时间;多边形关键帧可构成多边形/遮罩过渡 |
| 定向擦除或光圈/揭示剪辑 | 在重叠视觉剪辑上动画遮罩/裁剪边界;交接编排由hyperframes-animation负责 |
| 分屏交接 | 两个视觉剪辑由 core 放置,然后关键帧化它们内部的裁剪/遮罩包装层与分割线几何 |
| 恒定源变速 | hyperframes-core拥有归一化data-playback-rate(取值范围0.1..5),画面渲染安全且声音保持音高;对整个媒体元素恒定 |
| 源速度斜坡 | 不支持:不存在随时间变化的播放速率包络;应先预处理派生媒体资产,再通过 core 放置 |
| 冻结 / 定格 | 视觉姿态、最终源帧或已完成子组合可以保持;任意源中段冻结不支持——预处理一个静帧/派生片段,作为独立剪辑放置,再用另一源区间续接 |
当画面与声音需要一起编辑时,加载hyperframes-core+ 本技能(视觉运动)+hyperframes-audio(淡入淡出、音量自动化、duck/carve、已放置轨道上的效果)。可复制的"画面+声音"组合配方参见hyperframes-core技能中的references/creator-editing-recipes.md。
二、编写流程(Procedure)
技能文档给出五步标准流程:
- 识别动画主体、可见状态、最终状态与运行时长;
- 选择能证明诉求的最小机制(机制不明时才查阅
references/keyframe-patterns.md); - 编写在声明运行时长内的 seek-safe 关键帧:同步构建并注册运行时实例;
- 验证:依次运行
hyperframes lint、hyperframes check、hyperframes keyframes、一次聚焦的--shot,以及在证明时间点的快照(snapshot); - 失败修复:修正源关键帧后,先重跑最小失败诊断,再渲染。
契约(Contract)清单
- 命名移动的主体;
- 命名证明预期运动所需的姿态,包括最终状态;
- 关键帧化可见通道,而不是隐藏的辅助状态;
- 当连续性重要时保持对象同一性;
- 只有当预期运动就是"替换或溶解"时才使用交叉淡化;
- 可读或语义状态保持足够久以便观察;
- 最终帧是动画的一部分,不是收尾清理;
- 除非被要求,不要重置回静止态;
- 除非被要求,不要以黑场结束;
- 如果是在编辑 starter 场景,除非被要求重新设计,否则保留布局、文案、资产、颜色与最终状态。
三、Seek-safe 运行时规则(Runtime Rules)
"可跳转"是 HyperFrames 渲染的硬性前提:预览器与渲染器需要把时间轴精确设置到任意帧。各运行时规则如下。
GSAP
- 页面加载时同步构建;
- 使用
gsap.timeline({ paused: true }); - 注册为
window.__timelines[compositionId]; - 注册键必须与
data-composition-id一致; - 渲染关键运动时不要调用
tl.play(); - 重复次数保持有限(finite)。
window.__timelines正是运行时的全局契约:核心包在 packages/core/src/inline-scripts/runtimeContract.ts 中通过HYPERFRAME_RUNTIME_GLOBALS.timelines = "__timelines"声明该全局键。运行时适配器 packages/core/src/runtime/adapters/gsap.ts 展示了 seek 的实际语义:先timeline.pause(),再把totalTime设置为安全时间——由于 GSAP 3.x 在新 totalTime 等于_tTime时会跳过渲染,适配器会先加 0.001s 强制脏状态,再精确 seek 到目标时间。这就是"构建同步 + 注册到__timelines"被列为铁律的原因:未注册的 timeline 无法被 seek,也就无法逐帧渲染。
CSS keyframes
- 有限时长与有限迭代次数;
- 确定性延迟(deterministic delay);
animation-fill-mode: both;- 当时序属于某个剪辑时使用
data-start。
Anime.js
- 同步创建;
autoplay: false;- 有限时长与有限循环;
- 每个实例推入
window.__hfAnime数组。
WAAPI
- 有限
duration; fill: "both";- 确定性构建;
- 注意:文本诊断面不列出 WAAPI,需用
--shot(它会 seek WAAPI)与快照验证。
渲染关键运动中禁止使用的 API
以下任何一项都会破坏确定性,禁止用于渲染关键运动:
Date.now()performance.now()- 未播种的
Math.random() - 悬停/滚动触发器
- 定时器(timers)
- 异步创建的时间轴
- 未注册的
requestAnimationFrame - 无限循环
四、GSAP 骨架与关键帧形态
GSAP Skeleton
技能文档给出的标准骨架:
const root = document.querySelector("[data-composition-id]"); const compositionId = root.dataset.compositionId; const tl = gsap.timeline({ paused: true }); tl.addLabel("state-a", 0); tl.to(".subject", { keyframes: [ { x: 0, opacity: 1, duration: 0.2 }, { x: 120, opacity: 1, duration: 0.4, ease: "power2.out" }, { x: 100, opacity: 1, duration: 0.2, ease: "power2.inOut" }, ], ease: "none", }); window.__timelines = window.__timelines || {}; window.__timelines[compositionId] = tl;要点:
- 用标签(label)表达语义状态;
- 用位置参数(position parameter)代替链式 delay;
- 对后续会再次触碰同一属性的
from()/fromTo()tween,使用immediateRender: false。
配套的 references/keyframe-patterns.md 给出了四种运行时骨架:GSAP timeline、CSS@keyframes(含animation-iteration-count: 1)、Anime.jscreateTimeline({ autoplay: false })+__hfAnime.push,以及 Three/WebGL 的"代理对象"模式——用 GSAP 驱动{ progress: 0 }状态对象,在onUpdate中由state.progress推导相机/物体/材质值并调用renderer.render,从而让 WebGL 场景也获得 seek-safe 的确定性时间。
关键帧形态(Keyframe Forms)
- 数组关键帧(Array keyframes):姿态阶梯,每一步带独立 duration/ease;
- 百分比关键帧(Percentage keyframes):单个 tween 内的精确时序;
- 属性数组(Property arrays):紧凑的多停靠点变化;
- 父级
ease: "none":当每个停靠点自带缓动时; easeEach:当每个片段共享相同手感时。
不要照抄示例中的数值距离或时序,应从实际组合的几何与时长推导。例如,一个主体在两个盒子之间移动,优先用一条连续变换 tween 或 FLIP;只有当观众应当感受到明显节拍(每一段都改变速度、可能读出顿挫)时,才把x/y/scale拆成多个带缓动的关键帧。
五、通道选择:可见通道 vs 布局/生命周期通道
优先使用合成器/视觉通道
x/y/z、xPercent/yPercent、scale、rotationX/Y/Z、skew、transformOrigin、svgOrigin、opacity、autoAlpha、clip-path、遮罩、CSS 变量、SVG 路径/虚线值、相机变换、shader uniforms。
避免布局/生命周期通道
top/left/right/bottom、width/height、margin/padding、display、visibility、延迟创建 DOM、用辅助叠加层做主体运动。
可见性切换的正确姿势
- 在已注册的 seekable GSAP timeline 上使用
autoAlpha,或在明确边界处用零时长tl.set(); - 只作用于非剪辑元素或剪辑内部的包装层,永远不要作用于
.clip本身; - 永远不要对原始
visibility做时长 tween,永远不要 tweendisplay。
机制选择表
选择能证明诉求的最小机制:
| 需求 | 机制 |
|---|---|
| 同一主体改变盒子或层级 | 共享元素 / FLIP |
| 主体沿可见路线行进 | 路径旅行(path travel) |
| 笔画生长或描边 | stroke draw |
| 形状变成另一形状 | 形状插值 |
| 揭示边界可见 | clip、mask 或 shader uniform |
| 多项按顺序移动 | stagger / 索引延迟 |
| 文本本身移动 | 行/词/字符/带(band)细分 |
| 表面弯曲、拉伸或裁剪 | 父子反向变换 |
| UI 具有状态 | 显式状态机 |
| 场景具有深度 | DOM 3D、Three.js 或 WebGL 相机/物体关键帧 |
机制可以组合,但每一项都必须澄清创意——装饰不是证明。该表的完整版(含每种机制要关键帧化的通道、运行时与验证方式)见 references/keyframe-patterns.md。
六、时序原则(Timing)
- 只有当预期能澄清因果或方向时才用预备动作(anticipation);
- 加速从静止离开(acceleration leaves rest);
- 峰值证明(peak proof)必须让机制无可置疑地呈现;
- 跟随动作(follow-through)强化能量与方向;
- 只有当主体应当有弹性或触感时才用过冲(overshoot);
- 恒定速度的路径旅行通常需要
ease: "none"; - 离散 UI 状态通常需要锐利的 ease-out;
- 重复元素需要有序偏移,而不是相同时序;
- 最终锁定(final lockup)需要比过渡姿态更长的保持;
- 平滑意味着同一主体上的连续速度;
- 不要重叠写同一 transform 属性的 tween,除非重叠是有意且经过验证的;
- 避免在同一主视觉面缩放/移动时同时做大范围
clip-path/遮罩动画;主移动稳定后再用嵌套揭示。
七、文本、SVG、3D 与 Canvas/WebGL
文本
保留行盒(line boxes)、字距、可读性与最终适配。若文本内部移动,移动的是字形或遮罩带,而不是文本周围的装饰。对可读帧拍照验证。
SVG
- 笔画生长优先
DrawSVGPlugin,其次是stroke-dasharray/stroke-dashoffset; - 形状插值优先
MorphSVGPlugin;必要时把基本图形转换为路径,并将复杂轮廓拆分为更简单的部分。
3D
仅缩放是假深度。应使用:稳定父级上的 perspective、transform-style: preserve-3d、z 向旅行、旋转、相机/世界运动、遮挡(occlusion)与交叉时的层序。用一两个能暴露深度关系的诊断角度验证;如果带角度的证明没有显示深度交叉,就改进 z/相机/遮挡。
Canvas / WebGL
通过确定性状态关键帧化:相机位置、相机目标、物体变换、材质透明度、shader uniforms 与后处理强度。时间从 HyperFrames 时间驱动(参考前述{ progress }代理对象模式)。使用--ghost验证——因为标记盒(marker boxes)看不到 canvas 内部的运动。
八、CLI 像素级验证(CLI Proof)
技能文档给出的完整诊断命令集:
npx hyperframes lint npx hyperframes check npx hyperframes keyframes . npx hyperframes keyframes . --json npx hyperframes keyframes . --runtime all npx hyperframes keyframes . --selector "<selector>" --shot "<file>" --samples <n> npx hyperframes keyframes . --selector "<selector>" --shot "<file>" --layout strip --from <t0> --to <t1> npx hyperframes keyframes . --shot "<file>" --ghost --angle <angle> npx hyperframes snapshot . --at <times>用法要点:
<selector>选择真实的动画主体;<times>选择首帧、证明姿态、最终减去保持(final-minus-hold)与精确最终帧;<angle>仅在必须证明深度时指定。
各工具证明什么
| 工具 | 证明 |
|---|---|
keyframes | 目标、显式停靠点、路径、描迹(trace)、父子组合运动、CSS 停靠点、Anime 注册 |
--shot | 鬼影(ghosts)、路线形状、时间间距、DOM 3D 投影、聚焦选择器证明 |
--layout strip | 原地运动、重叠、接触、细微缩放/透明度、文本波动 |
--ghost | canvas、WebGL、shader 运动、渲染后的 3D |
snapshot --at | 遮罩、文本可读性、完整状态、最终锁定、黑场/复位尾巴 |
如果选择器证明看起来不对:
- 重跑
--json; - 找到实际动画目标;
- 拍摄该目标;
- 快照完整帧;
- 信任画出的像素,而不是日志。
CLI 的源码实现依据
hyperframes keyframes命令定义于 packages/cli/src/commands/keyframes.ts,其能力远超表面输出:
- 支持的目标:项目目录(通过
resolveProject找到index.html,并沿[data-composition-src]遍历子组合)或单个.html文件; - 选项:
target、selector(只输出匹配该 CSS 选择器的关键帧)、runtime(gsap|css|anime|all,默认all)、json(面向 Agent 的机器可读输出)、shot(洋葱皮截图 PNG)、samples(等时采样数,默认 9)、layout(path默认,strip胶片条)、from/to(时间区间)、angle(front|iso|top|side|rear-iso预设或yaw,pitch度数)、fit、ghost; - tween 形状归一化:
surfaceTween将 GSAP 动画归一化为三种 shape——"keyframes"(显式停靠点)、"flat"(to/from合成 0%/100% 端点对)、"motionPath"(弧线路径);flatKeyframes以元素静止姿态为基线合成端点(opacity/scale 基值 1,位移/旋转基值 0),确保输出格式统一; - 多笔画描迹(trace):
groupTraces将同一元素上 ≥2 个真正发生位移的位置 tween 组合为有序描迹,用 0 时长set表示"笔离纸"跳跃;测试 packages/cli/src/commands/keyframes.test.ts 专门验证了"同一元素上两条位置笔画合成单条 trace"与"单笔画元素保持普通 per-tween 输出"; - 父子组合运动:
attachComposedAncestors会为每个 tween 标注其动画祖先元素(composed with),避免子元素自身 tween 隐藏父元素的轨迹;summarizeMotion用各属性 min..max 区间描述(而非端点),让闭环路径(如 8 字/轨道回到起点)也能暴露真实行程; - CSS/Anime 静态面:
surfaceCssKeyframes用平衡括号解析@keyframes块并回查animation/animation-name声明(含简写多名称);surfaceAnime检测__hfAnime注册状态、timeline/animation 数量、targets 与 durations;技能提示css/anime运行时输出是"静态创作面",seek 能力仍需 validate/render/snapshot 验证; - 洋葱皮守卫:
--shot需要项目目录(单个.html会报错),且当无静态可解析的动画元素且未开--ghost时会拒绝执行(onionShotGuardError)。
诊断结果阅读(Diagnostic Reading)
flat:无显式中间姿态;keyframes:存在显式停靠点;motionPath:存在路线;trace:多笔画绘制;composed with:子运动继承父运动。
鬼影间距均匀 = 匀速;鬼影聚集 = 慢入或安定;大间距 = 快速行程。辅助选择器拍摄不是证明;在损坏的完整帧上叠加洋葱皮也不是证明。
九、错误处理速查(Error Handling)
| 失败 | 修复 |
|---|---|
| endpoint-only | 增加中间姿态,保持峰值证明,重跑--shot |
| identity break | 保持一个元素存活,使用共享的源/目标盒子,移除替身交叉淡化 |
| fake 3D | 增加 z/相机行程、遮挡、带角度证明 |
| wrong final | 增加最终保持,快照 final-minus-hold 与精确最终帧 |
| unseekable runtime | 暂停 autoplay,注册实例,移除定时器,同步构建 |
| unreadable text | 保留行盒,减少位移量,增加最终保持,快照文本帧 |
十、完成标准(Done)
技能文档要求提交前完成以下闭环:
- 运行
hyperframes lint、hyperframes check、hyperframes keyframes、一次聚焦的--shot与快照; - 确认:首帧、证明姿态、final-minus-hold、精确最终帧;
- 确认运动为主体自身拥有(subject-owned motion),无调试叠加层。
结语
HyperFrames 的关键帧体系把"动效创作"重新定义为可验证的工程契约:编辑器边界上,剪辑时序归 core、视觉运动归 keyframes;运行时上,四种动画库共享同一套"同步构建 + 注册 + 禁随机/定时器"的 seek-safe 纪律;验证上,hyperframes keyframes把 GSAP/CSS/Anime 的关键帧、路径、描迹与洋葱皮截图全部摊开到人类与 Agent 面前。掌握本文的 pose ladder、通道选择、机制最小化与 CLI 证明流程,你就能在任意 HyperFrames 组合中稳定地产出"逐帧可验证"的运镜、转场与 3D 关键帧动画。
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考