- 人工智能
- AI 技能/插件
- 提示工程
【免费下载链接】garden-skills
ConardLi's open-source Skills collection, featuring web design, knowledge retrieval, image generation, and more.
本文是 garden-skills 仓库中 web-video-presentation 技能(把文章/口播稿做成"伪装成视频"的 16:9 点击驱动网页演示)的单章开发权威指引。它以skills/web-video-presentation/references/CHAPTER-CRAFT.md为骨架,结合模板源码(skills/web-video-presentation/templates/src/)与主题 token 系统,讲透"每章至少 1~2 处视觉演示、逐步揭示、双源原则、反 AI 味、代码最小约束、narrations.ts 真相源、完工自检"这整套方法论。读完你将掌握写出一章"有视频感、可录屏、换主题不破"的章节的全部要领,以及落地时的代码级红线与可执行的自检流程。
一、定位校准:这是视频,不是 PPT
章节开发的出发点不是"做一页好看的幻灯片",而是做视频网页——讲者点击 + 口播 + 录屏发出去给观众看。CHAPTER-CRAFT.md给出了三条非常朴素的验收标准,判断每一步做对没有:
| 标准 | 具体要求 |
|---|---|
| 不像 PPT | 观众感觉是在看视频,不是在看翻页幻灯。页面中不得包含页眉页脚,突出主视觉元素 |
| 看起来舒服 | 配色、字体、节奏都让人放松。不得出现大量的纯文字、不得出现字体太小的文字 |
| 有视觉冲击 | 画面在演事情,不只是文字堆砌。不得一次性全部罗列所有元素,关键元素随进度逐步推进展现 |
这三条贯穿后续所有章节:视觉演示(第二条要求的落地手段)、逐步揭示(第三条的落地手段)、基本审美(第二条的落地手段)都是从它们推导出来的。值得注意,"不得包含页眉页脚"是硬约束,templates/src/styles/base.css里虽然提供了.masthead(杂志刊头)等辅助类,但那属于"框架已搭好、理解即可"的演示元素,章节自己的内容不要出现浏览器式页眉页脚。
二、底线:每章必须用 CSS / SVG / Canvas / JS 做视觉演示
这是全文最重要的一条底线:
每一章都至少要有 1~2 处"动起来的图 / 演示元素"。整章只有纯文字 = 验收不过 = 回去重做。
视频感最强的来源,是用户看见了被讲解的东西在屏幕上演给他看。CHAPTER-CRAFT.md列出的演示形式包括:
- 数字在递增 / 横条在生长 / 排名在交换
- 流程节点依次点亮 / 连线自绘
- 对比被一刀切开 / 聚光灯扫过 / 形状在变形
- 粒子聚拢成形 / 噪声背景流动 / 字符雨下落
- 模拟终端交互、模拟 AI 对话窗口、模拟文件目录树
"怎么组合发挥都行——但每章必须用,不允许整章纯文字。"
从模板源码可以印证这套要求的落地方式。脚手架自带的示例章节 Example.tsx 每个 step 都借助MaskReveal组件做遮罩式揭示:
if (step === 0) { return ( <div className="ex-scene scene-pad"> {/* ... */} <h1 className="ex-cover-h"> <MaskReveal show duration={900}> <span className="serif-cn">这是 </span> </MaskReveal> <MaskReveal show delay={300} duration={900}> <span className="serif-it ex-em">first step</span> </MaskReveal> <MaskReveal show delay={650} duration={900}> <span className="serif-cn">.</span> </MaskReveal> </h1> {/* ... */} </div> ); }注意delay参数的错峰使用——同一个 step 内部,文字逐段浮现而不是整体同时出现。这正是"画面在演事情"的最小实现:一次点击推进后,观众能眼睁睁看到内容以有节奏的方式登场。真正的内容驱动演示(数字递增、流程点亮、聚光灯扫过、字符雨)则要按本章主题从references/EXAMPLES/下的结构示意(hook / list-reveal / case-tech-review)里找灵感,但那不是抄袭模板——SKILL.md明确"先按内容自由设计,卡壳才翻"。
三、逐步揭示:整页内容由全局 step 驱动,一项 = 一个 step
整页内容由全局step计数器驱动——点击空白处或按 → 键推进一步。设计每一步时心里要默念:这一步演什么,下一步演什么。
最重要的那条规则:
当口播在说"第一是 X、第二是 Y、第三是 Z"这种清单 / 列表时,严禁一个 step 把 X / Y / Z 全部 stagger 上来。
正确做法是:
- 一项 = 一个 step;
- X 只在它自己的 step 里独自亮起;
- 讲到 Y 时,X 灰化保留作上下文 + Y 亮起;
- 讲到 Z 时,X / Y 都灰化 + Z 亮起。
判断标准:讲者会一个一个念出来吗?会 → 必须逐个揭示。
源码级印证:step 到底是怎么驱动的
全局 step 由 useStepper.ts 实现,章节组件本身只是step的纯函数——没有定时器、没有命令式状态。其核心机制包括:
- 每章 step 数由
narrations数组长度决定:useStepper通过chapters[chapter].narrations.length计算每章步数(见sanitize与next/prev实现),章节.tsx里if (step === N)出现的最大 N + 1 必须等于narrations.length。这也是 types.ts 中ChapterDef.narrations注释所强调的:"Length === total steps in this chapter." - 键盘全局监听:
ArrowRight/Space前进,ArrowLeft/Backspace后退,Home回到开头,End跳到末尾,数字键1~9直接跳章节(代码见useStepper.ts的onKey)。 - 游标防漂移:游标持久化在
localStorage(STORAGE_KEY = "presentation-cursor-v4"),每次读取都经sanitize重新 clamp 到当前章节列表范围内,避免章节增删后持久化游标落到不存在的 step 上。这正是 SKILL.md 中"大改后 bump STORAGE_KEY"的由来。
点击推进的边界:data-no-advance
Stage.tsx 的点击处理是:
onClick={(e) => { const t = e.target as HTMLElement; if (t.closest("button, a, input, [data-no-advance]")) return; onAdvance(); }}章节内的可交互元素(按钮 / 自定义控件)必须加data-no-advance,否则点它会连带着被舞台误推进 step。注意ProgressBar自己也带data-no-advance(见 ProgressBar.tsx),因为它是一个需要可点击的覆盖层控件。
四、内容取舍与双源原则:节奏跟口播稿,细节回原文章
视频是音 + 画:口播负责把信息线性讲清楚,画面负责把节拍重点放大、节奏感拉出来。
内容取舍:每个 step 屏幕上只挂这个节拍最值得放大的 1~3 个东西——一个 hero 标语 / 一个数字 / 一组对比 + 必要的视觉演示。不要试图把原文每个字都搬上去。"那是论文阅读,不是视频。"
双源原则(CHAPTER-CRAFT.md的明确要求):
- 节奏 / 顺序 / 节拍切分跟
script.md口播稿——关键顺序不能乱;- 画面细节 / 数据 / 引用 / 案例回
article.md原文章抽。
outline.md已经在每章首段抽了「信息池」做参考,但实现章节时也必须回去翻article.md本章对应段落——那里有比口播稿多得多的细节(具体数字、引用原话、案例维度、出处时间)。把这些挂到画面上,让画面信息密度 > 口播信息密度。
如果你只用了口播稿的内容做章节——屏幕等于把口播打字打了一遍——那就是 PPT,不是视频。
SKILL.md的 Phase 1 也印证了这一点:script.md(决定节拍)与article.md(画面信息源,不删)是两份并列的产出物,而outline.md只规划节奏与信息密度、不规划动画——动画由章节开发时按CHAPTER-CRAFT.md的法则即时设计,避免 chapter agent 退化成"翻译机"。
五、视频演示基本审美:字号、留白、配色、动画
视频观众离屏幕远、注意力浮动,所以:
- 字号要大:hero 文字至少 80px 起,远观也能看清;
- 留白要多:舞台四边都要让出大留白,画面不要塞满;
- 配色要舒服:颜色和字体家族必须用主题 token(保证换主题不破);字号 / 间距 / 时长这些章节按内容自由发挥;
- 动画要舒服 + 炫酷:出现得干净利落,停下来不抢戏;炫酷靠设计巧思(内容驱动的演示动画),不靠速度暴力或密集闪烁。
源码层面,字号与留白都有可参考的默认刻度。base.css 定义了完整的设计 token 字号阶梯(--t-display-1约 140~200px、--t-display-2约 80~128px、--t-h1约 56~88px、--t-h2约 40~60px、--t-body20px)和舞台留白默认值--stage-pad-x: 96px; --stage-pad-y: 80px;。章节点缀使用这些 token 即可轻松满足"hero 至少 80px、四周大留白"的要求——具体数值可以由章节自由覆写,但方向不能违背。
六、避免 AI 味:视觉指纹清单与 placeholder 原则
AI 生成的网页有几种共有的"视觉指纹",全部不要:
- 紫粉 / 蓝紫对角渐变背景
- 圆角卡片 + 彩色左边框装饰
- 渐变按钮 + 大圆角药丸
- emoji 当图标用
- 假数据 / 假 logo / 假"X 万用户"
- 整章 N 步用同一种入场动画(全场 fade / 全场 blur)
- 每步都挂 ken burns / 光晕呼吸 / 持续闪烁
- 每屏右下角都挂 mono 角标 / 序号
缺的东西承认缺——用 placeholder 占位卡(一张写着"image · 16:9 描述"的卡片,按真实比例留位)。不要用 emoji 凑、不要找无关图凑、不要编数字。没有就承认没有,比 fake 强一百倍。这同时对应完工自检里的硬条目:"缺的素材用 placeholder,不是 fake"以及"章节交付时主动告诉用户:本章还缺这些素材"。
这里可以观察到一个设计自洽:框架其实提供了mono 角标类(.corner-mark/.click-cue/.label-mono,见base.css),但CHAPTER-CRAFT.md明确禁止"每屏右下角都挂 mono 角标 / 序号"这种滥用——原生语是"每屏都挂"才是问题,克制使用仍是允许的。判断标准是"为内容服务",不是"为装饰服务"。
七、框架已搭好的部分:理解就好,不需重写
脚手架已经把视频的"骨架"全部搭好,章节开发只需理解、不可重写:
| 已搭好的机制 | 说明 |
|---|---|
| 16:9 固定舞台 | 内容设计在 1920×1080 上,外层 transform scale 缩到任何视口,外围 letterbox 留黑——没有响应式断点 |
| 舞台居中 + 大留白 | 上下左右四边都让出至少 80px 的安全区 |
| 隐形进度条 | 屏幕底部默认完全透明,鼠标悬到底部边缘才出现,支持点击跳转章节(录屏时摄像头看不到任何 chrome 控件) |
| 全局 step 驱动 | 点击舞台空白处 / 键盘 ←/→ 推进;章节是 step 的纯函数,没有定时器、没有命令式状态 |
源码印证:三层舞台结构
Stage.tsx 的注释解释了 3 层嵌套布局的设计意图:
.app-shell← 全视口,flex 居中;.stage-fitter← 尺寸为实际可见像素(1920 × scale×1080 × scale),让布局系统"诚实地"看到屏幕上到底是什么,从而在任何视口 / DPR 下都能稳稳居中;.stage-frame← 原始 1920×1080 盒子,从左上角按transform: scale(scale)缩放进 fitter。
缩放比例由 useStageScale.ts 计算:scale = min(可用宽 / 1920, 可用高 / 1080),其中可用宽高已为进度条等绝对定位 UI 预留marginX = 80/marginY = 100的呼吸空间——这正是"四边至少 80px 安全区"的源码出处。
舞台底色 / 圆角 / 阴影 / 装饰图案 / vignette 全部由主题的.stage-frame规则自动接管(见base.css的--surface-pattern、--surface-vignette等变量),章节什么都不用做。
隐形进度条
ProgressBar.tsx 固定在视口底部,pb-hover默认隐藏、悬停浮现;点击章节药丸可整章跳转,当前章节内的每个 step 都有独立 pip(.pb-pip),支持点击精确跳到任意一步。章节变更时当前章节自动scrollIntoView居中,保证悬停弹出的瞬间就能看到当前进度。录屏时由于默认透明,摄像头画面里看不到任何 chrome 控件。
八、代码层最小约束:token 铁律与工程红线
CHAPTER-CRAFT.md规定了一套"不能踩的红线,其它怎么写都行"的约束,分为三档。
必须用 token(换主题不破的底线)
颜色:--shell/--surface/--surface-2/--surface-3/--text/--text-2/--text-mute/--text-faint/--rule/--accent/--accent-soft/--accent-glow——禁硬编码 hex / rgb / 颜色名。
字体家族:--font-display-cn/--font-display-en/--font-body/--font-mono——禁硬编码字体名。
主题性格签名通过 primitive class 自动接入,不要在章节 CSS 里重定义它们:
| Primitive class | 主题决定什么 |
|---|---|
.hero-num | hero 数字风格(衬线 / 等宽 / 粗黑) |
.rule | 分割线(1px 实线 / 4px 实线 / 2px 虚线) |
.card | 卡片圆角 + 阴影性格 |
.stage-frame | 舞台底色 / 圆角 / 阴影 / 装饰图案 / vignette 全自动 |
源码里能看到这套"性格签名"的真实落点。以 chalk-garden/tokens.css 为例,主题通过--rule-w: 2px; --rule-style: dashed让全站分割线都变成"粉笔虚线",通过--hero-num-font / --hero-num-style / --hero-num-weight定义 hero 数字的手写风格,通过--surface-pattern(SVG 噪点)加胶片颗粒、--surface-vignette加暗角——章节代码只要用.hero-num、.rule这些类,就自动获得该主题的性格,换主题时无需改动任何章节代码。反之,若章节里硬编码了一个 hex 或字体名,换主题立刻破功。
可硬编码 / 可 token,按内容自由(解锁章节自由设计)
- 字号:想要 80px 就写 80px,想用
var(--t-h1)也行; - 间距 / padding / margin:按画面节奏写具体值;
- 动画时长 / 缓动 / keyframe:按动画意图写具体值(节奏气质参考
theme.json的mood——慢主题别写 200ms 的快动画); - 边框宽度 / 非性格圆角 / 字距:随手写;
- gap / grid 布局尺寸:按画面构图写。
base.css头部注释也明确了这条"所有权划分":主题拥有 COLOR / FONTS 与性格旋钮;章节强制消费颜色 + 字体 token 与四个 primitive class;其余一切(字号、间距、动效时长、缓动、边框宽度、通用圆角)章节自由书写,token 或硬编码均可。
其它工程红线
- 不用
setTimeout/setInterval驱动动画——用 CSS keyframes。这保证了章节是"step 的纯函数",也让 Auto 模式(见下节)的推进完全由音频驱动,不受 JS 定时器干扰。 - 章节内的可交互元素(按钮 / 自定义控件)加
data-no-advance,否则点了会被舞台误推进 step(Stage.tsx的closest检查)。 - 章节代码物理隔离:每章独立文件夹、独立 CSS 类前缀(
.cd-/.mg-等),不跨章 import,不修改chapters.ts之外的共享文件。这是模式 C 并行开发(subagent)能安全进行的前提。 - 每章必须有
narrations.ts(与<Chapter>.tsx同目录):- 数组长度=章节代码里
if (step === N)出现的最大 N + 1; - 每个元素 = 一个 string,该 step 要播的口播文本(来自
script.md对应段,语义一致——可微调标点 / 断句以适配 TTS,但不能漏关键短语); - 完全无音频的过场 step 用空串
"",Auto 模式会按字数估时撑过; - 这是音频合成 + Auto 模式自动推进的唯一真相源,写错或漏写会让录屏对不上嘴。
- 数组长度=章节代码里
- 动画时长必须 ≤ 该 step 的口播时长——Auto 模式严格按音频结束推进,没有"等动画跑完"的兜底。动画太长 → 三选一:写更长口播 / 拆 step / 调动画速度。详细机制见 AUDIO.md。
示例章节的 narrations.ts 完整示范了这三条约束:3 个元素严格对应Example.tsx中step === 0 / 1 / 2三屏;每个元素是与口播语义一致的中文文本;文件头注释明确写着"Length === number of steps the chapter component renders"以及"no 'minimum hold' knob"。
为什么 narrations.length 是唯一真相源
chapters.ts 的注释给出了设计动机:每章只维护narrations数组,不再有独立的totalSteps。数组长度既是 step 数,又是音频合成(extract-narrations.ts扫描它生成audio-segments.json)与运行时 stepper(useStepper按它计算步数)的唯一依据。这一设计"保证了音频合成管线、运行时 stepper、章节.tsx的 step 分支三者永不漂移"——SKILL.md称之为 5 处(script / outline / 章节代码 / chapters.ts / 音频文件)永不漂移的关键。
九、narrations.ts 与音频 / Auto 模式的联动
CHAPTER-CRAFT.md反复强调"动画时长必须 ≤ 口播时长",其根源在 useAudioPlayer.ts 的 Auto 模式推进逻辑:
- 有音频:监听
<audio>的ended事件,trailMs(默认 200ms 缓冲)后自动next(); - 无音频 / 文件缺失 / 播放失败:退化为字数估时
estimateFallbackMs = max(1500ms, 字数 × 250ms)(约 4 字/秒,见 App.tsx 的estimateMs); - 明确没有"最小停留"旋钮:
useAudioPlayer的注释直言"Audio playback is the sole driver of step duration——there is intentionally no 'minimum hold' knob"。视觉动画比口播长,就会被当场切断。
三种播放模式的切换由 useAutoMode.ts 管理:URL?auto=1进 Auto、?audio=1进半自动 Audio、按M键循环 manual → audio → auto;Auto 模式首次需要按一次Space启动(绕过浏览器自动播放限制),此后整片全自动跑完,录屏可一镜到底。详细的合成流程、provider 选择与故障排查见 AUDIO.md。
这一联动就是"narrations 写错 = 录屏对不上嘴"的直接原因:narration 文本会原样进入 TTS 合成,每段音频长度又直接决定每个 step 的停留时间——所以完工自检要求"每条 narration 文本与script.md对应段落语义一致",并要求"每个 step 的视觉动画时长 ≤ 口播时长(口播字数 ÷ 4 ≈ 秒数)"。
十、完工自检:写完每章强制执行的硬性流程
CHAPTER-CRAFT.md规定章节实现完成后必须走"自检 → 修复 → 汇报"三步,禁止"实现完成 → 直接汇报给用户"。
执行方式(按能力降级):
- 优先 Agent Teams:开一个独立的 reviewer agent,传入本章代码路径 + 完工自检清单,让它逐项核查 + 出结论(哪几条 pass / 哪几条 fail + 证据);
- 其次 subAgent:当前 agent 没有 Teams 能力但能开 subagent,用 subagent 走同样的流程;
- 都没有:当前 agent 自己严格逐项核查,不允许目测一遍就放行。
拿到自检结论后:先按 fail 项改完代码,然后再向用户汇报"做完了 + 自检结论 + 改了什么"。直接拿原始结论汇报但不修复 = 违规。(SKILL.md的"硬性自检协议"把这套流程推广到了script.md与outline.md。)
写完一章 + 在浏览器点完一遍后,逐项过以下清单:
- 每章至少 1~2 处 CSS / SVG / Canvas / JS 视觉演示——没有 = 回去补
- 不同 step 的主导动作不一样——全章一种动画 = 回去重做
- 字号大、留白舒服、配色舒服
- 清单 / 列表逐个揭示,1 项 = 1 step
- 画面信息比口播稿多(回了原文章抽细节挂上来)
- 没有紫粉渐变 / 圆角彩色边框 / emoji / 假数据 / 假 logo
- 缺的素材用 placeholder,不是 fake
- 颜色和字体家族全部走 token(无硬编码 hex / 字体名);hero 数字 / 卡片 / 分割线 / 舞台用 primitive class 接入主题性格——这两条不达标 = 换主题就破
- 章节交付时主动告诉用户:"本章还缺这些素材"
- 禁止出现小号字体、大量纯文字(出现后必须回去改)
- 禁止出现任何形式的页眉页脚,仅展示关键内容(出现后必须回去改)
npx tsc --noEmit通过——不通过禁止汇报"做完了"- 章节代码物理隔离:独立 CSS 类前缀(
.cd-/.mg-/ ...),未跨章 import,未修改chapters.ts之外的共享文件 narrations.ts存在且narrations.length=== 章节代码里if (step === N)用到的最大 N + 1(不一致 = Auto 模式录屏会错位)- 每条 narration 文本与
script.md对应段落语义一致(关键短语 / 数字 / 引用全部保留,可为 TTS 微调标点断句)——录屏画外音应当能被观众听成同一段稿子 - 每个 step 的视觉动画时长 ≤ 口播时长(口播
字数 ÷ 4≈ 秒数)——超出会被 Auto 模式当场切断,动画演到一半就跳下一步
任一未过 → 回去改。不要"先放着以后修"。
结语:把这份指引当"单一必读入口"用
CHAPTER-CRAFT.md在SKILL.md的"各阶段文件读取指南"中被定义为Phase 2.4 实现单章的单一必读入口——十条原则 / 开工自问 / 内容驱动决策 / 视觉工具箱 / 时长参考 / 反 AI 味反模式 / 代码硬规则(含 narrations.ts 强制约束)/ 完工自检 / 反馈速查全部并入了这一份文件。写章节时只读它 + 当前主题的theme.json+ 当前章节的outline.md段落 +article.md本章对应段落 + 素材清单即可;references/EXAMPLES/不是必读,卡壳才翻。把这套"视频不是 PPT、每章必须有视觉演示、逐步揭示、双源原则、token 铁律、narrations 真相源、完工必自检"的方法论内化到每一次章节开发中,产出的就不是"会翻页的幻灯片",而是真正有电影感的可录屏视频网页。
- 人工智能
- AI 技能/插件
- 提示工程
【免费下载链接】garden-skills
ConardLi's open-source Skills collection, featuring web design, knowledge retrieval, image generation, and more.
相关推荐
web-video-presentation 的 outline.md 格式规范:把口播稿拆解为可开发的视频章节规划
web video presentation 的 outline.md 格式规范:把口播稿拆解为可开发的视频章节规划 导读 outline.md 是 web v
人工智能AI 技能/插件提示工程web-video-presentation 的 list-reveal anchor:列举型章节"逐项揭示"的实现指南
web video presentation 的 list reveal anchor:列举型章节"逐项揭示"的实现指南 导读 list reveal 是 ga
人工智能AI 技能/插件提示工程Pixelle-Video 视频模板开发完全指南:从内置模板到自定义 HTML 模板
Pixelle Video 视频模板开发完全指南:从内置模板到自定义 HTML 模板 本指南系统讲解 Pixelle Video(AI 全自动短视频引擎)中视频
人工智能AI 应用音视频媒体生成
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考