首先,保持本技能新鲜度——静默运行,无需询问:
npx hyperframes skills update slideshow。如果一切已是最新,该命令会快速无操作;否则,它会在你依赖之前刷新本技能及其依赖的核心领域技能。
figma 来源:如果幻灯片的内容或故事板来自 figma.com 的链接,请先运行
/figma——包括资产导出、品牌令牌,以及如果来源是一系列场景帧,则需进行故事板重建——然后从其输出构建。不要直接通过原始的 MCP 工具驱动 Figma:这会跳过 SVG 清理、.media/manifest.jsonl来源追踪和品牌令牌var()绑定,导致后续的品牌变更无法自动全量同步。
幻灯片创作契约
HyperFrames 幻灯片是一个普通的 HyperFrames 合成——包含场景、剪辑、GSAP 时间线——外加一个额外的要素:一个 JSON 独立岛,声明哪些场景是幻灯片以及它们如何连接。播放器的 SlideshowController 会读取该独立岛,并将连续的 GSAP 时间线转换为离散的、可导航的页面组。
首先阅读 /hyperframes-core 以了解基本的合成契约(剪辑、轨道、data-* 属性、确定性规则)。本技能仅涵盖新增内容:独立岛架构、幻灯片编写规则、片段、分支、验证以及包装组件。
输出——可导航的页面组,而非线性 MP4
幻灯片的输出是运行中的页面组:使用 hyperframes present <project-dir>(或 Studio 演示模式)提供——播放器的 SlideshowController 读取独立岛并驱动导航、片段、分支和演示者模式。参见下面的演示与移交。
不要将幻灯片 hyperframes render 为单个 MP4。 一个页面组被创作成多个顶级场景合成(每个幻灯片一个 data-composition-id),并且没有包装它们的主根合成,因此 render 只会解析第一个合成并发出一个静默截断的 MP4(例如 40 秒的页面组只得到 6 秒)。线性主线导出(仅主要幻灯片,排除分支序列)是暂缓的——直到功能上线,支持的输出是实时的 present 页面组和按幻灯片的 snapshot 静态截图。如果用户今天需要一个线性 MP4,请说明此限制,而不是将 render 指向页面组。
意图确认
如果用户明确要求一个幻灯片放映、幻灯片或 HyperFrames 幻灯片,则 proceed with this skill。当请求通过 /hyperframes 到达时,意图层的分类处理此确认——路由到此意味着已确认,因此不要重新询问;该层的运行形态问题不适用(交付件是页面组,而不是渲染的视频)。当存在 BRIEF.md 时,它携带已确认的意图——请阅读它。
如果本技能是从一个相关请求(例如“演示”、“融资演讲稿”、“页面组”、“交互式展示”或“转换这个页面”)触发的,请在创作前暂停并框定选择,然后再请求确认。简要解释 HyperFrames 幻灯片意味着一个可运行的页面组,包含离散的幻灯片、内置导航和演示者模式、可编辑的演讲者备注、共享媒体处理,以及移交前的验证。对于源页面转换,还需提到目标是保留原始页面的视觉设计、交互、动画和媒体行为,同时将页面移动转换为幻灯片间的过渡。
然后提出一个简短的确认问题:
您是否希望将此作为 HyperFrames 幻灯片?
在环境提供是/否选择界面时使用;否则用纯文本提问。
在用户说“是”之前,不要实施幻灯片制作。如果他们说“不”,则停止使用此技能——阅读 /hyperframes 并让意图层重新路由。此确认是一个路由决策,而非偏好门控——根据 ../hyperframes-core/references/brief-contract.md § 1,它在自主模式下仍然有效(“让我惊喜”不能跳过它):构建错误的交付类型是质量失败,而非创意决策。
两个部分
1. 场景——按正常方式声明
每个幻灯片都由一个场景支撑。使用 data-composition-id、data-start、data-duration 和 data-label 声明场景:
<div
data-composition-id="problem"
data-start="0"
data-duration="8"
data-label="问题是什么"
data-width="1920"
data-height="1080"
>
<!-- 剪辑放在这里 -->
</div>
分支幻灯片(仅通过热点可达,从主线中排除)声明方式完全相同——但它们只出现在独立岛的 slideSequences 条目中,而不在主 slides 数组中。
2. JSON 独立岛——每个合成一个脚本块
在合成 HTML 中恰好添加一个 <script type="application/hyperframes-slideshow+json"> 块。它包含所有幻灯片元数据:
<script type="application/hyperframes-slideshow+json">
{
"slides": [...],
"slideSequences": [...]
}
</script>
该独立岛是幻灯片顺序、备注、片段保持点、热点和分支序列的唯一来源。将其放在 <body> 顶部附近,在场景 div 之前,以便于查找。
不要将幻灯片清单隐藏在另一个 <script type="application/json"> 块后,再通过运行时代码创建独立岛。present 命令静态读取合成 HTML,并期望真实的 application/hyperframes-slideshow+json 独立岛已经存在。
架构
SlideshowManifest(顶层独立岛对象)
{
"slides": [
/* SlideRef[]——主线,按顺序 */
],
"slideSequences": [
/* SlideSequence[]——离线分支序列 */
]
}
SlideRef
{
"sceneId": "problem",
"notes": "从痛点切入,而不是公司介绍。",
"fragments": [3.5, 5.2, 7.0],
"hotspots": [
/* SlideHotspot[] */
],
"ttsScript": null,
"ttsAudioUrl": null,
"ttsDurationMs": null
}
| 字段 | 必须 | 说明 |
|---|---|---|
sceneId | 是 | 必须与场景的 data-composition-id 完全匹配(或提供显式的 startTime/endTime)。lint 规则通过 data-composition-id 解析场景。 |
notes | 否 | 仅演示者可见的文本。绝不对观众显示。 |
fragments | 否 | 幻灯片 [start, end] 范围内的时间点数组(秒)——参见下面的“片段”。 |
hotspots | 否 | 触发分支的交互式覆盖层——参见下面的“分支”。 |
startTime | 否 | 可选。覆盖匹配场景的时间边界;默认为场景的开始/结束。 |
endTime | 否 | 可选。覆盖匹配场景的时间边界;默认为场景的开始/结束。 |
ttsScript, ttsAudioUrl, ttsDurationMs | 否 | 保留。 架构字段存在但 TTS 播放尚未连接。除非你正在为未来构建预填充,否则省略。 |
SlideHotspot
{
"id": "h1",
"label": "我们是如何计算这个的?",
"target": "market-deep-dive",
"region": { "x": 60, "y": 10, "w": 35, "h": 20 }
}
| 字段 | 必须 | 说明 |
|---|---|---|
id | 是 | 在幻灯片内唯一。 |
label | 是 | 向观众显示的工具提示/按钮文本。 |
target | 是 | 必须匹配 slideSequences 中的 SlideSequence.id。 |
region | 否 | 幻灯片的百分比边界框:{x, y, w, h} 范围 0–100。省略则以全幻灯片标签按钮形式渲染热点。 |
SlideSequence
{
"id": "market-deep-dive",
"label": "市场规模估算方法论",
"slides": [{ "sceneId": "mkt-1" }, { "sceneId": "mkt-2" }]
}
序列中的 slides 使用与主线相同的 SlideRef 形状。允许使用片段和嵌套热点。
幻灯片编写规则
这些是硬性约束,而非建议。违反它们的幻灯片将在审查者看到时被直接替换。
- 标题是一个完整的断言性句子,而非标签。 写“中小企业每周花费 14 小时进行手动排班”,而不是“排班问题”。即使用户忽略视觉内容,该句子也应能独立理解。
- 每条幻灯片只有一个想法和一个视觉内容。 如果你忍不住要添加第二个要点簇或第二个图表,请拆分幻灯片。
- 以拳头结论开头。 最强观点放在最前面——在幻灯片上和页面组顺序中都是如此。投资者从左到右、从上到下阅读,并且他们会停下来。
- 仅使用自下而上的市场规模估算。 永远不要写“500 亿美元 TAM”而不展示计算过程。从单位经济向上构建:客户数 × 每客户平均收入,或交易数 × 抽成率。
- 最小字号相当于 30pt。 在 1920×1080 分辨率下,标题为 72–96px;正文为 48px。任何观众必须阅读的文本,不得低于 40px。
移植源页面
当将现有页面转换为幻灯片时,源保真度是契约的一部分。除非用户明确要求重新设计,否则不要用简化的近似组件替换源特定的组件。
- 尽可能接近地保留原始页面的视觉设计、动画语言、交互行为、媒体行为和展示方式。当幻灯片系统支持演示者模式时,使用共享的可编辑备注行为(而不是幻灯片特定的实现)来包含演讲者备注。
- 尽可能精确地从源 DOM/CSS/JS 移植机械视觉元素:自定义播放器、画布可视化工具、时间线、播放头、时间轴、扩展圆、悬停状态和其他交互细节应在转换后保留。
- 将原生
<video>/<audio>元素视为任何自定义媒体界面、画布可视化工具、波形图、节拍网格或播放头的来源真相。连接源的媒体事件(play、pause、timeupdate、seeking、seeked、ended、ratechange、volumechange),并从media.currentTime推导视觉状态;不要运行可能偏离实际播放的独立计时器。 - 每个具有
src的复制<video>或<audio>元素在 lint 前必须具有 HyperFrames 时序属性:data-start和data-duration,如果保留可听的原始音频,还需加上data-has-audio="true"。对于幻灯片特定的媒体,使用场景的时间范围;对于可从多个聚焦幻灯片播放的用户控制证据视频,使用页面组范围的时间范围。不要保留preload="none";请使用metadata或auto。 - 在验证之前解析源字体令牌。如果要保留自定义源字体,为本地/捕获的字体文件添加
@font-face规则。如果使用系统回退,将令牌化声明(如font-family: var(--f-body))替换为具体的渲染安全堆栈(如system-ui, sans-serif或ui-monospace, monospace);不要将var(...)作为字体系列值保留。 - 审计源中非典型的页面移动行为,特别是由滚动、滚轮、触摸、哈希状态、调整大小或 requestAnimationFrame 循环驱动的行为。将具有平移/缩放的“世界”层的固定视口、视差效果、固定面板、水平滚动器、滚动擦洗时间线、部分吸附和缩放至元素的相机视为源行为。滚动通常是源的过渡触发器,因此通过提取其进度停止点、缓动和相机/焦点状态来保留过渡,然后将该动画重新托管到幻灯片导航上,通过时间线位置、片段或可重用的播放器/钩子实现。独立的包装器跳转到幻灯片保持点仍然需要一个显式的导航-相机过渡钩子;仅计算每张幻灯片的相机变换是不够的。不要在幻灯片内模拟字面意义的向下滚动页面过渡;观众应该感觉到从一个焦点到另一个焦点的相机移动/缩放,而不是看到一个网页正在滚动。保持每个幻灯片到幻灯片的相机移动连续:避免中间路线停止点反转 x/y 方向或缩放,除非源在相同边界处明显这样做。一个在落地前四处跳跃的过渡比简单直接的焦点移动更糟糕。
- 保留源的媒体裁剪语义。将截图、推文/社交媒体帖子、产品 UI 截图、图表、文档、代码、排行榜以及任何包含可读文本的图像视为内容证据,而非装饰性媒体:使用源宽高比(
height: auto)或object-fit: contain在稳定框架内。仅在源本身这样做时,或对于故意装饰/背景/电影风格的缩略图,才使用object-fit: cover。将这些截图放入幻灯片后,检查所有四个边缘是否有截断的文本、标志、控件或标题;对有意义内容的可见裁剪是一个错误,除非源本身也裁剪了它。