首页
/ Hyperframes Embedded Captions 定制设计指南:Presets 覆盖、Canonical 克隆与 Typography 逐场景决策

Hyperframes Embedded Captions 定制设计指南:Presets 覆盖、Canonical 克隆与 Typography 逐场景决策

2026-09-09 18:13:36作者:傅爽业Veleda

本篇指南聚焦 hyperframes 仓库中 embedded-captions skill 的核心设计方法论:5 个预设样式(intro / phrase / emph / dream / crown)与 3 个模板(wall-embed / corner-column-crown / portrait-header)只是脚手架而非规则,真正高质量的嵌入字幕渲染几乎都来自对预设的覆盖(override)与对已验证渲染的克隆(clone)。读完本文,你将掌握「先定形状 → 判断能否克隆 → 否则从预设出发逐组覆盖」的三步工作流,理解 Cinematic 模式下哪些属性被锁定不可覆盖、哪些保留给 Agent 自由编排,并学会通过 custom_css、flex 累积排版、字号缩放表和渲染历史快照实现场景级定制。


定位:Presets 是脚手架,不是规则

embedded-captions 的 Cinematic 纯嵌入模式中,每条字幕都直接合成在人物背后(matte 遮挡),没有 rail 轨道承载正文。此时排版是否贴合场景,直接决定渲染成败。而 bespoke-vs-presets.md 给出的核心结论是:

  • 只依赖 presets → 渲染看起来千篇一律(generic);
  • 只复制既有渲染 → skill 无法适应新场景;
  • 正确的做法是三步决策:
    1. 先决定形状(template 选择、plane 位置、blend mode);
    2. 检查是否有足够接近的 canonical 示例 → 克隆并替换 words + timings;
    3. 否则从 presets 出发 → 通过 custom_css 逐组覆盖。

原因很直接:typography 是逐场景(per-scene)的决策,不是通用规则。最好的出片几乎都是针对特定群体覆盖了预设的结果。


Canonical 示例渲染:验证过的设计资产

两个经过验证的完整渲染 HTML 存放在 skills/embedded-captions/references/example-renders/

文件 场景 它为什么有效
memory-wall.html 内省独白、右侧泡沫吸音墙、中调 右对齐级联,逐组定制尺寸(cap-1 78 italic / cap-2 66 italic + 右侧悬挂缩进 / cap-3 72 正体 / cap-4 90 大写)。对偏暗泡沫墙面使用 mix-blend-mode: screen
champion.html 播客访谈、杂乱书架背景、1920×1080 左上列 + 舞台中央 crown。调校后的预设类尺寸(cap-intro 52 / cap-phrase 60 / cap-emph 70 / cap-crown 140)。screen 混合让书架透出文字

当新场景与其中之一高度相似(相近构图、相近主体位置、相近背景类型)时:直接克隆 HTML,只替换 GROUPS 数组和单词时间戳。不要从预设重新推导设计——那会丢掉经过多轮迭代验证的特定选择。

两个示例的源码结构本身就是一份教材。以 memory-wall.htmlGROUPS 为例,每个组包含 id、逐词时间戳(words[].start/end)、组的 in/out 窗口和 tone

const GROUPS = [
  {
    id: "cg-0",
    words: [
      { text: "Some", start: 0.24, end: 0.44 },
      { text: "memories", start: 0.48, end: 0.82 },
      { text: "feel", start: 0.9, end: 1.14 },
      { text: "soft", start: 1.2, end: 1.64 },
    ],
    in: 0.2,
    out: 4.85,
    tone: "soft",
  },
  // ...cg-1 / cg-2 / cg-3
];

对应 HTML 中的字幕容器则形如 <div id="cg-0" class="cap cap-1">…</div>,每个词包裹在 <span class="w" data-i="N"> 中,供 GSAP 时间线逐词驱动(详见 memory-wall.html)。


何时 presets 是错的:四种典型越界场景

你会本能地写 "style": "emph",但场景真正需要的可能是下面四种情况之一。

场景一:「这条字幕位于第 N 个位置,值得专属处理」

memory-wall.html 使用 cap-1 / cap-2 / cap-3 / cap-4——按位置索引(position-indexed),而非按角色索引(role-indexed)。每一个都是针对叙事弧线上特定短语的定制设计:

  • cap-1(柔和开场,4 词):78px italic 600 —— 像耳语;
  • cap-2(梦幻修饰语,3 词):66px italic 500 + padding-right: 44px —— 悬挂缩进制造右侧参差、诗意般的边缘;
  • cap-3(转折,2 词):72px 正体 700 —— 句法枢纽,无斜体;
  • cap-4(高潮,4 词):90px uppercase 900 —— 三行右对齐级联。

phrase/emph/intro 无法表达「这条字幕带悬挂缩进」或「这条字幕是句法转折点」。当这一点重要时,发明自己的类名,并通过 plan.jsoncustom_css 注入:

{
  "template": "wall-embed",
  "custom_css": "
    .cap-1 { font-size: 78px; font-weight: 600; font-style: italic;
             letter-spacing: -0.01em; }
    .cap-2 { font-size: 66px; font-weight: 500; font-style: italic;
             padding-right: 44px; }
    .cap-3 { font-size: 72px; font-weight: 700; letter-spacing: -0.015em; }
    .cap-4 { font-size: 90px; font-weight: 900; letter-spacing: -0.03em;
             text-transform: uppercase; line-height: 1.0; }
  ",
  "groups": [
    { "id": "cg-0", "style": "1", "words": [...] },
    { "id": "cg-1", "style": "2", "words": [...] }
  ]
}

关键机制:"style": "1" 字段会变成元素上的 class="cap-1"——任意字符串都行,没有任何校验。这可以从编译器的源码直接印证:make-composition.cjsrenderCap() 读取 g.slot ?? g.style 并拼出 class="cap cap-${slot}";随后 buildPerGroupCss() 会把每组 css 写入 #${g.id} { ... } 规则。

场景二:「模板的混合模式不适合这个背景」→ 换模板,不要覆盖

Cinematic 模式不会覆盖颜色或混合模式。 模板的 mix-blend-mode + fill 是锁定的 DNA——make-composition.cjs 源码中明确注释:plan.cap_color / blend_mode / text_shadow / text_filter有意忽略。选择模板即承诺其外观;Agent 唯一可写的只有布局(planes/positions)和逐组排版。

因此,应该用字幕区域亮度去选择本就匹配的模板,而不是重着色:

区域亮度 适合什么 原因
< 60(暗 / 低调) cream + screen 模板(cinematic-creammemory-wallchampionportrait-header 浅色文字发光,拾取场景
60–180(中调) cream + screen 模板仍可读(边缘情况可经 Standard 加 scrim) 文字拾取纹理
> 180(明亮:窗户、浅色墙面) cream/screen Cinematic 模板一个都不行——会洗白 → 改用 Standard 模式(不透明 rail,按所选模板设置)

如果场景明亮、cream/screen 观感被洗白,正确的信号是切换到 Standard 模式(在 HTML 中设置不透明颜色),而不是把一个 Cinematic 模板重着色成它本不是的东西。

场景三:「悬挂缩进 / 外缩 / 字宽微调」

这些是按组(per-group)的辅助能力,偶尔需要。通过 custom_css 表达:

#cg-2 {
  padding-right: 44px;
} /* 右对齐:收缩右边缘,形成左侧外缩 */
#cg-2 {
  padding-left: 44px;
} /* 左对齐:右移起始位置 */
.cap-emph .w:first-child {
  font-size: 110%;
} /* 仅放大首词 */

#cg-N 选择器永远有效,因为 make-composition.cjsrenderCap() 为每个组都写出 <div id="cg-N" ...>

场景四:「字幕应该累积(flex 堆叠)而不是替换」

三个模板默认在其 plane 内对 .cap 使用 position: absolute——字幕堆在同一位置,只有激活的一条可见(单字幕替换)。这对 portrait-headercorner-column-crown 是正确的:每条字幕替换上一条。

memory-wall 使用 flex 列累积——字幕像诗一样堆积。模板默认不是这样,需要通过 custom_css 覆盖:

.wall-plane {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-end; /* 或 flex-start 用于左对齐 */
  text-align: right;
  gap: 14px;
}
.wall-plane .cap {
  position: static; /* 解除模板的 absolute */
  top: auto;
  right: auto;
  max-width: 100%;
}

配合错开的 in / out 时间:cap-0 在 t=0.2 淡入,cap-1 在 t=2.55(flex 顺序上位于 cap-0 下方),cap-2 在 t=4.90 进入(此时两者在 t=4.85 一起淡出)——这正是 memory-wall 诗歌分页的工作原理,实现在 memory-wall.htmlGROUPS 时间中。

场景五:「字号与场景不匹配」

模板预设尺寸是针对特定列宽 + 帧尺寸调校的。不要对抗它们——直接覆盖:

"custom_css": ".cap-intro { font-size: 52px; } .cap-phrase { font-size: 60px; }"

然后参考 typography-presets.md 中「字号随列宽缩放」一节,依据 plane 的实际尺寸决定目标值。


预设体系速览:五种样式与两种 tone

typography-presets.md 定义了与 cap-* CSS 类对应的五种命名样式,在 plan.json 中按行的语义角色为每个字幕组选择:

style CSS 何时使用
intro 66px italic 500 首行、填充语("You know…"、"So…")、沉思式开场。低视觉重量
phrase 78px upright 600 主要陈述从句。多数行的默认
emph 92px upright 800 情绪峰值或关键成就行("I've achieved incredible things")
dream 82px italic 700 向往 / "was dreaming of…" 风格行。斜体传达记忆/想象
crown 140px upright 900 uppercase 仅限高潮行。用于舞台中央 crown-plane。每个合成最多一条——理想情况下是最后一条字幕

每个组还有独立于样式的 tone 字段:soft(柔和淡入 + 8px 上移入场,power2.out 缓动,漂浮怀旧感,用于记忆、intro、dream)与 present(干脆的 6px 上移 + 1.04 缩放弹入,power3.out,transformOrigin 居中,果断在场感,用于 emph 和 crown)。

自动挑选启发式:1)含最高级词汇(incredible, best, only, never, always)或品牌/专有名词 → emph + present;2)以话语标记开头(you know, so, well, look)或很短(≤3 词)→ intro + soft;3)提及梦想、希望、记忆、过去时动词如 "was dreaming" → dream + soft;4)收束句且像标题/头条 → crown + present(每片仅一条);5)其余 → phrase +(跟随相邻组 tone,默认 soft)。

字号随列宽缩放.cap-* 默认值针对 ~560px 列(champion 原始构图)调校。plane 更宽时字体显得欠重:

Plane 宽度 intro phrase emph dream crown(居中全幅) crown(仅干净区)
460–580 px(紧凑) 66 78 92 82 140 n/a
600–760 px(中等) 78 108 128 100 220 118
780+ px(宽) 90 128 150 116 260 140

注意:crown 尺寸假设横屏 1920×1080;竖屏 1080×1920 时所有 crown 尺寸除以 1.5。「全幅 crown」指居中、宽度设计为帧宽 0.8+ 并横跨主体身体,仅当 layout-heuristics.md 的 Crown 放置条件通过时使用;「仅干净区 crown」放在一个干净区内、字号更小,是居中 crown 吃掉太多画面时的回退。另外,若 plane 的 rotateY 超过约 8°,有效可视宽度会收缩,字号需上调约 10% 补偿。

反模式清单:不要每片超过一个 crown(它是唯一的回报时刻);emph 不要超过约 30% 的组(处处强调等于没有强调);不要因为词短就为正文选 intro("I won" 两词应选 emphcrown);不要无理由地交替 soft/present——tone 应跟随故事弧线:soft 开场 → present 铺垫 → emph 峰值 →(可选 crown 高潮)。


Clone-and-tweak 工作流:跳过 plan.json 直接复制

当新视频与既有 canonical 示例明显相似时:

# 1. 搭建项目脚手架
hyperframes init <project> --non-interactive --video <video.mp4> --skill=embedded-captions

# 2. 抠像 + 转写
node scripts/matte.cjs <project>
node scripts/transcribe.cjs <project>

# 3. 复制 canonical HTML,而不是编写 plan.json
cp references/example-renders/memory-wall.html <project>/index.html

# 4. 用新转写稿的分组替换 GROUPS 数组(手工编辑 index.html)

# 5. 直接渲染(跳过了 make-composition.cjs,因为我们不用 plan.json)
bash scripts/render-and-composite.sh <project>

这条路径完全跳过基于预设的 plan.json。适合克隆:主体构图、镜头布局、背景类型与示例相似;只需替换文字和时间;示例的定制排版正是你想要的。不要克隆:主体位置差异显著(如居中 vs 偏侧)、场景亮度 / 混合模式需求不同、想实验新排版——这些情况应回到 plan.json + custom_css 迭代。

关于渲染脚本的细节,render-and-composite.sh 会根据项目内是否存在 index.html / plan.json / cinematic.json 自动决定编译器:无 index.html 时自动调用 make-composition.cjs(或 make-cinematic.cjs);当源文件比 index.html 新时自动重编译,避免渲染过期产物。


渲染历史快照:迭代可回退

render-and-composite.sh 会在每次渲染前把 index.html + plan.json 快照到 <project>/history/(带时间戳,见 render-and-composite.sh)。当用户说「上一个更好」时,与最新快照做 diff:

ls <project>/history/
diff <project>/history/index-20260422-203947.html <project>/index.html

这让你能恢复迭代中被改掉的某个设计,而无需重读 Agent 的对话记录。


附:从源码看「可写」与「锁定」的边界

结合 make-composition.cjs 可以精确界定 Cinematic 模式的职责边界:

  • Agent 可写plan.plane / plan.header / plan.crown(位置、尺寸、旋转角度,见 make-composition.cjsPLANE_* / CROWN_* 占位符替换)、plan.font_scale(全局字号缩放)、每组的 style/slot/css/scale/tone/hero
  • 编译器接管:画布时长默认跟随源视频时长而非最后一条字幕(源码中标注的 Bug-1 修复策略,make-composition.cjs)、合成背景、字体注入、以及 occlclusion/timing/overflow 等一系列渲染前 gate。

因此,本文讨论的「覆盖」永远发生在布局与逐组排版层面;颜色与混合模式层面请始终通过选择模板来解决。这就是 bespoke-vs-presets 方法论与源码实现完全吻合的地方:预设负责锁定视觉身份,而 Agent 的创造力集中在每个场景独有的形状、位置与字体叙事上。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
docsdocs
暂无描述
Markdown
899
5.83 K
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
860
1.35 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
925
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.84 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
533
601
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
395
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.04 K
525