From fc328aab59f590d449df633ebdf5020ed1daf9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E7=BF=94?= Date: Sun, 3 May 2026 16:38:08 +0800 Subject: [PATCH] docs: add Hero ink-data-morph animation design spec --- .../2026-05-03-hero-ink-data-morph-design.md | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 docs/superpowers/specs/2026-05-03-hero-ink-data-morph-design.md diff --git a/docs/superpowers/specs/2026-05-03-hero-ink-data-morph-design.md b/docs/superpowers/specs/2026-05-03-hero-ink-data-morph-design.md new file mode 100644 index 0000000..fc5fd08 --- /dev/null +++ b/docs/superpowers/specs/2026-05-03-hero-ink-data-morph-design.md @@ -0,0 +1,195 @@ +# Hero 数字水墨动画设计规格 + +> 日期:2026-05-03 +> 状态:待审查 +> 决策者:张翔 + +## 1. 需求与场景 + +### 背景 +当前 Hero 区域(`hero-section-v2.tsx`)使用纯白背景 + 基础 FadeUp 文字动画,视觉表现力不足,缺乏品牌辨识度。 + +### 目标 +为 Hero 区域添加"数字水墨"动画效果,传达"传统智慧 → 数字化转型"的品牌叙事。 + +### 成功标准 +- Hero 入场时有明确的三阶段动画叙事(墨粒扩散 → 沉淀 → 数据化) +- 动画在 60fps 下流畅运行,移动端无卡顿 +- `prefers-reduced-motion` 下优雅降级 +- 动画播放完毕后零持续 CPU 开销 +- 与现有 Hero 文字内容无视觉冲突 + +### 约束 +- 纯入场动画,无鼠标/滚动交互 +- 零新增外部依赖(纯 Canvas 2D API) +- 遵循项目现有特效组件模式(`src/components/effects/`) + +## 2. 技术选型 + +**方案:Canvas 2D 粒子系统** + +| 维度 | 评价 | +|------|------| +| 视觉效果 | 120-200 粒子 + 墨晕 + 连接线,效果完整 | +| 性能 | Canvas 2D 渲染 200 粒子无压力,移动端流畅 | +| 兼容性 | Canvas 2D 全浏览器支持,无 WebGL 依赖 | +| 包体积 | 零依赖,< 5KB gzipped | +| 可维护性 | 状态机驱动三阶段,逻辑清晰 | +| 项目一致性 | 与 DataParticleFlow、SubtleParticles 等现有组件模式一致 | + +排除方案:SVG + CSS 动画(feTurbulence 滤镜移动端不稳定,三阶段叙事难以用 CSS 实现) + +## 3. 组件设计 + +### 3.1 新组件:InkDataMorph + +**文件**:`src/components/effects/ink-data-morph.tsx` + +```tsx +interface InkDataMorphProps { + particleCount?: number; // 默认 150 + primaryColor?: string; // 墨色,默认 '#1C1C1C' + accentColor?: string; // 朱砂红,默认 '#C41E3A' + connectionColor?: string; // 连接线色,默认 '#C41E3A' + connectionDistance?: number; // 连接线触发距离,默认 80px + className?: string; +} +``` + +**渲染**:绝对定位 `` 元素,`pointer-events: none`,`aria-hidden="true"` + +### 3.2 三阶段状态机 + +``` +Phase 1: SPREADING (0s ~ 2s) +├── 墨粒从两个中心点向外扩散 +├── 粒子带有机随机速度 + 方向 +├── 大粒子附带墨晕光晕(径向渐变) +└── 25% 粒子为朱砂红色 + +Phase 2: SETTLING (2s ~ 3.5s) +├── 粒子速度衰减至接近静止 +├── 透明度缓慢降低(模拟墨汁沉淀) +└── 整体画面趋于稳定 + +Phase 3: MORPHING (3.5s ~ 6s) +├── 粒子缓慢移向目标数据点位置 +├── 粒子半径缩小为数据点大小 +├── 相邻粒子间浮现连接线(距离 < connectionDistance) +└── 最终状态:静态数据网络图 + +COMPLETE (6s+) +├── 停止 requestAnimationFrame +└── 零持续 CPU 开销 +``` + +### 3.3 粒子数据结构 + +```ts +interface Particle { + x: number; // 当前 x + y: number; // 当前 y + vx: number; // x 速度 + vy: number; // y 速度 + radius: number; // 当前半径 + initialRadius: number; // 初始半径(墨粒大小) + dataRadius: number; // 数据点目标半径 + opacity: number; // 当前透明度 + isAccent: boolean; // 是否为朱砂红 + phase: 'spreading' | 'settling' | 'morphing' | 'complete'; + spreadTime: number; + maxSpreadTime: number; + settleTime: number; + morphProgress: number; + targetX: number; // 数据点目标 x + targetY: number; // 数据点目标 y +} +``` + +### 3.4 扩散中心点布局 + +``` +┌─────────────────────────────────────────┐ +│ ● 中心1 │ +│ (70%, 35%) │ +│ │ +│ 文字区域 ←── │ +│ │ +│ ● 中心2 │ +│ (25%, 65%) │ +│ │ +└─────────────────────────────────────────┘ +``` + +- 中心1(右上):120 粒子,主墨色 +- 中心2(左下):60 粒子,延迟 500ms 启动 +- Phase 3 数据点目标位置分布在右侧和下方,不遮挡文字 + +### 3.5 性能策略 + +- **2x Canvas 渲染**:`canvas.width = clientWidth * 2`,CSS 缩放,Retina 清晰 +- **连接线优化**:Phase 3 才计算,使用网格空间分区避免 O(n²) +- **一次性动画**:Phase 3 完成后停止 rAF +- **`prefers-reduced-motion`**:跳过动画,直接渲染最终静态数据网络图 + +## 4. Hero Section 集成 + +### 4.1 修改文件 + +`src/components/sections/hero-section-v2.tsx` + +### 4.2 变更点 + +| 项目 | 当前 | 改造后 | +|------|------|--------| +| 背景色 | `bg-white` | `bg-[#FAFAF5]`(宣纸暖白) | +| Canvas 层 | 无 | `` 绝对定位 inset-0 z-0 | +| 内容层 z-index | 默认 | `z-10` | +| 品牌标签 delay | 0.1s | 1.6s | +| 标题 delay | 0.2s | 1.9s | +| 副标题 delay | 0.3s | 2.2s | +| 描述 delay | 0.4s | 2.5s | +| 按钮组 delay | 0.5s | 2.8s | +| IntersectionObserver | 保留 | 保留,只在进入视口时启动 Canvas 动画 | +| useReducedMotion | 保留 | 保留,禁用时 Canvas 直接渲染最终状态 | + +### 4.3 导入方式 + +使用 `dynamic import` + `ssr: false`,与项目现有特效组件加载方式一致: + +```tsx +const InkDataMorph = dynamic( + () => import('@/components/effects/ink-data-morph').then(mod => ({ default: mod.InkDataMorph })), + { ssr: false } +); +``` + +## 5. 测试策略 + +### 5.1 单元测试(ink-data-morph.test.tsx) + +- 组件渲染 canvas 元素 +- 接受自定义 props(particleCount, colors 等) +- `prefers-reduced-motion` 下不启动 rAF +- unmount 时清理 rAF + +### 5.2 集成测试(hero-section-v2.test.tsx 更新) + +- InkDataMorph 在 Hero section 中渲染 +- 文字内容 z-index 在 Canvas 之上 +- 背景色为 `#FAFAF5` + +### 5.3 视觉验证 + +- `npm run dev` 打开首页,观察三阶段动画 +- 移动端视口(375px)验证粒子密度和性能 +- `prefers-reduced-motion` 模拟验证降级效果 + +## 6. 文件清单 + +| 操作 | 文件 | +|------|------| +| 新建 | `src/components/effects/ink-data-morph.tsx` | +| 新建 | `src/components/effects/ink-data-morph.test.tsx` | +| 修改 | `src/components/sections/hero-section-v2.tsx` | +| 修改 | `src/components/effects/index.ts`(导出新组件) |