@gitruck/cli 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
# GSAP-emit 契约 v1 · HTML 动画颗粒的逐帧 seek 渲染合规
|
|
2
2
|
|
|
3
|
-
> **契约版本**:gsap-emit v1(2026-07-10
|
|
4
|
-
> **边界**:本契约只约束**机器可判定的管线消费属性**(封装/注册/确定性/自包含/依赖可达/禁 var()
|
|
3
|
+
> **契约版本**:gsap-emit v1(2026-07-10;2026-07-24 增补铁律 7「占满坑位 + 终态驻留」,主理人硬性规定;同日铁律 6 增补字体注册表命中规则,对齐 gitruck-infra change `align-render-font-contract`)。产 HTML 动画颗粒、经同合云渲染管线(html_animate_render)逐帧 seek 合成的 skill/工具,其产物 MUST 满足本契约。
|
|
4
|
+
> **边界**:本契约只约束**机器可判定的管线消费属性**(封装/注册/确定性/自包含/依赖可达/禁 var()/字体名命中注册表)。画面长什么样——颜色、字体取值、构图、节奏——**一律由调用方按其栏目自身规则决定**,本契约不点名任何具体字体/颜色;文中示例取值均为中性占位。
|
|
5
5
|
|
|
6
6
|
## 原理(为什么不能用 CSS animation)
|
|
7
7
|
|
|
8
8
|
渲染引擎逐帧渲染时,靠调用每个子合成在 `window.__timelines` 注册的 GSAP 时间线的 `.seek(t)` 把画面定格到第 t 秒。GSAP `paused` 时间线 = 可被外部 seek 的虚拟时钟 → 逐帧正确;纯 CSS `animation-delay` 动画不在 `window.__timelines` 里,引擎 seek 不到 → 画面冻结(实测)。
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 七条铁律(违反任一条 → 整片渲染失败 / 颗粒冻结 / 全黑 / 坑位内突兀消失)
|
|
11
11
|
|
|
12
12
|
1. **`<template>` 包裹根元素**:`<template><div data-composition-id="<id>" data-width="1920" data-height="1080">…</div></template>`。编译器取的是 `<template>` 内容;裸 `<div>` 会被判 "empty or could not be parsed" 整片失败。(1920×1080 为**当前引擎版本约束**,分辨率参数化预留——升版时以本契约新版为准。)
|
|
13
13
|
2. **GSAP `paused` 时间线 + 注册**:`var tl = gsap.timeline({paused:true}); … window.__timelines = window.__timelines || {}; window.__timelines["<id>"] = tl;`。`<id>` 必须等于根的 `data-composition-id`。
|
|
14
14
|
3. **确定性**:禁用 `Math.random` / `Date.now` / 无参 `new Date()`(过不了引擎 StaticGuard)。要"随机感"用固定种子/解析式/递归生成(见「确定性配方」)。
|
|
15
15
|
4. **自包含 + 底色显式声明**:颗粒不依赖外部文件(除脚本 CDN)。**根底色透明与否必须显式声明**——全屏颗粒给根设明确 `background`(色值由调用方按栏目规则指定);叠加在底轨上的透明颗粒根**不设** background。不显式想清楚这一层,叠加合成必出错。
|
|
16
16
|
5. **脚本用渲染机可达的 CDN(编译期内联)**:`<script src="https://lib.baomitu.com/gsap/3.13.0/gsap.min.js"></script>` 或由渲染管线 vendor 本地。⚠️ jsdelivr 在渲染服务器不稳(实测 compile 期 `fetch failed` → GSAP 未加载 → 整片全黑)。编译器**只内联 http(s) CDN、不内联相对本地路径**(写 `src="gsap.min.js"` 运行时 404)。
|
|
17
|
-
6. **颜色/字体用字面值,禁 CSS `var()`
|
|
17
|
+
6. **颜色/字体用字面值,禁 CSS `var()` 自定义变量;字体名 MUST 命中服务端注册字体表**:编译器/挂载不可靠地解析 var()(字体映射把 `var(--font-body)` 当字面字体名;颜色 var() 不应用 → 整片全黑,实测)。直接写字面值(如 `#RRGGBB` / `'某字体名'`);SVG 属性里同样禁 var()。栏目级换色/换主题 = **生成期**替换字面值(查调用方自己的词表/token 注入),不是运行时变量。**字体名规则(2026-07-24 增补)**:font-family 的每个具名家族 MUST 逐字符命中渲染服务端注册字体表(gitruck-infra 仓 `utils/assets/text/classic_template/font_manifest.json`,中英别名等价),并 SHOULD 以 `sans-serif`/`serif` 通用族收尾兜底;表外名字渲染不失败但**字形不保证**(服务端 fail-open 系统回退,2026-07-24 真机实锤:错名导致宋体被渲成回退黑体)。具体选哪款仍由调用方栏目规则决定,本契约不点名。
|
|
18
|
+
7. **占满坑位 + 终态驻留(2026-07-24 主理人硬性规定)**:颗粒时间线总长 MUST ≥ 它在成片中的**坑位时长**(落轨 clip 的实际时长,通常 = 派单槽位包络 `track_ed − track_st`,**不是** `duration_hint`);动画主叙事播完后,颗粒 MUST 以「**定格保持**」或「**有限次循环**」驻留到坑位末尾——坑位内任意时刻(含最后一帧)核心内容必须可见。**禁止**「整体渐隐到空 / 全局退场 / 清空画面」类收尾:渐隐会与剪辑层转场冲突,淡出与否由剪辑/装配层决定,不在颗粒内做。局部元素可按叙事退场(黯淡/让位),但画面在坑位内不得归零;**定格不动是完全合法的终态**(不必为凑动作密度在尾段硬加动画)。违反表现 = 观感上「动画一过完整个颗粒突兀消失」(2026-07-24 回声定位真机实测)。
|
|
18
19
|
|
|
19
20
|
## 颗粒骨架(中性模板)
|
|
20
21
|
|
|
21
22
|
```html
|
|
22
23
|
<template id="p">
|
|
23
24
|
<div data-composition-id="<id>" data-width="1920" data-height="1080"
|
|
24
|
-
style="position:absolute;inset:0;/* 底色显式声明:全屏颗粒填你栏目的底色,透明叠加则删除 background */background:<你的底色>;overflow:hidden;font-family:'
|
|
25
|
+
style="position:absolute;inset:0;/* 底色显式声明:全屏颗粒填你栏目的底色,透明叠加则删除 background */background:<你的底色>;overflow:hidden;font-family:'<你的字体·须命中服务端 font_manifest.json>',sans-serif;">
|
|
25
26
|
<style> [data-composition-id="<id>"] .xxx{ … } </style> <!-- 样式用属性选择器作用域,防跨颗粒污染 -->
|
|
26
27
|
<svg viewBox="0 0 1920 1080" preserveAspectRatio="xMidYMid meet" style="position:absolute;inset:0;width:100%;height:100%;">…</svg>
|
|
27
28
|
<script src="https://lib.baomitu.com/gsap/3.13.0/gsap.min.js"></script>
|
|
@@ -58,5 +59,5 @@
|
|
|
58
59
|
- **样式作用域**:颗粒与其他颗粒/根同处一个文档,全局类会撞——用 `[data-composition-id="<id>"] .xxx` 属性选择器作用域。
|
|
59
60
|
- **`<template>` 内的 `<script>` 默认不执行**——引擎把 template 内容克隆进文档后才执行;本地直接开浏览器不会跑,必须经引擎/player。
|
|
60
61
|
- **transform-origin(SVG)**:缩放 `<g>` 用 GSAP `svgOrigin:"x y"`(SVG 用户坐标),别用 CSS transform-origin。
|
|
61
|
-
- **时间线总长 ≥
|
|
62
|
+
- **时间线总长 ≥ 坑位时长**:颗粒 tl 总时长 ≥ 落轨 clip 时长(坑位包络),否则 seek 越界(已升格为铁律 7,含终态驻留要求)。
|
|
62
63
|
- **别用 `requestAnimationFrame`/`setInterval` 驱动画面**——不被 seek,等于冻结。所有视觉变化必须挂在 tl 上。
|
package/package.json
CHANGED
package/skills/gtrk-mg/SKILL.md
CHANGED
|
@@ -49,6 +49,8 @@ gtrk mg status --project "<split产物目录>" --json
|
|
|
49
49
|
### 2. 逐槽位产颗粒(驱动栏目 MG 生产 skill)
|
|
50
50
|
|
|
51
51
|
对每个「缺 HTML」的槽位:把它的 `composition_id` + `handoff`(`theme` / `duration_hint` / `category`:`overlay` 透明叠加·不挡主体 / `fullscreen` 不透明满屏)+ beat 语义上下文,**交给第「业务分离」节解析出的栏目 MG 生产 skill 产一颗 html-particle**。产完把颗粒**存到 `<产物目录>/mg/<composition_id>.html`**(`gtrk mg` 就从这里读)。
|
|
52
|
+
- **产前先抽帧看底轨(`overlay` 槽位必做,别只凭派单盲产)**:颗粒最终要叠在真实画面上,构图必须因势象形。对该槽位挂点用本地 ffmpeg 抽 1-2 帧(`ffmpeg -ss <track_st秒> -i <底轨视频> -frames:v 1 <out.jpg>`,成本≈0)看清三件事——①真人主体/人脸的位置(颗粒 bbox 避开,呼应栏目「不盖说话人」铁律);②该处是否已有烧入包装或 AI 画面(有 → 别铺这颗,报用户裁决——二次过毛片高发);③画面明暗基调(深底/浅底影响衬底与配色取舍)。把这些**连同抽帧图一起附进产片订单**交给栏目生产 skill;`fullscreen` 槽位可免(满屏不透明无避让问题)。
|
|
53
|
+
- **产片订单必须附带坑位硬约束(gsap-emit v1 铁律⑦,2026-07-24 主理人硬性规定)**:颗粒 GSAP 时间线总长 ≥ **坑位时长**(该槽位 `track_ed − track_st` 包络,**不是** `duration_hint`)+ 0.3s 余量;`duration_hint` 只是动画主叙事节奏参考。主叙事播完后颗粒必须**定格保持或有限循环驻留到坑位末尾**——坑位内任意一帧核心内容都可见;**禁全局渐隐/整体退场/清空画面**(渐隐与剪辑层转场冲突,淡出由剪辑层决定);定格不动是合法终态。违反的观感 = 动画一过完颗粒突兀消失。
|
|
52
54
|
- **`-aux<n>` 叠层颗粒同样处理**:`gtrk split` 若在某 beat 的 `aux_layers` 派了 `overlay`,会派生 `<beat>-aux<n>` 进 `dispatch.mg`(多为 B-roll 底轨之上叠透明概念图解)——照样产、照样存到对应 `composition_id.html`。
|
|
53
55
|
- **category 决定叠法**:`overlay` 颗粒背景透明、盖在 B-roll 上不挡主体;`fullscreen` 不透明满屏。最终透明度由颗粒 HTML 根 `background` 反推的 `opaque` 定,生产 skill 要让二者自洽(lint 会查)。
|
|
54
56
|
|
|
@@ -73,6 +75,7 @@ gtrk mg --project "<split产物目录>" --json
|
|
|
73
75
|
- **`laid`** = 铺成的 `composition_id`。
|
|
74
76
|
- **`skipped`** = 缺 HTML / lint 失败的 beat(不拦其余)——**回步骤 2 补产、重铺**,别当没看见。
|
|
75
77
|
- **只铺单个 beat**:`--only <beatId>`(主颗粒 + 其 `-aux<n>` 叠层一并选),适合迭代改单段。
|
|
78
|
+
- **铺完必核「clip 占满坑位」**:读回 `.gtrk`,各 beat clip 的时长必须 = 槽位包络(`track_ed − track_st`)。若你的 CLI 版本按 `dispatch.mg[].duration`(旧 `duration_hint` 语义)落轨、导致 clip 短于坑位(颗粒在 beat 中途突兀消失,2026-07-24 真机实测),**把 `dispatch.mg[]` 各条 `duration` 改为包络秒数(`track_ed − track_st`)后重铺**(铺轨幂等、直接覆盖)。CLI 侧根治(落轨恒用包络)落地后此步可省。
|
|
76
79
|
|
|
77
80
|
### 5. 循环到铺满
|
|
78
81
|
|
|
@@ -41,6 +41,8 @@ gtrk split --project "<oralcut产物目录>" --json
|
|
|
41
41
|
|
|
42
42
|
按下面「拆分方法论」把连续的 utterance 分成若干 beat。一个 beat 覆盖**连续的 id 区间**(可跨多句),但**不能跨前后两处拼接**。beat 之间允许留空隙(未覆盖段默认 A_ROLL 底轨直出),**不许重叠**。
|
|
43
43
|
|
|
44
|
+
**抽帧确认底轨画面(凡毛片可能已含视觉包装时必做,勿只凭文稿派单)**:view.json 只给你文字,看不见画面——但毛片未必是素的。**二次过 / 补 ov 场景**(毛片本身是已烧入 MG、AI 再现或其他包装的成片再加工)尤其危险:只凭时码派 overlay 会撞上已有包装叠罗汉。姿势:对候选挂点(尤其打算派 `overlay` 的句区间)用本地 ffmpeg 按 `track_st` 抽 1 帧看一眼(`ffmpeg -ss <秒> -i <毛片> -frames:v 1 <out.jpg>`,成本≈0),确认该处画面性质——**裸口播 → 正常派;已有包装 → 避开该区间或另选挂点;拿不准 → 列给用户裁决**。首次过全素毛片可免;一旦毛片来历含「粗剪成片 / 待 ov 补充 / 二次过」字样,此步为硬门。抽帧顺带看清真人主体位置与画面明暗,写进 beat 的语义上下文,供下游产颗粒时构图避让。
|
|
45
|
+
|
|
44
46
|
### 3. 写拆分稿 JSON
|
|
45
47
|
|
|
46
48
|
按 `references/field-schema.md` 的契约写。骨架:
|
|
@@ -51,6 +51,9 @@
|
|
|
51
51
|
// lane === "MG"(遗留 "RRV_MG" 读旧兼容)
|
|
52
52
|
"handoff": { "category": "overlay", "slug_hint": "neural-overfit", "theme": "overfitting", "bg": "paper", "duration_hint": 12 }
|
|
53
53
|
// duration_hint(秒)必填;slug_hint / theme / bg / category 可选(bg 底色可由底轨态推导)
|
|
54
|
+
// ⚠️ duration_hint 语义(2026-07-24 主理人硬性规定):只是「动画主叙事时长」参考,供生产 skill 排布节奏;
|
|
55
|
+
// 落轨 clip 恒占满槽位包络(track_ed − track_st),颗粒 tl 总长须 ≥ 包络、终态定格或有限循环驻留、
|
|
56
|
+
// 禁全局渐隐退场(gsap-emit v1 铁律⑦)。别把 duration_hint 当颗粒寿命写短。
|
|
54
57
|
// category(颗粒品类子类型,裁决⑩):overlay(透明叠加,叠在 A-roll/B-roll 上,不挡主体)
|
|
55
58
|
// | fullscreen(不透明满屏,旁白主导整帧);缺省=下游按颗粒 HTML 根 background 反推透明度。
|
|
56
59
|
// 二期扩 subtitle/title。供剪辑器色带按品类分层(叠加/满屏 各一行)。
|