DESIGN.md@agent/ui/visuals/tai_chi · git:20261009.412a14e · 2026-10-09 · sha256 72c6b61831cf0849

DESIGN.md@agent/ui/visuals/tai_chi git:20261009.412a14eA

Immutable. This exact content never changes and is served at /api/v1/blob/72c6b61831cf0849.

# Tai Chi Visual Effect Design

## 1. 设计目标

Tai Chi 是一个连续演化的全屏视觉特效,用动画表现:

> 一画开天 → 阴阳分化 → 太极成形 → 四层演化 → 八卦归位

整个过程不是多个互不相关的画面切换,而是一条连续时间线。前一阶段已经存在的图形应尽量作为下一阶段的动画起点,避免突然消失、重新生成或位置跳变。

视觉基调:

- 背景保持应用当前主题背景,不额外覆盖不透明底色。
- 文字以 `ColorBase.primary_text` 和 `ColorBase.secondary_text` 为主。
- 强调色统一使用 `ThemeColor.alpha_theme_color(alpha)`。
- 文字和卦线使用中性前景色作为清晰主体,主题强调色只承担近、远两层光影和轨迹作用。
- 文字与卦线的光影参数统一由 `TaiChiGlowDrawing` 管理,不在各阶段单独设置描边宽度和透明度。
- 所有位置和尺寸根据 `Control.size` 动态计算,支持不同窗口比例。

## 2. 文件职责

| 文件 | 职责 |
| --- | --- |
| `TaiChi.gd` | 总控制器,驱动各阶段、维护 Shader 图层并决定当前绘制阶段。 |
| `TaiChiOpeningFlow.gd` | 绘制“一画开天”的水平线和开场文字。 |
| `TaiChiDualityFlow.gd` | 将一条线分化为阳爻和阴爻。 |
| `TaiChiFormationFlow.gd` | 将两仪线条变形成完整太极。 |
| `TaiChiEvolutionFlow.gd` | 太极缩小、移动,并从下到上生成四层结构。 |
| `TaiChiBaguaFlow.gd` | 将横排八卦连续移动成圆阵,并将太极移到圆心。 |
| `TaiChiGlowDrawing.gd` | 统一绘制文字和卦线的中性主体、主题色近层光与远层光。 |
| `TaiChiFill.gdshader` | 绘制黑白太极填充图案。 |

## 3. 总时间线

阶段按以下顺序自动启动:

1. Opening:`2.25s`
2. Duality:`2.2s`
3. Formation:`3.2s`
4. Evolution:`14.4s`
5. Bagua:`5.8s`
6. Carousel:八卦各展示一次,每卦 `4.8s`
7. Hexagram:上下卦相重并生成六十四卦,`10.8s`

`TaiChi._process()` 每帧推进当前阶段。当一个阶段的 `progress()` 达到 `1.0` 时,启动下一个阶段。

所有 Flow 均遵循相同生命周期:

- `reset()`:清空时间并停用。
- `begin()`:从零开始并激活。
- `advance(delta)`:累加时间,返回画面是否需要重绘。
- `progress()`:返回经过缓动处理的 `0.0–1.0` 进度。

## 4. 阶段一:一画开天

实现文件:`TaiChiOpeningFlow.gd`

### 步骤

1. 在画面中下部确定水平线中心。
2. 水平线从中心向左右两端同时延伸。
3. “一画开天”四个字同步出现。
4. 文字从中心向外展开,避免像普通淡入字幕。
5. Shader 在水平线周围添加非常轻的流动光带。

### 完成条件

`line_progress() == 1.0` 后启动两仪阶段。

## 5. 阶段二:两仪分化

实现文件:`TaiChiDualityFlow.gd`

### 步骤

1. 开场水平线分离成上下两行。
2. 上行保持完整,表示阳。
3. 下行从中心打开缺口,表示阴。
4. 左右辅助文字随动画后半段出现。
5. 开场标题逐渐退场。

### 完成条件

`progress() == 1.0` 后启动太极成形阶段。

## 6. 阶段三:太极成形

实现文件:`TaiChiFormationFlow.gd`

### 步骤

1. 阳爻弯曲为太极外圆的构造线。
2. 阴爻两段分别收束为上下两个鱼眼。
3. 中央 S 形分界线由上至下绘制。
4. 构造线逐渐退去。
5. `TaiChiFill.gdshader` 的黑白填充逐渐显现。
6. 太极下方显示“易有太极,是生两仪”及英文副标题。

鱼眼不能通过“横线各点直接插值到完整圆周”的方式生成,否则中间帧会发生路径交叉并形成绳结。当前实现把横线视为高度为零的椭圆:先逐渐增加椭圆纵向半径,再同步移动中心、收缩横向半径,最终得到无自交的圆。

### 关键进度

- `outer_progress()`:外圆构造。
- `upper_inner_progress()`:上方鱼眼。
- `lower_inner_progress()`:下方鱼眼。
- `divider_progress()`:S 形分界。
- `fill_progress()`:黑白填充。

### 完成条件

`progress() == 1.0` 后启动四层演化阶段。

## 7. 阶段四:太极缩小和标题退场

实现文件:`TaiChiEvolutionFlow.gd`

该阶段前半部分先处理太极和标题,再开始生成层级。缩小与移动不能同时发生。

### 步骤

1. 太极保持在成形阶段的中心位置。
2. `shrink_progress()` 驱动太极半径从大尺寸缓慢缩小。
3. 原标题保持相同字距和排版同步缩小。
4. 标题在缩小后半段逐渐透明并完全消失。
5. 太极缩小完成后保持原位,不再执行层级阶段的位置移动。
6. 四层结构和下方中英文说明都以太极中心为布局基准。

最终横坐标使用:

```gdscript
content_area(canvas_size).get_center().x
```

这不是整个窗口的几何中心,而是“阳”和“阴”两个内容格之间的正中间。

## 8. 阶段五:四层结构生成

实现文件:`TaiChiEvolutionFlow.gd`

四层从下到上排列:

1. 太极
2. 两仪
3. 四象
4. 八卦

`row_from_bottom == 0` 表示太极层,`row_from_bottom == 3` 表示最上层。

### 层级位置

- 最下层与缩小后保持不动的太极中心对齐。
- 最上层位于画面高度约 `16%`。
- 中间层通过线性插值均匀分布。
- 两仪、四象和八卦的爻线统一使用 `54px` 最终宽度。
- 层级标题的中心位于画面宽度约 `20%` 处,更靠近图案区域。
- 内容区域从画面宽度 `25%` 开始,占据约 `50%`,中心与太极对齐。

### 启动顺序

`row_progress()` 让各层从下到上依次启动,并保留少量时间重叠,使整体动画连续而不拖沓。

每层内部由 `item_progress()` 继续拆分:

- 左侧图案最先启动。
- 后续图案依次延迟。
- 每个图案拥有独立的完整飞行时间。

### 天外飞入动画

除太极以外的图案都从画面顶部之外飞入。

`flying_position()` 的计算过程:

1. 起点 Y 位于 `-70px` 以上,确保图案初始不可见。
2. 起点 X 在画面中心附近形成扇形分布。
3. 使用缓动插值从起点飞向目标位置。
4. 偶数和奇数索引使用相反的横向弧线。
5. 中段弧线偏移最大,起点和终点偏移为零。
6. 图案从小尺寸逐渐恢复到最终尺寸。
7. 飞行中段绘制低透明度短拖尾。
8. 到达目标位置时拖尾自动归零。

当前 Evolution 总时长为 `14.4s`,用于保证飞行过程足够舒缓。

## 9. 爻象编码规则

两仪、四象和八卦统一由爻线图形表示,并在图形上方显示中文名称。各爻从画面上方向下绘制,最低有效位对应最上面一爻。

- 两仪名称与编码:`["阳", "阴"]`、`[1, 0]`。
- 四象名称与编码:`["太阳", "少阴", "少阳", "太阴"]`、`[3, 2, 1, 0]`。
- 八卦名称与编码:`["乾", "兑", "离", "震", "巽", "坎", "艮", "坤"]`、`[7, 6, 5, 4, 3, 2, 1, 0]`。

标准编码如下:

| 卦名 | 图形 | 二进制 | 十进制 |
| --- | --- | --- | --- |
| 乾 | ☰ | `111` | 7 |
| 兑 | ☱ | `110` | 6 |
| 离 | ☲ | `101` | 5 |
| 震 | ☳ | `100` | 4 |
| 巽 | ☴ | `011` | 3 |
| 坎 | ☵ | `010` | 2 |
| 艮 | ☶ | `001` | 1 |
| 坤 | ☷ | `000` | 0 |

`TaiChiEvolutionFlow` 中的名称与编码常量是唯一数据来源。横排阶段和圆阵阶段必须共同使用八卦编码数组,禁止分别维护两套编码。

## 10. 阶段六:八卦归位

实现文件:`TaiChiBaguaFlow.gd`

四层完全生成后,八个横排卦象移动成圆阵。

### 无缝交接

1. `TaiChi.gd` 调用 `evolution.draw(..., false)`,停止由 Evolution 绘制八卦行。
2. Bagua Flow 在完全相同的源坐标绘制同一组卦象。
3. 初始尺寸、线距、透明度和文字位置与横排阶段一致。
4. 因此画面中没有“旧图消失、新图出现”的一帧跳变。

### 卦象移动

1. 八个卦象仍按横排从左到右依次启动。
2. 每个卦象从原横排位置直接移动。
3. 中途加入向上的浅弧线,使轨迹更自然。
4. 卦象移动时同步旋转为径向方向。
5. 卦线宽度、线距和整体尺寸逐渐放大。
6. 卦名和图案使用同一轨迹同步移动。

### 最终方位

- 上:乾
- 左上:兑
- 左:离
- 左下:震
- 右上:巽
- 右:坎
- 右下:艮
- 下:坤

这些方位由 `TARGET_ANGLES` 定义。

## 11. 太极进入圆心

太极不淡出,也不创建替代图片。

### 步骤

1. 使用 Evolution 阶段最终的太极坐标作为起点。
2. `taiji_progress()` 独立控制太极移动时间。
3. 太极缓慢移动到 `canvas_size * 0.5`。
4. 移动过程中半径逐渐增加到短边的约 `15.5%`。
5. Shader 始终使用同一个 `FillLayer`,所以黑白图案连续稳定。

## 12. 圆阵框架

当卦象接近最终位置后,`frame_progress()` 开始绘制圆阵:

1. 从正上方顺时针绘制第一条外圆。
2. 绘制第二条较淡的外圆。
3. 绘制包围中央太极的内圆。
4. 沿外圆依次生成 64 个刻度。
5. 每隔 8 个刻度使用较长线段,标记八卦主方位。

圆环和刻度使用低 Alpha 主题色,不能压过中央太极和八个卦象。

## 13. 主题色与透明度

禁止直接使用不透明主题色绘制大面积元素。

推荐形式:

```gdscript
ThemeColor.alpha_theme_color(alpha)
```

主要透明度范围:

- 卦线:约 `0.32–0.58`,取决于阶段和强调程度。
- 单元格边框:约 `0.24`。
- 亮格填充:约 `0.07`。
- 拖尾:最高约 `0.055`。
- 圆环:约 `0.09–0.16`。
- 刻度:最高约 `0.20`。

主题色变化时,`TaiChi.on_theme_changed()` 会触发重绘,所有线条和文字从统一绘制工具获取最新主题色。

## 14. 绘制层级

`TaiChi.gd` 中的主要绘制层:

1. `FillLayer`:`z_index = -1`,Shader 太极填充。
2. `_draw()`:统一绘制构造线、层级结构、卦象、圆环、光影和文字。

FillLayer 从太极成形阶段一直复用到最终圆阵。

## 15. 响应式规则

- 太极尺寸基于窗口短边计算。
- 层级 Y 坐标按窗口高度比例分布。
- 内容区按窗口宽度比例计算。
- 字号使用窗口高度比例,并通过 `clampi()` 限制最小和最大值。
- 圆阵半径使用窗口短边的约 `34%`。
- 小窗口下仍需保证太极、文字和圆环不互相覆盖。

## 16. 测试要求

测试场景:

```text
res://agent/test/visual/tai_chi_unit/TaiChiTest.tscn
```

关键断言包括:

- 各 Flow 能正确开始、推进和结束。
- 四层必须按从下到上的顺序启动。
- 飞行图案初始位置位于画面外,结束位置等于目标位置。
- 横排八卦编码必须为 `[7, 6, 5, 4, 3, 2, 1, 0]`。
- Bagua 阶段必须保持从左到右的启动顺序。
- 最终太极中心必须等于画布中心。
- 最终太极半径必须大于四层结构中的小太极半径。
- Shader 图层必须存在,并使用正确的透明主题色。

修改动画后至少执行:

```powershell
godot --headless --path . res://agent/test/visual/tai_chi_unit/TaiChiTest.tscn
```

新增脚本或修改复杂绘制函数时,还应显式检查脚本解析:

```powershell
godot --headless --path . --check-only --script res://agent/ui/visuals/tai_chi/TaiChiEvolutionFlow.gd
godot --headless --path . --check-only --script res://agent/ui/visuals/tai_chi/TaiChiBaguaFlow.gd
```

## 17. 后续修改原则

1. 优先延续已有图形,不用淡出后重新创建的方式模拟移动。
2. 修改卦象编码时只改 `TRIGRAM_VALUES`。
3. 修改层级位置时同时检查太极与“两仪”中心对齐。
4. 修改八卦源位置时确保 Bagua Flow 与 Evolution Flow 使用相同坐标公式。
5. 增加主题色强度时优先调整 Alpha,不要改为不透明颜色。
6. 修改阶段时长后,检查快速 Agent 任务结束时是否仍有足够播放时间。
7. 所有新增函数遵循项目 GDScript 规范:显式返回类型,且无显式 `return` 的命名函数以 `pass` 结束。

## 18. 阶段七:八卦说明轮播

实现文件:`TaiChiCarouselFlow.gd`

圆阵稳定后依次展示八卦,并为六十四卦阶段保留圆阵结构。

### 入场步骤

1. 太极围绕自身中心旋转约一圈半。
2. 太极在旋转过程中逐渐透明,最终完全消失。
3. 外侧双圆环、内圆和 64 个刻度开始持续缓慢旋转。
4. 八个卦象保持固定方位,确保文字和图案始终可读。
5. 中央区域由太极图案平滑交接为八卦说明。

### 轮播内容

每一卦展示三层信息:

- 自然象征:天、泽、火、雷、风、水、山、地。
- 对应说明:乾为天、兑为泽、离为火、震为雷、巽为风、坎为水、艮为山、坤为地。
- 核心特性:例如乾的“刚健 · 自强 · 创造”和坤的“柔顺 · 承载 · 包容”。
- 《象传》原文:显示在圆阵内部下方,并与当前卦同步切换。

### 轮播规则

1. 按圆阵顺时针方向播放:乾、巽、坎、艮、坤、震、离、兑。
2. 每项持续 `4.8s`。
3. 开头 `18%` 时间淡入,结尾 `18%` 时间淡出。
4. 中央主字进入时带轻微向上稳定的位移。
5. 当前卦象在外圈同步提亮并轻微呼吸放大。
6. 八项结束后不再回到乾,而是进入六十四卦生成阶段。

## 19. 阶段八:八卦相荡与六十四卦

实现文件:`TaiChiHexagramFlow.gd`

1. 八卦说明轮播结束后,旋转圆环平滑减速并回正。
2. 八个三爻卦分成内外两层,表现上卦与下卦的组合关系。
3. 外圈八卦保持固定,内圈八卦每轮旋转一个方位,形成一组新的上下卦关系。
4. 每轮同时绘制八个扇形组合框,分别框住八组内外卦象。
5. 当前八组组合生成六爻卦后,分别飞入八个扇区内属于自己的位置。
6. 飞行动画结束后内圈再次旋转,共执行八轮,使每个扇区最终拥有八个六爻卦。
7. 六十四卦生成完成后,中央显示“六十四卦”、“变动不居,周流六虚”和注解“(变化之象,周流不息)”。
8. 全景只显示微型六爻图形,不同时显示 64 个名称,避免小窗口信息拥挤。

最终落位采用伏羲先天六十四卦圆图的二进制次序,而不是生成轮次顺序:

- 第一半圆由乾 `63` 递减至复 `32`。
- 第二半圆从坤 `0` 递增,经剥至姤 `31`,最后与乾相接。
- 八轮旋转仍决定卦象何时生成;六爻编码决定它最终飞往圆图中的哪个位置。

六爻编码延续现有绘制约定:最低有效位位于图形最上方,因此组合公式为:

```gdscript
hexagram_value = upper_trigram | (lower_trigram << 3)
```

## 20. 阶段九:六十四卦轮盘问卦

实现文件:

- `TaiChiDivinationFlow.gd`:提示、中心罗盘针旋转、跑马灯高亮、命中与结果展示。
- `TaiChiHexagramCatalog.gd`:全部 64 卦的身份、上下卦、卦辞和大象辞配置。

### 流程

1. 六十四卦全景完成后显示“八卦定运势,运势生大业。”及英文说明。
2. 伏羲六十四卦圆盘保持静止,中心细针旋转一次并缓慢指向目标。
3. 针尖经过的卦象实时提亮、放大,形成沿固定圆盘移动的跑马灯效果。
4. 程序先等概率确定一个六爻编码,再计算目标角度并驱动指针缓慢停止,结果不依赖帧率。
5. 命中卦从圆盘原位沿弧线飞向中央,六爻同步放大,指针同时淡出。
6. 结果页优先显示核心结论、白话解读与宜忌建议,再以较低层级显示上下卦、卦辞和大象辞。
7. 指针使用严格单调的减速曲线,只向一个方向旋转,不做回转或回弹。
8. 结果内容淡入完成后完整停留 `3s`,随后才允许视觉特效结束。

圆盘位置使用伏羲先天卦序,结果身份使用文王卦序。例如六爻编码 `34` 在结果页显示:

```text
䷂  第 3 卦 · 水雷屯
上卦:坎 · 水    下卦:震 · 雷
```