欢迎光临
我们一直在努力

HyperFrames2026终极指南-第3章第1节-HTML组合系统-Composition详解你的第一个视频剧本

Composition 详解:你的第一个视频"剧本"

HyperFrames 2026 终极指南 · 第3章第1节

系列回顾:上一章我们把 HyperFrames 的整体架构扒了个底朝天,知道了从 HTML 到 MP4 的完整链路。从这章开始,我们正式进入实战——先搞定 HyperFrames 里最核心的概念:Composition。


一、Composition 到底是什么?

我打一个你可能秒懂的比方:Composition 就是你视频的"剧本"。

你拍电影得有剧本吧?剧本里写了这场戏几点开始、演多久、演员在哪、台词是什么。Composition 干的就是这个事——它用 HTML 的方式告诉 HyperFrames:这个视频有多长、分辨率多少、每一段内容什么时候出现、持续多久。

我第一次接触 Composition 的时候,觉得它跟 After Effects 里的"合成"概念很像。但仔细一想,区别很大:AE 的 Composition 是二进制格式,你没法用文本编辑器打开看;HyperFrames 的 Composition 就是一个普通的 HTML 文件,你甚至可以用 Git 做版本管理。

Composition 的本质就是一个 HTML 文件,通过特定的 data-* 属性来描述视频的结构和时间线。


二、data-* 属性完整语义详解

HyperFrames 用一组 data-* 属性来标记 HTML 元素在视频中的角色。这些属性就是"剧本"里的标记符号。我按重要程度给你排个序:

2.1 data-composition-id —— 视频的"身份证号"

<div data-composition-id="my-awesome-video">
<!– 整个视频的内容都在这里 –>
</div>

作用:标记这个元素是一个 Composition 的根容器。一个 HTML 文件可以有多个 Composition,靠这个 ID 来区分。

规则:

  • 必须是唯一标识符,同一个文件内不能重复
  • 建议使用 kebab-case 命名(my-video),不要用驼峰或中文
  • 渲染时通过 CLI 指定要渲染哪个 composition

# 渲染指定的 composition
npx hyperframes render ./my-video –composition my-awesome-video

# 如果只有一个 composition,可以省略 –composition 参数
npx hyperframes render ./my-video

踩坑经历:我曾经在一个文件里放了两个 composition,ID 写成了驼峰命名 myVideo,结果 CLI 一直找不到。后来才发现 HyperFrames 内部做 ID 匹配时是严格区分大小写的,而且建议用 kebab-case。这个坑你别踩。

2.2 data-start —— “这段戏什么时候开场”

<div class="clip" data-start="3">
<h1>这段内容从第3秒开始</h1>
</div>

作用:定义这个 clip 在视频时间线上的起始位置,单位是秒。

规则:

  • 值必须 >= 0
  • 可以是小数,比如 data-start="1.5" 表示从第 1.5 秒开始
  • 必须加 class="clip",否则 data-start 不会被识别(这个我后面 Clip 与 Track 那节详细讲)

时间坐标系:HyperFrames 的时间坐标系很简单——从 0 开始,向右递增,单位是秒。

时间轴: 0s 3s 6s 9s
|———|———|———|
├─ 背景 ──────────────────────┤
├── Clip A ──┤
├── Clip B ──┤

2.3 data-duration —— “这段戏演多久”

<div class="clip" data-start="3" data-duration="5">
<h1>从第3秒开始,持续5秒</h1>
</div>

作用:定义 clip 的持续时间,单位也是秒。

规则:

  • 值必须 > 0
  • data-start + data-duration 不能超过 composition 的总时长
  • 如果超出,linter 会报错

一个容易犯的错误:很多人以为 data-duration 是"结束时间"。不是的!它是"持续时长"。如果你的 clip 从第 3 秒开始,要到第 8 秒结束,那 data-duration 应该写 5(8 – 3 = 5),不是 8。

2.4 data-track-index —— “这段戏在哪个舞台”

<div class="clip" data-start="0" data-duration="10" data-track-index="0">
<div class="background">背景层</div>
</div>

<div class="clip" data-start="2" data-duration="6" data-track-index="1">
<div class="subtitle">字幕层</div>
</div>

作用:定义 clip 所在的轨道编号。轨道从 0 开始,数字越大越在上面(类似 Photoshop 的图层)。

规则:

  • 必须是整数,从 0 开始
  • 同一轨道内的 clip 不能有时间重叠(同一时间只能显示一个)
  • 不同轨道的 clip 可以同时显示(叠加效果)
  • 如果不指定 data-track-index,默认为 0

这个概念太重要了,我单独用一整节来讲。现在你只要知道:轨道就是视频的"层",用来管理多个内容块的叠加和切换。

2.5 data-composition-src —— “引用外部剧本”

<!– 主文件 main.html –>
<div data-composition-id="full-video" data-duration="30">
<!– 引用另一个 composition 文件 –>
<div data-composition-src="./intro.html"
data-start="0"
data-duration="5">

</div>

<div data-composition-src="./main-content.html"
data-start="5"
data-duration="20">

</div>

<div data-composition-src="./outro.html"
data-start="25"
data-duration="5">

</div>
</div>

作用:引用外部的 composition 文件,实现模块化管理。类似于编程里的 import。

规则:

  • 路径相对于当前文件
  • 被引用的文件本身也必须是合法的 composition
  • 引用时可以覆盖被引用 composition 的部分属性

什么时候用? 当你的视频很长、结构复杂时,把所有内容塞在一个 HTML 文件里会很痛苦。用 data-composition-src 可以把视频拆成多个模块:

project/
├── main.html # 主编排文件
├── scenes/
│ ├── intro.html # 片头
│ ├── chapter1.html # 第一章
│ ├── chapter2.html # 第二章
│ └── outro.html # 片尾
├── assets/
│ ├── style.css
│ └── animations.js
└── meta.json # 配置文件


三、一个完整的最小可运行 Composition 文件

光说属性太抽象了,我直接给你一个完整能跑的例子,逐行给你讲:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>我的第一个 Composition</title>
<style>
/* ① 根容器尺寸 = 视频分辨率 */
[data-composition-id] {
width: 1920px;
height: 1080px;
overflow: hidden;
background: #0a0a0a;
font-family: 'PingFang SC', sans-serif;
}

/* ② clip 默认隐藏,由 HyperFrames 控制显隐 */
.clip {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}

/* ③ 各 clip 的样式 */
.clip-title {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

.clip-title h1 {
color: white;
font-size: 80px;
font-weight: 700;
text-align: center;
}

.clip-content {
background: #1a1a2e;
color: #eee;
font-size: 40px;
padding: 60px;
}

.clip-end {
background: #16213e;
color: #e94560;
font-size: 60px;
font-weight: bold;
}
</style>
</head>
<body>
<!– ④ Composition 根容器 –>
<div data-composition-id="hello-world"
data-duration="12">

<!– ⑤ Clip 1:标题卡,0-4秒 –>
<div class="clip clip-title"
data-start="0"
data-duration="4"
data-track-index="0">

<h1>Hello<br>HyperFrames</h1>
</div>

<!– ⑥ Clip 2:内容展示,4-9秒 –>
<div class="clip clip-content"
data-start="4"
data-duration="5"
data-track-index="0">

<p>用 HTML 写视频,就是这么简单。</p>
<p>你写的每一行 CSS,都会变成视频画面。</p>
</div>

<!– ⑦ Clip 3:结束卡,9-12秒 –>
<div class="clip clip-end"
data-start="9"
data-duration="3"
data-track-index="0">

<p>Thanks for Watching!</p>
</div>
</div>
</body>
</html>

逐行解析:

行代码说明
[data-composition-id] { width: 1920px; height: 1080px; } 根容器尺寸决定了输出视频的分辨率。1920×1080 就是 1080p
.clip { position: absolute; } 所有 clip 用绝对定位,这样它们才能叠加在同一位置
.clip-title { … } 每个 clip 的视觉样式,跟写普通网页一模一样
data-composition-id="hello-world" 标记这是 composition 根容器,ID 是 “hello-world”
data-duration="12" 视频总时长 12 秒
data-start="0" data-duration="4" 第一个 clip 从 0 秒开始,持续 4 秒
data-start="4" data-duration="5" 第二个 clip 从 4 秒开始,持续 5 秒
data-start="9" data-duration="3" 第三个 clip 从 9 秒开始,持续 3 秒

注意看时间线:

0s 4s 9s 12s
|───────────|───────────|──────────|
│ Clip 1 │ Clip 2 │ Clip 3 │
│ (标题卡) │ (内容) │ (结束卡) │
│ track 0 │ track 0 │ track 0 │

三个 clip 都在 track 0 上,首尾相接,无缝衔接。这就是最简单的"场景切换"。

把这段代码保存为 hello-world.html,然后跑:

npx hyperframes render ./hello-world.html –output hello.mp4

你就能得到一个 12 秒的 1080p 视频。


四、meta.json 配置详解

除了 HTML 里的 data-* 属性,HyperFrames 还支持一个 meta.json 配置文件来定义 composition 的全局参数。

{
"compositions": [
{
"id": "hello-world",
"width": 1920,
"height": 1080,
"fps": 30,
"duration": 12,
"background": "#0a0a0a",
"assets": {
"css": ["./assets/style.css"],
"js": ["./assets/animations.js"]
}
}
]
}

4.1 各字段说明

字段类型必填说明
id string Composition ID,对应 HTML 里的 data-composition-id
width number 视频宽度(像素)
height number 视频高度(像素)
fps number 帧率,默认 30
duration number 总时长(秒)
background string 背景色,CSS 颜色值
assets.css string[] 额外引入的 CSS 文件
assets.js string[] 额外引入的 JS 文件

4.2 HTML 属性 vs meta.json,到底用哪个?

这是个很多人问我的问题。我的建议是:

场景推荐方式
简单的单文件视频 直接用 HTML 的 data-* 属性
多文件组合的复杂项目 用 meta.json 统一管理
需要动态参数(分辨率、帧率) 用 meta.json,方便脚本修改
团队协作、CI/CD 用 meta.json,配置和代码分离

实际上两者可以混用。meta.json 里的配置会作为默认值,HTML 里的 data-* 属性可以覆盖它。优先级是:HTML data- > meta.json > 默认值*。


五、视频分辨率、帧率、时长的配置方式

这三个参数是视频最基础的规格,HyperFrames 提供了多种配置方式:

5.1 分辨率

<!– 方式1:CSS 直接设置(推荐) –>
<style>
[data-composition-id] {
width: 1920px;
height: 1080px;
}
</style>

<!– 方式2:meta.json –>
<!– { "width": 1920, "height": 1080 } –>

<!– 方式3:CLI 参数覆盖 –>
<!– npx hyperframes render ./video –width 1280 –height 720 –>

常用分辨率速查表:

名称宽×高适用场景
4K 3840×2160 高端展示、大屏播放
1080p 1920×1080 标准高清,最常用
720p 1280×720 网络传输、快速预览
竖屏 1080×1920 1080×1920 抖音/快手/Reels
正方形 1080×1080 社交媒体方形视频
4:3 1440×1080 复古风格

5.2 帧率

<!– 方式1:meta.json(推荐) –>
<!– { "fps": 60 } –>

<!– 方式2:CLI 参数 –>
<!– npx hyperframes render ./video –fps 60 –>

帧率选择指南:

FPS效果适用场景
24 电影感 电影风格视频
30 流畅 网络视频、教程(默认值)
60 丝滑 动画展示、游戏录屏
12 定格动画感 特殊艺术风格

5.3 时长

<!– 方式1:HTML data-duration(最直观) –>
<div data-composition-id="my-video" data-duration="30">

<!– 方式2:meta.json –>
<!– { "duration": 30 } –>

时长计算小技巧:视频的总时长应该等于最后一个 clip 的 data-start + data-duration。如果你设置了 data-duration="30" 但最后一个 clip 在第 25 秒就结束了,那后面 5 秒就是黑屏(或者背景色)。


六、Composition 的结构层次

用一张图来展示 Composition 内部的层次关系:

#mermaid-svg-x4pYzKF5cwtra0uh{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-x4pYzKF5cwtra0uh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-x4pYzKF5cwtra0uh .error-icon{fill:#552222;}#mermaid-svg-x4pYzKF5cwtra0uh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-x4pYzKF5cwtra0uh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-x4pYzKF5cwtra0uh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-x4pYzKF5cwtra0uh .marker.cross{stroke:#333333;}#mermaid-svg-x4pYzKF5cwtra0uh svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-x4pYzKF5cwtra0uh p{margin:0;}#mermaid-svg-x4pYzKF5cwtra0uh .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-x4pYzKF5cwtra0uh .cluster-label text{fill:#333;}#mermaid-svg-x4pYzKF5cwtra0uh .cluster-label span{color:#333;}#mermaid-svg-x4pYzKF5cwtra0uh .cluster-label span p{background-color:transparent;}#mermaid-svg-x4pYzKF5cwtra0uh .label text,#mermaid-svg-x4pYzKF5cwtra0uh span{fill:#333;color:#333;}#mermaid-svg-x4pYzKF5cwtra0uh .node rect,#mermaid-svg-x4pYzKF5cwtra0uh .node circle,#mermaid-svg-x4pYzKF5cwtra0uh .node ellipse,#mermaid-svg-x4pYzKF5cwtra0uh .node polygon,#mermaid-svg-x4pYzKF5cwtra0uh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-x4pYzKF5cwtra0uh .rough-node .label text,#mermaid-svg-x4pYzKF5cwtra0uh .node .label text,#mermaid-svg-x4pYzKF5cwtra0uh .image-shape .label,#mermaid-svg-x4pYzKF5cwtra0uh .icon-shape .label{text-anchor:middle;}#mermaid-svg-x4pYzKF5cwtra0uh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-x4pYzKF5cwtra0uh .rough-node .label,#mermaid-svg-x4pYzKF5cwtra0uh .node .label,#mermaid-svg-x4pYzKF5cwtra0uh .image-shape .label,#mermaid-svg-x4pYzKF5cwtra0uh .icon-shape .label{text-align:center;}#mermaid-svg-x4pYzKF5cwtra0uh .node.clickable{cursor:pointer;}#mermaid-svg-x4pYzKF5cwtra0uh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-x4pYzKF5cwtra0uh .arrowheadPath{fill:#333333;}#mermaid-svg-x4pYzKF5cwtra0uh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-x4pYzKF5cwtra0uh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-x4pYzKF5cwtra0uh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x4pYzKF5cwtra0uh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-x4pYzKF5cwtra0uh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x4pYzKF5cwtra0uh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-x4pYzKF5cwtra0uh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-x4pYzKF5cwtra0uh .cluster text{fill:#333;}#mermaid-svg-x4pYzKF5cwtra0uh .cluster span{color:#333;}#mermaid-svg-x4pYzKF5cwtra0uh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-x4pYzKF5cwtra0uh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-x4pYzKF5cwtra0uh rect.text{fill:none;stroke-width:0;}#mermaid-svg-x4pYzKF5cwtra0uh .icon-shape,#mermaid-svg-x4pYzKF5cwtra0uh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-x4pYzKF5cwtra0uh .icon-shape p,#mermaid-svg-x4pYzKF5cwtra0uh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-x4pYzKF5cwtra0uh .icon-shape .label rect,#mermaid-svg-x4pYzKF5cwtra0uh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-x4pYzKF5cwtra0uh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-x4pYzKF5cwtra0uh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-x4pYzKF5cwtra0uh :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

Composition 根容器data-composition-iddata-duration

Track 0 (背景轨道)data-track-index=0

Track 1 (内容轨道)data-track-index=1

Track 2 (特效轨道)data-track-index=2

Clip Adata-start=0data-duration=10背景视频/图片

Clip Bdata-start=10data-duration=10切换场景

Clip Cdata-start=2data-duration=6字幕/标题

Clip Ddata-start=12data-duration=5说明文字

Clip Edata-start=0data-duration=3转场动画

Clip Fdata-start=10data-duration=2转场动画

层次关系解读:

  • 最顶层是 Composition 根容器,定义视频的全局属性(ID、时长、分辨率)
  • 中间层是 Track(轨道),通过 data-track-index 区分
  • 最底层是 Clip(片段),每个 clip 有自己独立的时间(data-start、data-duration)和内容
  • 渲染时,HyperFrames 会从左到右(track 0 → track N)逐层渲染,后渲染的层会覆盖先渲染的层。这就像 Photoshop 的图层——你在最上面的图层画的东西,会遮住下面图层的內容。


    七、多 Composition 管理

    一个项目里经常有多个 composition。比如你要做一系列产品介绍视频,每个产品的模板一样但内容不同:

    <!– templates.html –>

    <!– 模板 A:15秒版本 –>
    <div data-composition-id="product-intro-15s" data-duration="15">
    <div class="clip" data-start="0" data-duration="5">
    <h1>产品名</h1>
    </div>
    <div class="clip" data-start="5" data-duration="7">
    <p>产品特点介绍</p>
    </div>
    <div class="clip" data-start="12" data-duration="3">
    <p>立即购买</p>
    </div>
    </div>

    <!– 模板 B:30秒版本 –>
    <div data-composition-id="product-intro-30s" data-duration="30">
    <div class="clip" data-start="0" data-duration="5">
    <h1>产品名</h1>
    </div>
    <div class="clip" data-start="5" data-duration="15">
    <p>详细功能演示</p>
    </div>
    <div class="clip" data-start="20" data-duration="7">
    <p>用户评价</p>
    </div>
    <div class="clip" data-start="27" data-duration="3">
    <p>立即购买</p>
    </div>
    </div>

    # 渲染 15 秒版本
    npx hyperframes render ./templates.html –composition product-intro-15s

    # 渲染 30 秒版本
    npx hyperframes render ./templates.html –composition product-intro-30s

    # 批量渲染所有 composition
    npx hyperframes render ./templates.html –all


    八、Composition 的嵌套与引用

    前面提到了 data-composition-src,这里给一个更实际的例子:

    <!– main.html – 年度总结视频 –>
    <div data-composition-id="annual-review-2025" data-duration="180">

    <!– 片头:0-10秒 –>
    <div data-composition-src="./scenes/opening.html"
    data-start="0" data-duration="10"
    data-track-index="0">

    </div>

    <!– Q1 回顾:10-50秒 –>
    <div data-composition-src="./scenes/q1.html"
    data-start="10" data-duration="40"
    data-track-index="0">

    </div>

    <!– Q2 回顾:50-90秒 –>
    <div data-composition-src="./scenes/q2.html"
    data-start="50" data-duration="40"
    data-track-index="0">

    </div>

    <!– Q3 回顾:90-130秒 –>
    <div data-composition-src="./scenes/q3.html"
    data-start="90" data-duration="40"
    data-track-index="0">

    </div>

    <!– Q4 回顾:130-170秒 –>
    <div data-composition-src="./scenes/q4.html"
    data-start="130" data-duration="40"
    data-track-index="0">

    </div>

    <!– 片尾:170-180秒 –>
    <div data-composition-src="./scenes/ending.html"
    data-start="170" data-duration="10"
    data-track-index="0">

    </div>
    </div>

    这样做的好处:

    • 模块化:每个季度是独立文件,各团队可以并行制作
    • 可复用:opening 和 ending 模板可以复用到其他视频
    • 易维护:改一个季度不影响其他季度
    • 渲染快:可以只渲染修改过的部分

    九、常见错误排查

    我整理了一份 Composition 新手最常犯的错误清单:

    错误现象原因解决
    忘记 class="clip" clip 不显示 HyperFrames 只识别带 clip class 的元素 加上 class="clip"
    data-start 写成结束时间 clip 出现时间不对 data-start 是开始时间,不是结束时间 改为 开始时间 = 结束时间 – 持续时长
    根容器没设尺寸 渲染出来黑屏 没有告诉 HyperFrames 视频分辨率 在 CSS 里设置 width 和 height
    clip 时间超出总时长 linter 报错 start + duration > composition duration 调整 clip 时间或增加总时长
    同轨道 clip 时间重叠 渲染异常 同一 track 的 clip 不能重叠 调整时间或分到不同 track
    data-composition-id 重复 只渲染第一个 ID 必须唯一 改不同的 ID

    小结

    今天我们把 Composition 这个核心概念彻底搞明白了。总结一下关键知识点:

  • Composition = 视频的剧本,本质是一个带 data-* 属性的 HTML 文件
  • 5 个核心属性:data-composition-id(身份)、data-start(开始时间)、data-duration(持续时长)、data-track-index(轨道)、data-composition-src(外部引用)
  • 分辨率、帧率、时长可以通过 HTML 属性、meta.json 或 CLI 参数配置,优先级依次递减
  • 多 composition 可以放在同一个文件里,也可以用 data-composition-src 拆分到不同文件
  • Composition 搞明白了,你就掌握了 HyperFrames 的"语言"。后面不管是做简单的文字动画还是复杂的多轨道视频,都是在写 Composition。


    下节预告

    这节我们讲了 Composition 的整体结构和属性语义,但有一个关键概念只是提了一下没展开——Clip 与 Track。下一节我们就深入这个话题:为什么每个定时元素都需要 class="clip"?多轨道到底怎么管理?我会用一个 3 轨道视频的完整示例,把时间线管理这件事讲透。


    如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连!本系列持续更新中,关注不迷路~

    赞(0)
    未经允许不得转载:171主机测评 » HyperFrames2026终极指南-第3章第1节-HTML组合系统-Composition详解你的第一个视频剧本
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址