插件安装: 在执行安装或更新命令之前,如果此技能位于 HyperFrames 插件内部,请遵循 插件执行规则。独立安装则保留下方的更新说明。
HyperFrames 核心
Agent 常见陷阱(先读):
- 使用 flex/
inset居中,而不是在节点上使用 CSStransform: translate(-50%,-50%)然后使用 GSAPx/y。Lint 规则:gsap_css_transform_conflict。请使用fromTo或xPercent/yPercent。 - 不要添加场景退出的
tl.set(..., {visibility:"hidden"})。运行时已经隐藏了定时剪辑。在内部节点(或.clip上的opacity)上使用不透明度淡入淡出就足够了。字幕硬消失是另一条规则。 window.__timelines["id"]必须与根元素的data-composition-id匹配。- 在
render之后,阅读摘要的第二行:beginframevsscreenshot、GPU 模式、阶段时长。screenshot+ Linux 上的software gpu是慢路径。
HyperFrames 从 HTML 渲染视频。合成是一个 HTML 文件,其 DOM 使用 data-* 属性声明时间,其动画运行时是可查找的,并且其媒体播放由框架拥有。
此技能是技术协议——如何构建一个 HyperFrames 项目。以下内容是构建指南;按主题的详细信息位于 references/(索引如下),按需阅读。流程文档(简报、故事板、审核、制作、分发、帧处理工作器)位于 /hyperframes → references/。其他关注点位于同级领域技能中——hyperframes-animation、hyperframes-creative、media-use、hyperframes-cli、hyperframes-registry。/hyperframes 中的能力映射说明了每个技能覆盖的内容。
参考
| 文件 | 阅读目的 |
|---|---|
references/minimal-composition.md | 从最小的可渲染合成骨架开始 |
references/composition-patterns.md | 选择整体式与模块化;构建模块化 index.html;选择子合成原型 |
references/data-attributes.md | 查阅任何 data-*(根 / 剪辑 / 子合成宿主 / 旧别名);使用 class="clip" |
references/tracks-and-clips.md | 了解 data-track-index 的作用(和不作用)、z-index、相对于另一个剪辑的时间定位;使用 npx hyperframes timeline 列出每个轨道和剪辑 |
references/creator-editing-recipes.md | 复制真实的剪切/修剪/重新排序/重新计时/冻结/相机/遮罩/交叉淡入淡出/音频编辑配方及其限制 |
references/sub-compositions.md | 连接子合成(宿主属性、<template>、实例变量)并在其内部进行动画 |
references/variables-and-media.md | 声明变量;放置 <video>/<audio>,设置音量,修剪 |
references/determinism-rules.md | 构建可查找的时间线;确定性禁令;布局/文本适配 |
references/full-screen-motion.md | 使用共享背景创作全帧运动 |
references/tailwind.md | 在 Tailwind v4 项目中工作(init --tailwind;运行时合约与 Studio 的 v3 不同) |
有关动画运行时细节(GSAP API、Lottie、Three.js 等),请转到 hyperframes-animation → adapters/<runtime>.md。
构建合成
两种根形式(不可互换)
- 独立式(顶层
index.html):根<div data-composition-id="…">直接位于<body>中,没有<template>包装器。包装独立根会隐藏所有内容,并且lint会拒绝它(standalone_composition_wrapped_in_template,错误)。 - 子合成(通过
data-composition-src加载):将根包装在<template>中。这是推荐的编写形式:加载器也接受纯完整文档并回退到其<body>,但模板化形式是示例和工具假设的形式。
⚠ 传输规则:对于模板化子合成,组装器会丢弃文件自身的
<head><style>/<script>(packages/core/src/compiler/compositionAssembly.ts,hasTemplate门),因此请将<style>/<script>放在模板内部。<link>在两种情况下都会被提升。 ⚠ 宿主 ID 约定:给宿主槽、内部模板和window.__timelines["<id>"]键使用相同的 ID。支持不同的本地 ID(组装器回退到文件中的第一个根),但不匹配是静默的,因此除非有理由不这样做,否则请使它们匹配。
文件形状、宿主连接和渲染前检查清单 → references/sub-compositions.md。
根必须有尺寸(静默布局错误)
独立根使用 width/height: 100%。画布大小是 data-width/data-height。运行时将这些像素标记到合成根上。不要硬编码 1920px/1080px 到 #root。骨架 → references/minimal-composition.md。
一个暂停的时间线
每个合成注册恰好一个 gsap.timeline({ paused: true }) 到 window.__timelines["<id>"](键 = 根 data-composition-id)。在异步回调(document.fonts.ready)内部构建它是支持的;重要的是仅在构建完成后注册。渲染长度是根的 data-duration,而不是时间线的长度:超出根时长的部分会被截断,提前结束则保持其最后一帧。省略根 data-duration 则将推断长度(时间线、媒体窗口或适配器)。您不需要 window.__timelines = window.__timelines || {}:运行时在您的内联脚本运行之前创建注册表,并且 lint 不再要求它。不要手动将子时间线嵌套到宿主中;运行时自动嵌套已注册的子时间线。完整合约(包括非 GSAP 运行时)→ references/determinism-rules.md + hyperframes-animation/adapters/。
首次 lint 陷阱(保证首次构建失败)
lint 确实会捕获的规则,但仅在事后。第一次就写对:
- 永远不要将 CSS 初始
transform与相同属性上的 GSAP 补间配对——CSS 值和补间的起点会发生冲突,lint会以gsap_css_transform_conflict拒绝它。使用gsap.fromTo(el, { x: -40 }, { x: 0 })在补间内部设置初始状态,而不是使用 CSStransform: translateX(-40px)。 - 永远不要在
<video>/<audio>上放置crossorigin。lint无条件拒绝它,错误为media_crossorigin_breaks_preview(错误),包括用于画布/WebGL/WebAudio 回读的情况。没有抑制方法。 - 永远不要给带有
data-start的<video>一个也携带data-start的祖先。lint以video_nested_in_timed_element(错误)拒绝它。要么给包装器计时,要么给视频计时,而不是两者都计时。 - 每个
<audio>都需要一个id。lint以media_missing_id拒绝它,并且没有id的<audio>永远不会被混合器拾取,因此渲染将是静音的。 - 永远不要用
autoAlpha或visibility补间.clip——lint以gsap_animates_clip_element拒绝它。请改为动画其子元素。 - 命名 CSS
font-family需要一个文件内的@font-face指向提供的本地文件,否则lint会触发font_family_without_font_face。 - 子合成
#root使用width/height: 100%(或inset: 0),而不是硬编码的1920px/1080px。画布大小是data-width/data-height。
lint 错误也会关闭布局和对比度审计:check 然后报告 0 sample(s) 和 0/0 text checks,这看起来像是一个干净的文件,但实际上什么也没运行。在信任这些数字之前,请清除所有 lint 错误。
不可协商的规则(自动化门控可能遗漏的静默错误)
在此列出;完整理由在链接的参考文档中。不要违反:
- 没有渲染时时钟 / 未播种的
Math.random/ 网络 / 输入状态;没有repeat: -1(使用有限计数)。→determinism-rules.md - 永远不要在
.clip元素上补间display、visibility或autoAlpha。框架拥有剪辑可见性,并且lint会拒绝它(gsap_animates_clip_element)。请改为动画其子元素。→determinism-rules.md - 正文中无
<br>;变换后的元素必须是块级且有尺寸;脉动的绝对定位装饰元素需要峰值间隙。→determinism-rules.md <video>/<audio>通过平面文档查询找到,因此框架可以在任何嵌套深度(包括在子合成<template>或包装器内部)定位和解码它们。一个硬限制:如果<video data-start>位于另一个也带有data-start的普通元素内部,lint会报错,并且失败是真实的(错误的源帧,然后剪辑在时间段中间消失),因此请将时间放在包装器或视频上,绝不能同时放在两者上。子合成宿主是例外的:子合成内部的媒体可以正确渲染。另一个注意事项是时间线,而不是放置:子合成时间线无法动画宿主根元素。→variables-and-media.md- 确保组装后页面中的每个
id都是唯一的(为子合成 ID 添加合成 ID 前缀,如#<id>-hero),以便您自己的#idCSS 和getElementById调用能够正确解析。帧注入不再依赖于此:编译器会在每个video[src]/audio[src]/img[src]上打上文档唯一的data-hf-render-id。使用<source>子元素而非src属性的媒体不会被打上标记,因此在这些情况下唯一 ID 仍然重要。→composition-patterns.md - 对于正常渲染,在合成根上使用全屏填充是可以的。它仅在分层合成路径(HDR 内容或使用着色器过渡的合成)上被丢弃,此时引擎强制每个合成根透明,以便底层可以显示出来。如果您的合成使用着色器过渡或 HDR 媒体,请将填充放在一个全出血的子元素上(
position:absolute; inset:0)。→composition-patterns.md
编辑现有合成
- 首先读取文件。保留无关的时间、轨道、ID、变量、媒体路径。
- 要了解项目时间线上有什么(轨道、剪辑、开始、结束、播放内容),请运行
npx hyperframes timeline [--json],而不是阅读index.html和每个子合成文件。 - 匹配现有的合成 ID 和时间线键。
- 添加剪辑:根据周围剪辑有意设置其
data-start/data-duration。data-track-index是 Studio 的显示通道,不是时间约束,因此它不需要是空闲的。 - 超出根
data-duration的剪辑会被截断:在同一编辑中将根data-duration扩展到剪辑结束位置(lint警告clip_ends_past_root_duration)。 - 任何合成元素上的
data-hidden会在预览和渲染中均将其隐藏,覆盖其时间窗口;它是非破坏性/可逆的,由 Studio 时间线的眼睛图标切换。 - 添加子合成:在连接宿主之前验证其内部的
data-composition-id。
验证
有关命令详情,请使用 hyperframes-cli。
-
npx hyperframes check通过(lint、运行时、布局、运动和对比度方面均无发现) - 带有子合成的项目:
npx hyperframes snapshot --at <midpoints>并目视检查每一帧 - 使用
npx hyperframes preview --background进行审查(用户可以在 Studio 的时间线中编辑任何内容,并且服务器在调用命令后继续运行) - 仅在用户批准后使用
npx hyperframes render