核心概念
帧适配器
将你自己的动画运行时引入 Hyperframes。
帧适配器(Frame Adapter)模式是 Hyperframes 支持多种动画运行时的方式。每个适配器需要回答的核心问题是:
在第 N 帧时,屏幕应该是什么样子?
如果一个运行时能回答这个问题,它就可以接入 Hyperframes。
工作原理
宿主应用(引擎或生产器)通过按严格顺序调用适配器方法来驱动渲染。适配器从不控制自己的时钟——它只响应定位命令。
sequenceDiagram
participant Host as 宿主(引擎)
participant Adapter as 帧适配器
participant Chrome as Chrome / 浏览器
Host->>Adapter: init(context)
Adapter-->>Host: 就绪
Host->>Adapter: getDurationFrames()
Adapter-->>Host: 300 帧
loop 遍历每一帧 0..300
Host->>Host: 归一化帧(clamp、floor)
Host->>Adapter: seekFrame(frame)
Adapter->>Chrome: 更新 DOM / canvas 状态
Adapter-->>Host: 完成
Host->>Chrome: 捕获像素缓冲区
end
Host->>Adapter: destroy()
Adapter-->>Host: 清理完成
适配器 API(v0)
ype FrameAdapterContext = {
compositionId: string;
fps: number;
width: number;
height: number;
rootElement?: HTMLElement;
};
ype FrameAdapter = {
id: string;
init?: (ctx: FrameAdapterContext) => Promise<void> | void;
getDurationFrames: () => number;
seekFrame: (frame: number) => Promise<void> | void;
destroy?: () => Promise<void> | void;
};
必须满足的语义
getDurationFrames()必须返回一个 >= 0 的有限整数seekFrame(frame)必须支持任意顺序的定位(向前、向后、随机)seekFrame(frame)对于相同的输入帧必须是幂等的seekFrame(frame)必须将内部时间限制在适配器的范围内- 适配器应该是暂停/定位驱动的,而非时钟驱动的
宿主编排
宿主在调用适配器之前会对帧进行归一化:
normalizedFrame = clamp(Math.floor(frame), 0, durationFrames);
典型的渲染循环:
await adapter.init?.({ compositionId, fps, width, height, rootElement });
const durationFrames = adapter.getDurationFrames();
for (let frame = 0; frame <= durationFrames; frame += 1) {
await adapter.seekFrame(frame);
// 捕获该帧的像素缓冲区
}
await adapter.destroy?.();
确定性契约
以下规则对任何适配器来说都是不可协商的。它们是 Hyperframes 确定性渲染保证的基础。
- 规范时钟:
t = frame / fps - 无挂钟依赖(
Date.now、依赖漂移的逻辑) - 无未设种子的随机性
- 无渲染时网络请求
- 固定输出参数(
fps、width、height) - 仅有限时长
- 在定位前进行确定性帧量化
支持的运行时
官方运行时适配器:
| 运行时 | 定位方法 | Skill |
|---|---|---|
| GSAP | timeline.totalTime(timeSeconds) 或 timeline.seek(timeSeconds) | /gsap |
| Anime.js | instance.seek(timeMs),适用于注册在 window.__hfAnime 上的动画 | /animejs |
| CSS keyframes | 浏览器 Animation.currentTime,带暂停的负延迟回退 | /css-animations |
| Lottie / dotLottie | goToAndStop(timeMs, false)、原始帧设置器或播放器定位 API | /lottie |
| Three.js / WebGL | hf-seek 事件加上 window.__hfThreeTime 用于确定性场景渲染 | /three |
| Web Animations API | document.getAnimations() 和 animation.currentTime | /waapi |
欢迎社区贡献适配器——如果它能按帧定位,它就属于 Hyperframes。
一致性测试
每个适配器应通过以下最低测试:
- 可重复性 -- 对同一帧定位两次,获得相同的输出
- 随机定位 -- 定位顺序
[90, 10, 50, 10]产生确定性结果 - 边界值 -- 负数和溢出帧值不会导致崩溃
- 持续时间 -- 返回的持续时间是有限整数
- 清理 --
destroy后没有泄漏的定时器/监听器
下一步
- 确定性渲染 了解适配器必须遵守的确定性保证
- GSAP 动画 查看官方 GSAP 适配器的实际运作
- @hyperframes/engine 在渲染期间驱动适配器的捕获引擎
- 参与贡献 构建并贡献你自己的适配器