diff --git a/docs/superpowers/specs/2026-05-03-ink-wash-enhancement-design.md b/docs/superpowers/specs/2026-05-03-ink-wash-enhancement-design.md new file mode 100644 index 0000000..57c8f5b --- /dev/null +++ b/docs/superpowers/specs/2026-05-03-ink-wash-enhancement-design.md @@ -0,0 +1,151 @@ +# 粒子束墨韵增强设计规格 + +> 日期: 2026-05-03 +> 状态: 已批准 +> 方向: 方案A — 墨韵增强 + +## 1. 背景与问题 + +当前 InkDataMorph 组件的粒子束动画存在以下视觉问题: + +1. **粒子像散点图** — 椭圆+旋转仍呈"圆点"感,缺少水墨"晕染渗透"质感 +2. **扩散阶段缺乏墨韵** — 粒子简单扩散+缩小,无墨汁层层渗透感 +3. **连接线过于几何化** — 贝塞尔曲线像数据图表,缺少"墨丝牵连"有机感 +4. **背景缺乏宣纸质感** — 简单径向渐变太平淡 +5. **移动端视觉单薄** — 粒子少且效果被砍太多,画面干涩 + +## 2. 设计目标 + +- 让每个粒子都像一滴墨在宣纸上晕开 +- 不增加粒子数量,提升单个粒子的视觉表现力 +- 移动端用"少而精"策略保持质量 + +## 3. 核心升级项 + +### 3.1 四层晕染系统 + +每个粒子绘制4层径向渐变叠加,模拟墨汁在宣纸上的多层渗透: + +| 层级 | 名称 | 半径倍数 | 透明度倍数 | 色调范围 | +|------|------|---------|-----------|---------| +| 第1层 | 核心 | r×1 | op×0.9 | 深色调(tones 0-1) | +| 第2层 | 浓墨 | r×1.5 | op×0.4 | 深色调(tones 0-1) | +| 第3层 | 淡墨 | r×3 | op×0.12 | 浅色调(tones 2-4) | +| 第4层 | 水渍 | r×5 | op×0.04 | 浅色调(tones 2-4) | + +色调分配策略: +- 核心层+浓墨层使用深色调,模拟浓墨 +- 淡墨层+水渍层使用浅色调,模拟淡墨和水渍 +- 强调色(#C41E3A)粒子:核心层用强调色,外层渐变为暖灰 + +### 3.2 不规则墨迹边缘 + +用极坐标噪声路径替代简单椭圆: + +``` +for angle 0 → 2π: + noise = sin(angle*3 + seed1) * 0.3 + cos(angle*5 + seed2) * 0.2 + r_actual = baseRadius * (1 + noise * wobbleFactor) + x = cx + cos(angle) * r_actual + y = cy + sin(angle) * r_actual +``` + +- 每个粒子有独立的 seed1, seed2(创建时随机生成) +- wobbleFactor 在 spreading 阶段从 0.3 渐变到 0.15 +- 核心层 wobbleFactor 小(浓墨边缘清晰),外层 wobbleFactor 大(淡墨边缘模糊) + +### 3.3 墨丝效果 + +spreading 阶段,近距离粒子对之间绘制"墨丝": + +- 触发条件:两粒子距离 < connectionDistance × 0.5 且都在 spreading 阶段 +- 绘制方式:贝塞尔曲线连接,线宽从中间粗(1-2px)向两端细(0.3px)渐变 +- 透明度:distRatio × 0.15 × min(opacityA, opacityB) +- 颜色:两端粒子的混合色 +- 控制点偏移模拟毛笔拖拽弧度 + +### 3.4 宣纸纹理叠加 + +- 初始化时用 OffscreenCanvas 生成一次性噪声纹理(灰度点阵+细微纤维线条) +- 桌面端纹理分辨率 256×256,移动端 128×128 +- 每帧渲染最后一步,用 `globalCompositeOperation = 'overlay'` 铺满画布 +- 纹理内容:随机灰度点 + 水平方向纤维线条,模拟宣纸纤维结构 + +### 3.5 飞白笔触 + +settling 阶段的粒子沿运动反方向绘制渐变消失的笔触: + +- 起点:粒子当前位置 +- 方向:粒子速度的反方向 +- 长度:粒子半径 × 3-5 +- 宽度:从粒子半径渐变到 0 +- 透明度:从 0.25 渐变到 0 +- 形态:略带弧度的二次贝塞尔曲线 +- 只有非 splash 粒子才绘制飞白 +- 飞白效果在 morphing 阶段逐渐消失 + +## 4. 移动端适配策略 + +核心原则:不砍效果,"少而精"——粒子数减少但单个粒子表现力增强。 + +| 参数 | 桌面端(≥1024) | 平板(768-1023) | 移动端(<768) | +|------|-------------|-------------|------------| +| 粒子数 | 180 | 120 | 70 | +| 晕染层数 | 4 | 3 | 3 | +| 晕染半径系数 | 1.0 | 1.1 | 1.2 | +| 墨丝距离阈值 | 0.5×conn | 0.4×conn | 0.35×conn | +| 飞白效果 | ✅ | ✅ | ❌ | +| 宣纸纹理 | 256px | 128px | 128px | +| 噪声边缘 | ✅ | ✅ | ✅(简化) | +| 中心点 | 2个 | 2个 | 1个(偏右上) | +| trail长度 | 6 | 4 | 2 | + +## 5. 数据模型变更 + +### Particle 接口新增字段 + +```typescript +interface Particle { + // ... 现有字段保留 + seed1: number; // 噪声种子1 + seed2: number; // 噪声种子2 + wobbleFactor: number; // 当前边缘扰动系数 + prevVx: number; // 上一帧速度x(飞白方向) + prevVy: number; // 上一帧速度y(飞白方向) + inkLayerCount: number; // 晕染层数(响应式) +} +``` + +### ResponsiveConfig 接口新增字段 + +```typescript +interface ResponsiveConfig { + // ... 现有字段保留 + inkLayers: number; // 晕染层数 + inkRadiusScale: number; // 晕染半径系数 + inkStringThreshold: number; // 墨丝距离阈值比例 + showFeibai: boolean; // 是否显示飞白 + paperTextureSize: number; // 宣纸纹理分辨率 + wobbleDetail: number; // 噪声边缘采样点数 +} +``` + +## 6. 性能考量 + +- 宣纸纹理只生成一次,缓存到 OffscreenCanvas,每帧仅做 overlay 合成 +- 不规则墨迹边缘用 16-24 个采样点绘制路径(桌面端24,移动端16) +- 墨丝效果仅在 spreading 阶段绘制,且受距离阈值限制 +- 飞白笔触仅在 settling 阶段绘制,每粒子仅一条 +- 四层晕染中,水渍层(第4层)使用 fillRect 而非 arc,减少路径计算 + +## 7. 验收标准 + +- [ ] 桌面端粒子呈现4层墨韵晕染效果 +- [ ] 粒子边缘不规则,呈现墨迹形态 +- [ ] spreading 阶段近距离粒子间有墨丝连接 +- [ ] 背景有宣纸纹理质感 +- [ ] settling 阶段粒子有飞白笔触 +- [ ] 移动端粒子虽少但视觉表现力充足 +- [ ] 移动端帧率 ≥ 30fps +- [ ] 桌面端帧率 ≥ 50fps +- [ ] 所有现有测试通过