HyperFrames 动画避坑清单:6 条让渲染不出错的运动规则
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
HyperFrames是一个「写 HTML、渲染视频」(Write HTML. Render video.)的开源框架:你给它一份带时间属性的 HTML,它就能确定性地逐帧渲染成 MP4。但新手最常栽的坑恰恰出在动画上——预览里看着正常,一渲染就错位、卡死、元素消失。这份避坑清单把 6 条真正决定「渲染对不对」的运动规则一次讲清,帮你少走弯路。
💡一句话原理:HyperFrames 不「播放」视频,而是一次只问要某一帧。第 90 帧长什么样,只取决于数字 90。所以任何依赖「真实时钟 / 随机 / 播放顺序」的写法,都会让渲染结果对不上预览。原理详见 docs/concepts/determinism.mdx。
规则一:每个要出场的元素,必须带class="clip"和时间属性
🚨 坑:某个标题 / 图片在预览里正常,渲染后却从头到尾一直可见(永远挂着),或者干脆不出现。
✅ 规则:会定时出场的元素,要同时满足两件事——
- 加
class="clip"(让元素拥有满画布盒子,并被运行时正确控制显隐); - 写清
data-start(何时进入)、data-duration(占多长)。data-track-index只是 Studio 里的泳道,可省略。
<section id="headline" class="clip">const timeline = gsap.timeline({ paused: true }); window.__timelines = window.__timelines || {}; window.__timelines["intro"] = timeline; // 必须匹配 />「Animation is static」这一类问题,根因几乎都是时间线没暂停、或没按正确的 ID 注册。规则与最小契约见 docs/guides/gsap-animation.mdx 与 docs/guides/troubleshooting.mdx。
规则三:只动 transform / opacity,别直接改 width、height、top、left
🚨 坑:视频画面冻结、外框却在动;或元素抖、布局抽搐,预览和渲染对不上。
✅ 规则:位移、缩放、旋转一律用transform(x/y/scale/rotation)和opacity表达。不要对width / height / top / left反复做补间——这些是「布局属性」,触发重排、性能差且难以 seek。要移动 / 缩放<video>时,包一层 wrapper,动画加在 wrapper 上,而不是视频本身。
动画技能合约里明确写着:animates transforms and paint-only properties — width/height/top/left tweens are forbidden。完整约束见 skills/hyperframes-animation/rules-index.md。
规则四:动画必须「可复现」——用显式状态,禁止 Math.random / Date.now
🚨 坑:同一份工程每次渲染都不一样,预览正常但冷启动渲染乱飞;或想加「手作感 / 抖动」却把确定性彻底破坏。
✅ 规则:
- 无墙钟:不写
Date.now()、requestAnimationFrame、系统定时器; - 无未播种的随机:
Math.random()让每帧都不同;要伪随机请用固定种子的 PRNG(如 mulberry32); - 优先
fromTo():显式写清起点和终点,向后 / 随机 seek 都稳; - 输出尺寸 / 时长锁死:
fps、width、height在第 0 帧前就定好,组合要有确定的结束点。
这是整份清单里最核心的一条——确定性是「同一输入永远同一输出」的基石,自动流水线、CI、AI 剪辑都建立在它之上。完整规则与「手作感仍要可复现」的做法见 docs/concepts/determinism.mdx 与 docs/prompting/motion.mdx。
规则五:隐藏元素要显式写出「可见的终点状态」(冷启动 seek 陷阱)
🚨 坑:预览里元素正常浮现,可渲染后它一直是隐形的——哪怕你明明写了入场动画。
✅ 规则:冷启动的渲染 worker 会直接 seek 到某一帧,恢复的是你「写死的隐藏状态」,而不是预览里刚见过的那一瞬。所以:
- 用
gsap.fromTo()揭示元素时,终点变量里要带上opacity: 1(或autoAlpha: 1),不能只写from; - 初始隐藏状态要放在时间线之外(用裸
gsap.set()或直接写在 CSS/HTML 里),别指望时间线第 0 位的一条零时长set; - 若元素要在前几帧「缺席」,用
to()+keyframes,或一个零时长的set()卡点。
![]()
例如「航线沿行进方向自己画出来」这类效果,若只给起点不给可见终点,冷渲染下就只会是一条静止、未绘出的线。描边绘制的安全写法见 skills/hyperframes-animation/rules/svg-path-draw.md。
规则六:每个场景加「入场动画」,场景之间加「转场」
🚨 坑:元素突然「啪」地冒出来、场景之间生硬跳切——成片一看就「廉价」,观众会本能地觉得哪里不对。
✅ 规则(这是默认就应遵守的最佳实践,有特殊理由可覆盖):
- 给每个场景加入场动画:没动效的出现,在视频里看起来就是坏的;
- 场景之间加转场:组合视频里的跳切,几乎总不是有意的。
弹跳式入场是经典、稳妥的一招(scale: 0 → 1+back.out过冲,fromTo保证 t=0 也正确):
timeline.fromTo("#title", { opacity: 0, y: 32 }, { opacity: 1, y: 0, duration: 0.6, ease: "power3.out" }, 0);
入场 / 转场的取舍与「避免幻灯片感」的方法见 docs/prompting/motion.mdx;完整规则与反模式对照见 docs/prompting/rules-and-anti-patterns.mdx。可复用的入场配方如 skills/hyperframes-animation/rules/spring-pop-entrance.md。
🧭 出问题时,按这个顺序自查
症状 先查哪条规则 定位工具 元素一直可见 / 不出现 规则一 npx hyperframes lint动画完全不动 规则二 确认 ID 与paused注册 画面冻结、布局抖 规则三 改成 transform/opacity 每次渲染都不一样 规则四 去随机 / 墙钟,改fromTo 渲染里元素隐形 规则五 补可见终点状态 生硬跳切、显廉价 规则六 加入场 + 转场
环境 / 浏览器 / FFmpeg 层的问题,先跑npx hyperframes doctor;需要逐位一致(哈希比对、证明静帧、两次渲染 diff)时用 Docker 固定环境渲染:npx hyperframes render --docker。更多细节见 docs/guides/troubleshooting.mdx 与 docs/concepts/determinism.mdx。
🎯一句话收尾:HyperFrames 的每一帧都是「按序号精确 seek」出来的,所以你的动画只要做到状态显式、可复现、只动 transform,预览是什么样,渲染出来就一定是什么样。把这 6 条刻进肌肉记忆,基本就能告别「预览好好的,渲染翻车」。
更多可复用原子配方(SVG 描边、弹跳入场、深度相机、粒子爆发等)都放在 skills/hyperframes-animation/;底层解析与逐帧渲染实现在 packages/core 与 packages/producer。
【免费下载链接】hyperframesWrite HTML. Render video. Built for agents.
项目地址: https://gitcode.com/GitHub_Trending/hy/hyperframes
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考