Viva Video
从一份产品文档做出一支讲得准、看得清、每一帧都由代码生成的片子。
和 cinematic-product-video 的区别:那个用 SeedDance 生成电影感素材,偏品牌向。这个一帧生成素材都不用,全部代码渲染,偏信息向。两个 skill 互不依赖,不要混用。
交付的是成片,不是分镜稿。只被要求改规格或提示词时,止于文件修订与校验,不启动付费生成或完整渲染。
第一件事:读懂文档。这一步不过,后面全错
片子讲不清的首要原因不是渲染,是没吃透文档就开始排版。
film-rules.yaml的comprehension段是 blocking 的,compose_spec.py会拦。
要产出三份东西
| 文件 | 内容 | 作用 |
|---|---|---|
UNDERSTANDING.md | 这是什么、解决谁的什么问题、机制因果链、关键数字及其测量条件、观众看完要能回答的三个问题、文档没有主张的事、读不懂的点标 unknown | 防止片子说错、说大 |
CLAIMS.md | 每条结论一行:claim / 原文出处 / 机制 / 收益 / 限定条件 / 画面证据 / 风险措辞 | 片里每句话都要能回查到这张表 |
CONCEPT_MAP.md | 文档章节 → claim → 机制与收益 → 画面主体与动作 → 禁止的误读 → 判定所需证据 | 把"讲什么"翻译成"画什么" |
同时把结论填进 content.yaml 的 content.understanding,compose_spec.py 校验它。
合上文档,回答这五个问题
答不上来就回去重读,不要带着问号往下做。
- 这个东西解决的问题是什么,用户原来怎么做、痛在哪
- 把机制讲成一条因果链,中间不跳步
- 哪一个数字最能证明结论,它在什么条件下测出来的,换条件还成立吗
- 观众最可能把它误解成什么,画面要怎么防
- 文档里哪些话是营销话术、不能当事实播
读懂之后要重新组织,不是照搬目录
顺序按 问题 → 旧做法的代价 → 新机制 → 证据 → 适用边界 → 下一步动作。 每个场景只讲一个结论;结论先行,再给机制,再给证据。术语第一次出现时用一句话解释。
禁止:用"大幅提升""全面升级""显著优化"替代文档里已经给出的具体数字;文档没给数字时自己编;把路线图讲成已交付;把示例代码改写成更漂亮但跑不起来的写法;没读懂某章就按标题猜。
compose_spec.py 会扫这些套话并报错。
检查点
写 content.yaml 之前,把 UNDERSTANDING.md、章节大纲、每章一句结论、每章打算用的视觉原型交给用户过一遍。
事实层没过审不进入视觉层。这一步返工最便宜,成片返工最贵。
方法来源:转场决策表、焦点三件套、能量骨架、三米测试、中文排印这几节借自 huashu-design(花叔)。搬了什么、 哪些看过但没搬、为什么不搬,记在
references/borrowed-from-huashu-design.md。
三层结构,只有中间一层每次会变
| 层 | 文件 | 每次做片子 |
|---|---|---|
| 规则层 | references/film-rules.yaml | 不改。必须做到什么:读懂文档、一帧一件事、旁白与信息单元一一对应、讲到谁谁亮、零裸切、密度下限、渲染不变量 R01–R30、验收门 Q01–Q38、度量方法与阈值 |
| 主题包 | themes/<name>/theme.yaml | 换观感才改。长什么样:配色推导、字号、坐标、卡片与导航的画法、缓动曲线、转场选型、焦点的墨量、配乐的 BPM 与配器 |
| 产品内容 | 你的 content.yaml | 只写这个。理解、事实、章节、claims、指标、品牌资源、发音表、每章的讲法与信息单元 |
| 合成产物 | video-spec.resolved.yaml | 不要手改,脚本生成 |
规则层和主题包的分界线只有一条:换观感不应该能换掉「旁白要和画面对上」。
判据留在规则层,观感交给主题包;theme_contract 把两边都写成机器可查的清单,
包缺键、越界、或者伸手去改判据,validate_spec.py 当场拒绝。
默认包是 daylight(近白底 + 白卡片 + 品牌色三停靠渐变),是 skill 的默认观感。
怎么写一个新包见 themes/README.md。
SKILL=~/.agents/skills/viva-video
cp $SKILL/templates/content.example.yaml ./content.yaml
# 先读懂文档,填 understanding;再填其余 TODO
python3 $SKILL/scripts/compose_spec.py ./content.yaml -o ./video-spec.resolved.yaml # 加 --theme <包名> 换观感
python3 $SKILL/scripts/validate_spec.py ./video-spec.resolved.yaml --self-test
examples/content.viva-video.yaml 是填写示范(viva-video 1.0 自己的发布片,7 章)。
语音与视频模型:用户给什么用什么,没给就只用自己的能力
skill 不带任何语音或视频模型的地址和密钥。
- 用户说明了自己的语音合成、语音识别或视频模型怎么调用(命令、接口文档、已有脚本都算):把它包成一条命令写进
providers.json,之后tts.mjs、pron_calibrate.mjs、asr_check.mjs --backend command都走它。密钥只留在环境变量或用户自己的配置里,不写进工程文件、日志和消息。 - 用户没说:只用 agent 自己手上有的能力。环境里有现成语音工具就用;没有就出只带字幕、不带旁白的片子,发音检查记
not_tested。不要去猜或搜某个服务的地址和密钥。
格式、查找顺序和降级表见 references/providers.md。
换产品的前三件事,顺序不能颠倒
一、定发音
中文 TTS 把 Rspack 当一个英文词整体读,中间的 s 被吞掉——实测回转写成 Spac。
修法是让 TTS 按字母读,不是把名字转写成汉字。 写法:RS + 空格 + 余下的英文词。
| 显示 | 送进 TTS | 读出来 |
|---|---|---|
| Rspack | RS pack | R-S-pack |
| Rsbuild | RS build | R-S-build |
| Rstest | RS test | R-S-test |
| Rsdoctor | RS doctor | R-S-doctor |
2026-11-04 实测(某中文女声音色,语速 1.24,合成后用本地 faster-whisper 回转写):
| 写法 | 回转写 | 判定 |
|---|---|---|
Rspack | Spac | 否,s 丢失 |
RS pack | RSPAC | 采用,四名总长 7.78s |
R S pack | RS Pack | 可用,略长 |
R 斯 pack | OSPAC | 否,汉字"斯"把前面的 R 带偏 |
R-S-pack | RS Pack | 否,连字符插入停顿,整句长 1.5s |
而斯派克 | 而斯派克 | 否,整体中文化,英文词消失 |
单位必须展开:实测 915.8 ms 被读成「915.8 米」。写成「915.8 毫秒」。
pronounce.py 自动做这件事(只在数字后面的单位才替换)。
字母缩写(SSR / BFF / SWC / CLI)、小数、百分比、版本号 3.0 实测都读对,不要多此一举改写。
python3 scripts/pronounce.py --self-test # 8 条
python3 scripts/pronounce.py "分析耗时从 915.8 ms 降到 51.6 ms。"
node scripts/pron_calibrate.mjs --terms terms.json # 换产品/换音色时实测选写法
node scripts/asr_check.mjs --spec video-spec.resolved.yaml --voice voice/
换音色、换语速、引入新专名,一律先跑 pron_calibrate.mjs 实测,不要照抄上面的结论。 不同音色的字母读法不一样。
未回测不得标发音通过;ASR 通过也不等于听感自然,未试听标 not_tested。
二、定主题色与渐变
python3 scripts/theme_resolve.py --svg brand/logo.svg --out qa/theme-resolution.json
python3 scripts/theme_resolve.py --hex '#F93920'
按 design.theme.resolution_order:用户指定 → 品牌 SVG → 官网 CSS 变量 → 文档装饰色 → fallback。
取到的原始色先转 OKLCH,亮度钳 0.45–0.62、彩度钳 0.12–0.22,保留原色相。超出 sRGB 时降彩度映射,不许逐通道裁切——裁切会改色相,等于白归一化了。
渐变三停靠色沿色相圈朝同一个方向走,走向品红锚点(H=350°),跨度钳在 55°–86°,secondary 在 40% 处。双向走会让渐变中途折返,看着像 bug。用参考片自己的主色喂进去,能复现它自己的 #376CFF → #8E33F2 → #E3429B。
两条斜坡:标题用满饱和那条,≥96px 的大数字用浅一档(L +0.13、C −0.06)——大字面积大,满饱和会压过标题。
对比度分档:正文墨色 4.5,品牌色承担的大字 3.0,≥96px 主数值 2.3(参考片自身实测 2.37–2.86,再严会把整条渐变压浊)。
红绿橙是语义色,不参与推导。禁止把 error 红当普通容器边框或装饰。
三、给每章选视觉原型和讲法
视觉原型从 scene_language.archetypes 的八个里选:依赖图、代码加关系、请求响应、先发现后请求、前后指标、能力矩阵、状态机、分层架构。相邻两章不得重复。
讲法(explanation_mode)从 explanation_modes.vocabulary 里选,决定这一页要不要动、怎么动。先看信息是什么类型,再查选择表(见下面「抽象信息怎么讲」一节)。
信息单元每章写 3–5 个短标签,这既是密度下限的依据,也是"一个画面太多内容"的上限。
三项 compose_spec.py 都会校验。
版面:满不满、散不散
标题永远是「铺垫,结论」两段
前段墨色,后段整段上渐变。分界只能落在标点上,结论段占 35%–70%。
简洁、线性,|每一步单独读也成立
声明一次, |运行时检查与说明书自动就绪
同机实测, |跑得更多、更快、更省
content.yaml 里写成 headline_lead + headline_emphasis,compose_spec.py 校验比例和分界。
注意它和 title(章节名)是两个东西:章节名上章节页和导航,headline 是正文页的大标题。
渐变预算:每页最多 1 个标题 + 1 个主数值 + 2 个关键词。超了就不再是强调信号。 渐变不许用在 <32px 的字上(实测出带状断层),不许加描边投影发光,不许流动。
槽位先占满,关键内容后给
场景第一帧就把全部槽位画出来——容器边框、槽位标题(chip + 标题 + 分隔线)、内容骨架, 之后只改内容和透明度,包围盒不动。关键内容(数值、代码、标签)留到旁白讲到它时再填。
这一条同时解决三件事:版面从第一帧就是满的,观众看不到"内容还没长出来"的空页; 填充过程中不会重排抖动;第一眼看到的是这一页的结构,知道待会儿会讲几件事。
骨架必须带标题或占位结构,不许是纯空白圆角矩形。
槽位头部不能跟着内容一起等。 2026-11-05 实测的一个 bug:feature 和 stage 两种槽位
把标题挂在了内容的揭示事件上,结果页面开场时底下两张卡是纯白矩形。头部属于容器,内容属于节拍。
这条有像素级判定(R18 的实测半边): 场景开场帧(转场过完那一刻)正文区的最大空白矩形 ≤ 0.26。只测停留帧看不出来——停留帧上页面当然是满的,它看不见前八秒的半空状态。
还没填内容的槽位不要压暗。 见下面「焦点」一节:把空槽位也降到失焦档,页面立刻读成"还没长出来", 正好是预分配槽位要解决的那个毛病。实测把空槽位从 0.38 提到 0.80 之后,七个场景的开场帧 最大空白矩形从 0.29–0.62 降到 0.058–0.199。
没有框的内容必须收住
用户反馈"没有卡片的时候很分散",规则收紧成:
- 正文区里每个信息单元都要属于一个容器或带标签的组
- 允许无框的只有三种:紧贴容器下方的要点列表、页面底部的一句结论、顶部的 kicker 与标题
- 无框要点必须与相邻容器共享左边界和宽度,最多 7 列宽、最多 4 条,形状是「圆圈序号 + 粗体短标题 + 冒号 + 正文」同一行起排
- 同一页所有无框文字块只能有一条左边界
- 无框内容占正文区面积超过 40% 就必须收进容器
禁止:三四段文字各自居中彼此留白;用空行拉开距离来"填满";一页出现两种以上左边界。
密度下限(正文区 [120, 280, 1680, 610])
| 指标 | 下限 | 测法 |
|---|---|---|
| 容器占比 occupancy | ≥ 0.55 | 场景对象包围盒 |
| 垂直跨度 | ≥ 0.72 | 场景对象包围盒 |
| 横向跨度 | ≥ 0.86 | 场景对象包围盒 |
| 最大空白矩形 | ≤ 0.14 | 场景对象包围盒 |
| 最大空白带 | ≤ 150 设计px | 场景对象包围盒 |
| 独立信息单元 | ≥ 3 个 | 场景对象清单 |
| 稳定帧最大空白矩形 | ≤ 0.20 | 稳定帧边缘图 |
最后一条是像素级的,章节页/封面/结尾豁免。 不用"非背景像素比例":这套视觉是近白底上的白卡片,卡片填充会成为众数色,度量会反过来(实测参考片 0.144、被判审美差的那版 0.419,方向完全错)。边缘图不受影响。
内容不够时按 density.escalation 向下补,第 0 步先回头检查是不是槽位没预分配、内容没进容器——多数"空旷"是这个,不是内容不够。
禁止直接留空。禁止靠放大字号填版面。禁止用粒子光晕几何块冒充信息单元。
窗口壳按信息量判定,不按偏好
该用:内容天然属于某个界面(文件、配置、终端、编辑器、看板、报告);信息单元 ≤3 显得稀疏需要边界收拢;要表达"文件名 + 内容"的从属关系。
不该用:有更准确的表现形式且能撑满正文区;前两镜已连续用过;内容是抽象机制而非具体界面。
用了就要填满:内容填充率 ≥ 78%。窗口标题用真实文件名,不用"示例""Demo"。全片窗口场景 ≤ 50%,不连续三镜同一构图。
关系图与流程图
至少 4 节点 3 边。节点要标题加一行说明。每条有向边必须有动作标签和箭头,两端锚定到真实对象 id 的边界点,端点落空即为缺陷。 必须配一个说明面板,占正文区宽度 30%–42%:伪代码、配置片段、状态表、报文样例、指标条、步骤序列任选。伪代码 5–12 行,每行对应图上一个节点或一条边,渲染时同步高亮。
指标页
主数值之外至少 2 项支撑内容:前后对比图、构成拆解、测试条件块、同机制的第二个指标、产生该指标的真实配置、基准定义。 图表共享基线、标注刻度与数值。不同单位(qps 与 ms)必须分图或分轴。 顺序:先显示原值与测试条件 → 变化到新值 → 提升幅度落定 → 稳定保持。数字等宽、单位固定、只强调一次。
中文排印:西文那套不能照搬
| 规则 | 为什么 | |
|---|---|---|
| 行高 | display 1.15、标题 1.35、正文 1.65 | 汉字是满格方块,没有西文小写之间的天然空隙,行距不足会糊成一片。中文全线比西文高 0.2 左右 |
| 字距 | display(>60px)−0.02em、标题 0、正文 0 | 汉字字距天然均匀。标题加正字距会松垮,display 再负就笔画相撞。只有全大写西文小标签才需要 0.08–0.15em |
| 行长 | 一行 22–38 字,最佳 28–32 | 汉字密度高,同宽度承载的信息比西文多,行太长回行会迷路 |
| 字体栈 | 西文在前、中文在后 | 逐字符匹配:西文体不含 CJK 码位,汉字自然穿透到中文字体。反过来写,西文全被中文字体自带的难看西文吃掉 |
| 强调 | 换字重或加底色 | 中文没有斜体,浏览器/渲染器的合成斜体会扭曲汉字。合成加粗同理,一律禁掉 |
| 引号 | 直角引号「」『』 | 弯引号在中文字体里是全角占位、西文形状,视觉漂浮 |
| 数字 | 走西文字体 + tabular-nums | 否则 1 和 8 不等宽,数据列会左右抖 |
等宽字体必须验中日韩字形。 JetBrains Mono 没有 CJK,代码窗里的中文注释会变成豆腐块。 mono 字族要显式加中文回退。
三米测试
任一帧暂停,画面里最大的词在三米外可读;把关键帧缩到手机屏大小仍要读得出。 观众看视频时给每一帧的注意力比看静图更少,字号只能更大不能更小。 这条和密度下限互为上下限:密度下限防空旷,三米测试防"为了塞下而缩字号"。
一帧只讲一件事
用户反馈:内容、特效、旁白都要把信息表达清晰,不要模糊不清,不要一个画面太多内容。 这一节的每条规则都能被
motion_audit.py判定,不是审美建议。
信息预算:下限之外还有上限
| 值 | 说明 | |
|---|---|---|
| 信息单元下限 | 3 | 低于这个页面是空的 |
| 信息单元上限 | 5 | 高于这个 2 秒静帧测试就通不过 |
| 正文区文字总量 | ≤ 120 计数单位 | 汉字按字计、英文按词计 |
| 每个节拍新进入的信息 | 1 处 | 一组 stagger 算一处 |
计数按最外层的容器或带标签的组,组内子项不单独计。参考片 01:32 那一页按这个口径是 3 个单元(配置代码窗 + 云设备卡片组 + 流程条),卡片有 5 张也仍然算 1 个。
超了不要缩字号塞进去。按顺序试:拆成两个场景 → 同类合并成一个带标题的组 → 细节移进说明面板。
阅读路径按 F 型,而且是可测的
眼动研究里内容区的注视集中在三处:上方横条(kicker 与标题)、第二道横条(主内容首排)、左侧竖条(共享的那条左边界)。落到这套片子上:
- 起点:场景第一个揭示的信息单元,重心必须落在正文区左上(归一化 x ≤ 0.50、y ≤ 0.45)
- 顺序:揭示序列的垂直重心单调不减,最多允许一次向上回跳
- 竖条:无框文字块共用一条左边界(R14),容器左边吸附列网格(R13)
- 前置信息:标题、槽位标题、要点标题的前两个词必须自带信息。以「关于」「我们的」「更好的」「如何」开头的标题
compose_spec.py直接报错。
实测(content_box 内,12fps,每次切镜后 1.5 秒的变化重心):
| 起点 x | 起点 y | 向下铺开的切镜比例 | |
|---|---|---|---|
| 参考片 | 0.393 ± 0.121 | 0.336 ± 0.126 | 67% |
| 上一版被判审美差的成片 | 0.660 ± 0.175 | 0.498 ± 0.152 | 48% |
参考片从左上起步往下铺,那一版从偏右的中间往外铺——这是"显得分散"的直接成因之一,跟排得密不密无关。
画面和旁白必须讲同一件事
每个信息单元要写明它对应哪一句旁白,揭示时间落在 [句子开始 −0.4, 句子结束 +0.8] 秒内。写不出对应句子,说明这个单元在旁白里没人讲,应该删掉或者补讲。
画面上的文字是结论短语、专名、数值、标签,不是旁白的逐句抄写——同一句话同时听和读会互相抢占。字幕是独立轨道,不计入文字预算。
旁白也要一句一件事
- 一句话一个事实。两个事实写两句,不要用「同时」「并且」串起来。单句 ≤ 32 个计数单位。
- 每个场景第一句就是结论,后面才给机制和证据。
- 不连续用「它」「这个」指代;隔了一句就把名字再说一遍。
- 术语第一次出现当句解释,不留到下一句。
- 说出一个数字,同句或紧接一句必须带测量条件。
- 禁止:关键词清单式朗读(「更快、更强、更稳定」)、广告腔排比、一句三个专名、把画面上已经写清楚的内容再念一遍。
旁白逐句抄进 CLAIMS.md 做映射,映射不上的句子要么删掉,要么补成有出处的结论。
2 秒静帧测试
取场景的 hold 帧,遮住旁白与字幕,请一个不了解该产品的人说出这一页的结论和那个数字。说不出就是这一页没讲清楚。逐场景记 passed / failed / not_tested,没做就是 not_tested。
时长怎么分:先划 hold 预算,再排动效
多镜头片子的时长不是平均分的。四段骨架,占比是硬指标:
| 段 | 占比 | 能量 | 内容 | 硬指标 |
|---|---|---|---|---|
| 开场 | 8–12% | 低 | 品牌亮相 + 一句话说明整片要讲什么 | 字标落定后 hold ≥1 秒;第 0 帧就是完整封面 |
| 立传 | 10–16% | 低中,全片最慢 | 第一章,质感最高的一段 | — |
| 爬升 | 52–64% | 中高与低交替 | 一镜一个能力 | 每 1–2 个内容镜之间插一张章节页降能量 |
| 收场 | 10–16% | 全片峰值 | 回顾 + 关键数字 + 入口 | 不渐隐,读完保持到末帧 |
顺序:① 列能力清单数出镜头数 → ② 先把不可侵犯的静止时间划走(字标 hold、阅读停留、 章节页完整保持 1.1 秒、结尾保持 2 秒)→ ③ 剩下的时间才分给动效 → ④ 逐接缝选转场, 转场时长从相邻两镜的预算里划走,不另外加时。
不许连续两镜高能。 章节页就是降能量用的"呼吸字卡"——它是低密度、大留白、2–6 字, 别把它做成又一个信息镜头,那等于没插。
模板装饰黑名单
这些不是"丑",是"一眼看出来是套模板的"。顺手出现就删掉:
每个标题上方再加一行全大写英文小标签 · 「A · B · C」中点连接的词串 · 按钮或标签尾部的箭头装饰 · 标题里只给一个词换颜色 · 内容不是序列却用 01/02/03 编号 · 与机制无关的 emoji 图标 · 左侧彩条圆角卡片 · 发光粒子、数据流、全息 HUD、霓虹 · 深底加霓虹光晕冒充科技感。
判据是"它从内容里长出来了吗",不是"它看起来像不像模板"。 编号在真的是序列时合法(章节、推演阶段);渐变在它来自品牌色推导时合法。
接缝:全片零裸切
用户反馈(2026-11-05):「每个章节和下个章节的过度要非常自然,而不是直接显示显得非常生硬」。 公认优秀的发布片全程没有一次裸切。要"切"的效果,就用设计过的切。
每一个场景接缝都必须声明一种转场,时长从相邻两镜各自的预算里各划走一半——
转场不是加在片长上的,是从两镜里借的。窗口是 [边界 − 时长/2, 边界 + 时长/2],
这段时间里两个场景同时在画面上。
| 相邻两镜 | 用什么 | 时长 | 怎么做 |
|---|---|---|---|
| 封面 → 章节页 | 交叉淡化 | 0.62s | 封面淡出并逐渐模糊,章节编号同时由模糊解析出来 |
| 正文 → 章节页 | 交叉淡化 | 0.58s | 前一页淡出的同时编号模糊进入,两件事在同一窗口里 |
| 章节页 → 正文 | 棱镜扫光 | 0.92s | 编号放大虚化 → 彩虹光带斜扫 → 下一页在光带后面已成形,关键内容仍未展示 |
| 正文 → 结尾 | 交叉淡化 | 0.62s | 同上 |
| 正文 → 正文(同章内换镜) | 虚焦接力 | 0.50s | 只换模糊,不做横向位移 |
棱镜扫光:整屏覆一层 surface_tint 的薄纱(峰值 0.62),一条 1420 宽的光带斜 17° 扫过,
停靠色是主色 0.34 → 次强调色 0.30 → accent 0.26。禁止闪白、整屏擦除、翻页、旋转。
接缝吸附到旁白间隙(move on pause):只提前不推后,上限 0.8 秒。观众在听觉空档移动视线的成本最低。
判定(R27):把接缝窗口按 12fps 取帧,算全画面逐帧变化量; 单帧变化量占窗口总变化量 ≤ 0.55。裸切会把九成以上的变化挤在一帧里。 实测这一版七个接缝落在 0.155–0.35。
封面必须是第 0 帧。 播放器取 t=0 当海报;第 0 帧是空白,封面就等于没有。 所以封面不靠元素入场制造运动——元素一开始全在,运动来自不改变包围盒的三件事: 静止的同心圆环、两次扫光、旁白讲到哪个方向就让对应标签亮一下。 判定是第 0 帧正文区的边缘覆盖率 ≥ 封面停留帧的 0.90 倍。 连装饰也要在第 0 帧就位——实测圆环做成 0→1 的渐显,这个比值只有 0.673。
焦点:讲到谁谁亮,但讲过的要还能读
用户反馈(第二轮):「讲一个内容的时候其他的内容是置灰的,突出正在讲的内容」。 用户反馈(第三轮):「讲完后立马置灰了,根本没看完」「不要过于模糊,而是暗下去, 但是能看清内容」「如果讲完的内容和下面讲的内容有关联就暂时先不变暗」。
四档状态,只压墨量不压清晰度
| 状态 | 墨量 | 模糊 | 卡片 | 什么时候 |
|---|---|---|---|---|
| active | 1.0 | 0 | 有阴影,主色边框 | 旁白正在讲它。它靠"浮起来"被认出来,不是靠别人糊掉 |
| read | 0.70 | 0 | 无阴影,普通边框 | 讲过了。墨色压到视觉上约 #5A6070,对比度仍有 6:1,三米外读得出来 |
| waiting | 0.88 | 0 | 普通 | 还没轮到。只轻降,页面必须读起来是满的 |
| settled | 1.0 | 0 | 普通 | 旁白讲完,整页回到不透明 |
不用模糊。 这一条和 huashu-design 的「失焦三件套必须含 blur」冲突,在这里按信息片的 需要解决:模糊的作用是让元素停止竞争注意力,但信息片的观众还要回头读它。 模糊只保留给两处——场景之间的转场,和章节页编号的入场出场。
什么时候开始变暗
句子开始 句子结束 +1.0s +0.8s
|--------------|------------|------------|
active ============================>
变暗 [===渐变===] read
- 一个单元不得在它自己那句旁白结束之前开始变暗(R30 的声明半边)。
- 讲完之后再留 1.0 秒给观众读完,然后用 0.8 秒缓慢压下去。
- 旧做法是「下一句一开始就切焦点」。观众还在读上一块,画面已经把它夺走了。
相关联的两块一起亮、一起暗
配置和它的适用边界、数值和它的测量条件——这种成对的内容声明同一个 focus_group:
组内任何一个在讲,整组都保持 active;组里最后一个讲完 + 1.0 秒之后,整组一起变暗。
判定(R28)
取某个单元失焦时刻的一帧和停留帧的同一帧,比较同一个单元包围盒内的平均梯度幅值。 失焦态 ≤ 停留态的 0.85。
用平均梯度而不是阈值化的边缘数:只压对比度不加模糊时,阈值要么全过要么全不过, 度量会和处理脱钩。平均梯度随对比度线性变化,墨量 0.70 就测出 0.70 左右。
揭示:支撑内容开场就在,只有关键项等旁白
用户反馈(第三轮):「中间的框没有内容,下面的框没内容但是还有样式,第一眼看上去很奇怪」 「其实可以先把不重要的内容先显示出来。重要的在讲解的时候打字机展示」 「通常只需要打字机把内容打印出来。如果已经打印出来了,后面还有提及到这一行的时候, 再高亮一下背景」。
这条把第二轮的「关键内容留到旁白讲到它时再填」收窄了,不是推翻: 留到后面的只有每个单元的那一个关键项,不是整张卡。
开场就要画出来的
卡片、chip、标题、分隔线、行标签、次要行、结构。 一个单元只留一个关键项等旁白——那个数值、那段代码、那组标签。
一行只用一种动效
| 时机 | 用什么 | 不许叠加 |
|---|---|---|
| 首次出现 | 打字机,从左到右逐字,0.4–1.0 秒 | 不加扫光、不加底色带、不加左侧色条 |
| 后面再被提到 | 背景高亮带 #FFF4D6 + 3px 左侧色条,0.42 秒 | — |
高亮是「再次提到」的语言。 首次出现就高亮,这门语言就没了,观众分不清哪些是新的。
上一版给每一行都配了一次扫光,为的是凑「有变化帧占比 ≥ 0.45」—— 用户的原话是「里面的文字对应的动效太多」。为了凑动量堆装饰动效,现在直接判不过。
骨架屏什么时候可以用
内容确实要留到后面讲、并且骨架本身是设计过的时候可以用,但要满足: 带标题与结构(不是纯空白圆角矩形)、占位条宽度不等长(看起来像一段真实内容的轮廓)、 骨架不超过卡片高度的 60%、每张卡的骨架不能长得一模一样。
旁白和画面必须讲同一件事,这是底线
用户反馈(第三轮):「务必务必旁白和画面内容和动效要一致!!!这是底线」。
第二版的失败是声明本身就是错的:R22 只检查「揭示时间是否落在声明的那句话的时间窗内」, 从来不检查这句话是不是在讲这个单元。于是 2.8 倍那张卡挂在了「另一项耗时从 12.6 秒降到 4.0 秒」上——那句讲的是另一张卡的第二行——时间窗当然对得上,门当然全绿。
R29:一一对应,而且文本对得上
- 每个信息单元恰好声明一句旁白。
- 两个单元不得共用一句,除非它们是同一个 stagger 组、在同一拍里一起进入。
- 场景里每一句旁白都必须被某个单元声明,不允许孤儿句。
- 这句话的文本里必须出现该单元的关键词:卡片标题、行标签、数值、标签文字、文件名任一。
所以
content.yaml的每个信息单元都要写keywords。
R30:画面跟着旁白走
- 声明层:
dim_t >= 该单元那句话的结束时间 + 1.0 秒。 - 实测层:每一句旁白播放期间,它对应的那个单元框内必须有可见变化