docs: add Hero ink-data-morph animation design spec
This commit is contained in:
@@ -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;
|
||||
}
|
||||
```
|
||||
|
||||
**渲染**:绝对定位 `<canvas>` 元素,`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 层 | 无 | `<InkDataMorph />` 绝对定位 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`(导出新组件) |
|
||||
Reference in New Issue
Block a user