Skip to content

Commit 2e45552

Browse files
committed
feat: 添加 GitHub 仓库链接徽标到页面右上角
1 parent 583d4a9 commit 2e45552

27 files changed

+2735
-332
lines changed
Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
# Design Document: Animation-Driven Visualization
2+
3+
## Overview
4+
5+
本设计将【算法执行状态】面板(AlgorithmGuide)删除,将其功能通过动画和浮动标注的形式整合到递归树画布中。核心设计理念是**动画即叙事**——通过精心编排的视觉动效来传达算法执行过程,而非依赖文字说明。
6+
7+
### 设计目标
8+
9+
1. **沉浸式体验**:用户通过观看动画理解算法,无需阅读大段文字
10+
2. **视觉层次清晰**:通过颜色、动画、大小区分不同状态的节点和边
11+
3. **上下文感知**:在关键时刻显示简短的浮动提示,自动消失
12+
4. **流畅过渡**:所有状态变化都有平滑的动画过渡
13+
14+
## Architecture
15+
16+
```
17+
┌─────────────────────────────────────────────────────────────┐
18+
│ App.tsx │
19+
│ ┌─────────────┐ ┌──────────────────────────────────────┐ │
20+
│ │ LeftPanel │ │ CenterPanel │ │
21+
│ │ │ │ ┌────────────────────────────────┐ │ │
22+
│ │ - Input │ │ │ TreeVisualization │ │ │
23+
│ │ - Control │ │ │ ┌──────────────────────────┐ │ │ │
24+
│ │ - Keypad │ │ │ │ SVG Canvas │ │ │ │
25+
│ │ - Path │ │ │ │ - Animated Nodes │ │ │ │
26+
│ │ - Results │ │ │ │ - Animated Edges │ │ │ │
27+
│ │ │ │ │ │ - Floating Annotations │ │ │ │
28+
│ │ │ │ │ │ - Path Highlight │ │ │ │
29+
│ │ │ │ │ └──────────────────────────┘ │ │ │
30+
│ │ │ │ │ ┌──────────────────────────┐ │ │ │
31+
│ │ │ │ │ │ Compact Legend │ │ │ │
32+
│ │ │ │ │ └──────────────────────────┘ │ │ │
33+
│ │ │ │ └────────────────────────────────┘ │ │
34+
│ └─────────────┘ └──────────────────────────────────────┘ │
35+
└─────────────────────────────────────────────────────────────┘
36+
```
37+
38+
## Components and Interfaces
39+
40+
### 1. TreeVisualization (Enhanced)
41+
42+
增强后的树可视化组件,整合所有动画和标注功能。
43+
44+
```typescript
45+
interface TreeVisualizationProps {
46+
treeData: TreeNode | null;
47+
currentNodeId: string | null;
48+
highlightedPath: string | null;
49+
currentStep: AnimationStep | null; // 新增:当前步骤信息
50+
previousStep: AnimationStep | null; // 新增:上一步骤(用于检测变化)
51+
playbackSpeed: number; // 新增:播放速度(影响动画时长)
52+
}
53+
```
54+
55+
### 2. AnimationConfig
56+
57+
动画配置接口,用于统一管理动画参数。
58+
59+
```typescript
60+
interface AnimationConfig {
61+
baseDuration: number; // 基础动画时长 (ms)
62+
nodeEnterDuration: number; // 节点进入动画时长
63+
nodeExitDuration: number; // 节点退出动画时长
64+
edgeFlowDuration: number; // 边流动动画时长
65+
annotationDuration: number; // 标注显示时长
66+
annotationFadeOut: number; // 标注淡出时长
67+
easing: string; // 缓动函数
68+
}
69+
70+
// 根据播放速度计算实际动画时长
71+
function getScaledDuration(baseDuration: number, speed: number): number {
72+
return baseDuration / speed;
73+
}
74+
```
75+
76+
### 3. FloatingAnnotation
77+
78+
浮动标注数据结构。
79+
80+
```typescript
81+
interface FloatingAnnotation {
82+
id: string;
83+
type: 'digit' | 'letter' | 'combination' | 'backtrack';
84+
content: string;
85+
position: { x: number; y: number };
86+
nodeId: string;
87+
createdAt: number;
88+
}
89+
```
90+
91+
## Data Models
92+
93+
### 动画状态映射
94+
95+
| StepType | 节点动画 | 边动画 | 浮动标注 |
96+
|----------|---------|--------|---------|
97+
| INIT | - | - | - |
98+
| ENTER_RECURSION | 脉冲激活 | - | 显示数字 "处理: {digit}" |
99+
| SELECT_LETTER | 新节点缩放进入 | 向下流动 | 显示字母 "+{letter}" |
100+
| ADD_TO_PATH | 路径高亮延伸 | 路径边发光 | - |
101+
| FOUND_COMBINATION | 成功标记 ✓ | 路径变绿 | 🎉 "{combination}" |
102+
| BACKTRACK | 淡出变灰 | 向上流动 ||
103+
| EXIT_RECURSION | - | - | - |
104+
| COMPLETE | - | - | 🎊 "完成!" |
105+
106+
### 节点视觉状态
107+
108+
```typescript
109+
type NodeVisualState = 'default' | 'active' | 'completed' | 'backtracked' | 'highlighted';
110+
111+
const NODE_STYLES: Record<NodeVisualState, NodeStyle> = {
112+
default: {
113+
fill: '#ffffff',
114+
stroke: '#4a90d9',
115+
strokeWidth: 2,
116+
scale: 1,
117+
opacity: 1,
118+
},
119+
active: {
120+
fill: '#4a90d9',
121+
stroke: '#2c5282',
122+
strokeWidth: 3,
123+
scale: 1.1,
124+
opacity: 1,
125+
glow: true,
126+
pulse: true,
127+
},
128+
completed: {
129+
fill: '#27ae60',
130+
stroke: '#1e8449',
131+
strokeWidth: 2,
132+
scale: 1,
133+
opacity: 1,
134+
checkmark: true,
135+
},
136+
backtracked: {
137+
fill: '#bdc3c7',
138+
stroke: '#95a5a6',
139+
strokeWidth: 2,
140+
scale: 0.9,
141+
opacity: 0.7,
142+
},
143+
highlighted: {
144+
fill: '#ffc107',
145+
stroke: '#e0a800',
146+
strokeWidth: 3,
147+
scale: 1.15,
148+
opacity: 1,
149+
},
150+
};
151+
```
152+
153+
### 边视觉状态
154+
155+
```typescript
156+
type EdgeVisualState = 'default' | 'active' | 'completed' | 'backtracked' | 'highlighted';
157+
158+
const EDGE_STYLES: Record<EdgeVisualState, EdgeStyle> = {
159+
default: {
160+
stroke: '#95a5a6',
161+
strokeWidth: 2,
162+
dashArray: 'none',
163+
animation: 'none',
164+
},
165+
active: {
166+
stroke: '#4a90d9',
167+
strokeWidth: 3,
168+
dashArray: '8,4',
169+
animation: 'flow-down', // 向下流动的虚线动画
170+
},
171+
completed: {
172+
stroke: '#27ae60',
173+
strokeWidth: 3,
174+
dashArray: 'none',
175+
animation: 'glow-pulse', // 短暂发光
176+
},
177+
backtracked: {
178+
stroke: '#bdc3c7',
179+
strokeWidth: 2,
180+
dashArray: '4,4',
181+
animation: 'flow-up', // 向上流动的虚线动画
182+
},
183+
highlighted: {
184+
stroke: '#ffc107',
185+
strokeWidth: 4,
186+
dashArray: 'none',
187+
animation: 'none',
188+
},
189+
};
190+
```
191+
192+
## Correctness Properties
193+
194+
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
195+
196+
### Property 1: Node Visual State Mapping
197+
198+
*For any* tree node with a given status (isActive, isCompleted, isBacktracked), the rendered node SHALL have the corresponding visual attributes (fill color, stroke, scale, opacity) as defined in NODE_STYLES.
199+
200+
**Validates: Requirements 2.1, 2.2, 2.3, 2.4**
201+
202+
### Property 2: Edge Visual State Mapping
203+
204+
*For any* edge connecting two nodes, the edge SHALL have visual attributes corresponding to the target node's state (active → flow-down animation, backtracked → flow-up animation, completed → green with glow).
205+
206+
**Validates: Requirements 3.1, 3.2, 3.3**
207+
208+
### Property 3: Annotation Content Mapping
209+
210+
*For any* animation step with a given StepType, IF an annotation should be displayed (ENTER_RECURSION, SELECT_LETTER, FOUND_COMBINATION, BACKTRACK), THEN the annotation content SHALL match the expected format for that step type.
211+
212+
**Validates: Requirements 4.1, 4.2, 4.3, 4.4**
213+
214+
### Property 4: Path Highlight Consistency
215+
216+
*For any* current path from root to active node, all nodes and edges along that path SHALL have the highlighted visual state applied.
217+
218+
**Validates: Requirements 5.1, 5.2, 5.3**
219+
220+
### Property 5: Animation Duration Scaling
221+
222+
*For any* playback speed value, the actual animation duration SHALL equal the base duration divided by the speed factor.
223+
224+
**Validates: Requirements 6.3**
225+
226+
## Animation Storyboard (动画分镜设计)
227+
228+
### 场景 1: 进入递归 (ENTER_RECURSION)
229+
230+
```
231+
时间轴: 0ms ──────────────────────────────────────── 600ms
232+
│ │
233+
├─ 0-200ms: 当前节点脉冲放大 (scale 1→1.1)
234+
│ 发光效果渐显
235+
236+
├─ 100-400ms: 浮动标注淡入
237+
│ 内容: "处理: {digit}"
238+
│ 位置: 节点上方
239+
240+
└─ 400-600ms: 标注保持显示
241+
```
242+
243+
### 场景 2: 选择字母 (SELECT_LETTER)
244+
245+
```
246+
时间轴: 0ms ──────────────────────────────────────── 800ms
247+
│ │
248+
├─ 0-300ms: 新节点从父节点位置
249+
│ 缩放淡入 (scale 0→1, opacity 0→1)
250+
251+
├─ 0-400ms: 连接边绘制动画
252+
│ 从父节点向子节点延伸
253+
│ 虚线向下流动效果
254+
255+
├─ 200-500ms: 字母标注淡入
256+
│ 内容: "+{letter}"
257+
│ 位置: 新节点上方
258+
259+
└─ 300-800ms: 父节点脉冲减弱
260+
新节点成为活动节点
261+
```
262+
263+
### 场景 3: 找到组合 (FOUND_COMBINATION)
264+
265+
```
266+
时间轴: 0ms ──────────────────────────────────────── 1200ms
267+
│ │
268+
├─ 0-200ms: 当前节点放大 (scale 1→1.2)
269+
270+
├─ 100-400ms: 路径上所有边变绿
271+
│ 短暂发光效果
272+
273+
├─ 200-500ms: 节点内显示 ✓ 图标
274+
275+
├─ 300-800ms: 庆祝标注淡入
276+
│ 内容: "🎉 {combination}"
277+
│ 位置: 节点上方,稍大字体
278+
279+
└─ 800-1200ms: 标注淡出
280+
节点恢复正常大小
281+
```
282+
283+
### 场景 4: 回溯 (BACKTRACK)
284+
285+
```
286+
时间轴: 0ms ──────────────────────────────────────── 600ms
287+
│ │
288+
├─ 0-150ms: 回溯图标淡入
289+
│ 内容: "↩"
290+
│ 位置: 当前节点旁
291+
292+
├─ 100-400ms: 当前节点淡出变灰
293+
│ (opacity 1→0.7, scale 1→0.9)
294+
295+
├─ 150-450ms: 连接边向上流动动画
296+
│ 颜色变为灰色
297+
298+
└─ 300-600ms: 父节点重新激活
299+
脉冲效果
300+
```
301+
302+
### 场景 5: 算法完成 (COMPLETE)
303+
304+
```
305+
时间轴: 0ms ──────────────────────────────────────── 1500ms
306+
│ │
307+
├─ 0-500ms: 所有完成路径依次高亮
308+
│ 波浪式发光效果
309+
310+
├─ 500-1000ms: 中央显示完成标注
311+
│ 内容: "🎊 算法完成!"
312+
│ 带有缩放弹跳效果
313+
314+
└─ 1000-1500ms: 标注淡出
315+
树恢复静态显示
316+
```
317+
318+
## Error Handling
319+
320+
1. **空树状态**: 当 treeData 为 null 时,显示占位提示 "输入数字后开始演示"
321+
2. **动画中断**: 当用户快速切换步骤时,取消进行中的动画,立即跳转到目标状态
322+
3. **性能保护**: 当节点数量超过 100 时,简化动画效果(禁用粒子效果、减少发光)
323+
4. **标注堆叠**: 当多个标注同时显示时,自动调整位置避免重叠
324+
325+
## Testing Strategy
326+
327+
### Unit Tests
328+
329+
1. **getNodeVisualState**: 测试节点状态到视觉状态的映射
330+
2. **getEdgeVisualState**: 测试边状态到视觉状态的映射
331+
3. **getAnnotationContent**: 测试步骤类型到标注内容的映射
332+
4. **getScaledDuration**: 测试动画时长缩放计算
333+
334+
### Property-Based Tests
335+
336+
使用 fast-check 库进行属性测试:
337+
338+
1. **Property 1 测试**: 生成随机节点状态组合,验证视觉属性映射正确
339+
2. **Property 2 测试**: 生成随机边状态,验证边样式映射正确
340+
3. **Property 3 测试**: 生成随机步骤类型,验证标注内容格式正确
341+
4. **Property 4 测试**: 生成随机路径,验证路径高亮一致性
342+
5. **Property 5 测试**: 生成随机播放速度,验证动画时长缩放正确
343+
344+
### Integration Tests
345+
346+
1. 验证 AlgorithmGuide 组件已从 App.tsx 中移除
347+
2. 验证 TreeVisualization 组件正确接收新的 props
348+
3. 验证动画在不同播放速度下正常工作
349+

0 commit comments

Comments
 (0)