合成
合成(Composition)是定义视频时间线的 HTML 文档。每个片段——视频、图片、音频——都存在于一个合成之中。
结构
每个合成都需要一个带有 data-composition-id 的根元素:
<div id="root" data-composition-id="root"
data-start="0" data-width="1920" data-height="1080">
<!-- 元素放在这里 -->
</div>
index.html 文件是顶层合成。它可以在内部包含嵌套合成。任何合成都可以被导入到另一个合成中——没有特殊的"根"类型。
片段类型
片段(Clip)是时间线上任意一个离散的块,用带有数据属性的 HTML 元素表示:
<video>-- 视频片段、B-roll、A-roll<img>-- 静态图片、叠加层<audio>-- 音乐、音效<div data-composition-id="...">-- 嵌套合成(动画、分组序列)
每种片段类型的完整属性列表请参阅 HTML Schema Reference。
嵌套合成
你可以通过两种方式将一个合成嵌入另一个合成:从外部文件加载或在内联定义。外部文件是可复用合成的推荐方式。
外部文件
使用 data-composition-src 引用另一个 HTML 文件。框架会自动获取该文件、提取 <template> 内容、挂载它、执行脚本并注册时间线。
<div
id="el-5"
data-composition-id="intro-anim"
data-composition-src="compositions/intro-anim.html"
data-start="0"
data-track-index="3"
></div>
每个外部合成文件用 <template> 标签包裹其内容:
<template id="intro-anim-template">
<div data-composition-id="intro-anim" data-width="1920" data-height="1080">
<div class="title">Welcome!</div>
<style>
[data-composition-id="intro-anim"] .title {
font-size: 72px; color: white; text-align: center;
}
</style>
<script>
const tl = gsap.timeline({ paused: true });
l.from(".title", { opacity: 0, y: -50, duration: 1 });
window.__timelines["intro-anim"] = tl;
</script>
</div>
</template>
内联
直接在父合成内部定义嵌套合成。对于不需要复用的一次性合成,这种方式更简单。
<div id="root" data-composition-id="root"
data-start="0" data-width="1920" data-height="1080">
<!-- 内联嵌套合成 -->
<div id="el-5" data-composition-id="intro-anim"
data-start="0" data-track-index="3"
data-width="1920" data-height="1080">
<div class="title">Welcome!</div>
</div>
<script>
// 内联合成的时间线
const introTl = gsap.timeline({ paused: true });
introTl.from(".title", { opacity: 0, y: -50, duration: 1 });
window.__timelines["intro-anim"] = introTl;
</script>
</div>
内联合成不使用 <template> 标签或 data-composition-src。
项目结构
project/ index.html compositions/ intro-anim.html caption-overlay.html outro-title.html assets/ video.mp4 music.mp3 logo.png
两个层次:原生元素和脚本
每个合成都有两个层次:
- HTML -- 原生片段(
video、img、audio、嵌套合成)。声明式结构:播放什么、何时播放、在哪条轨道上。由数据属性控制。 - Script -- 特效、过渡、动态 DOM、Canvas、SVG——通过 GSAP 实现创意动画。脚本不会控制媒体播放或片段的显示/隐藏。
⚠️ Warning
切勿使用脚本来播放/暂停/寻找媒体元素,或根据时间控制片段的显示/隐藏。框架会自动根据数据属性处理这些操作。重复这些行为的脚本会与框架产生冲突。示例请参阅常见错误。
变量
HyperFrames 不会自动将 data-var-* 属性绑定到合成的 DOM 或 CSS 中。
支持的模式是:
- 在子合成的
<html>根元素上使用data-composition-variables声明变量(id + type + default)。 - 在每个合成宿主元素上使用
data-variable-values传递逐实例的值。 - 在合成内部使用
window.__hyperframes.getVariables()读取解析后的值。运行时会按实例将宿主的data-variable-values覆盖在声明的默认值之上,因此相同的源文件可以使用不同的值嵌入多次。
<div
data-composition-id="card-pro"
data-composition-src="compositions/card.html"
data-start="0"
data-track-index="1"
data-variable-values='{"title":"Pro","color":"#ff4d4f"}'
></div>
<div
data-composition-id="card-enterprise"
data-composition-src="compositions/card.html"
data-start="card-pro"
data-track-index="1"
data-variable-values='{"title":"Enterprise","color":"#22c55e"}'
></div>
<html data-composition-variables='[
{"id":"title","type":"string","label":"Title","default":"Fallback"},
{"id":"color","type":"color","label":"Color","default":"#111827"}
]'>
<body>
<div data-composition-id="card" data-width="1920" data-height="1080">
<h1 class="title"></h1>
<style>
[data-composition-id="card"] {
--card-color: #111827;
}
[data-composition-id="card"] .title {
color: var(--card-color);
}
</style>
<script>
// 在子合成脚本中,getVariables() 返回逐实例的值:
// 声明的默认值 < 宿主 data-variable-values 覆盖值。
const { title, color } = __hyperframes.getVariables();
const root = document.querySelector('[data-composition-id="card"]');
root.querySelector(".title").textContent = title;
root.style.setProperty("--card-color", color);
</script>
</div>
</body>
</html>
如果你正在基于 @hyperframes/core 构建工具链,同一个 data-composition-variables 数组可以通过 extractCompositionMetadata() 读取,用于 Studio 编辑界面和分析流程。
列出合成
使用 CLI 查看项目中的所有合成:
npx hyperframes compositions
下一步
- 数据属性 时间、媒体和合成属性的完整参考
- GSAP 动画 使用 GSAP 时间线为合成添加动画
- 示例 从常见视频模式的内置示例开始
- HTML Schema 参考 创作合成的完整 schema