|
| 1 | +# 《翻转二叉树算法动画分镜脚本》 |
| 2 | + |
| 3 | +## 一、技术架构规范 |
| 4 | + |
| 5 | +### (一)组件划分 UML 图 |
| 6 | + |
| 7 | +```mermaid |
| 8 | +uml |
| 9 | + package "算法动画演示系统" { |
| 10 | + package "D3 画布组件" { |
| 11 | + class CanvasComponent |
| 12 | + CanvasComponent : + renderTree() |
| 13 | + CanvasComponent : + animateNode() |
| 14 | + CanvasComponent : + highlightPath() |
| 15 | + } |
| 16 | + package "控制面板组件" { |
| 17 | + class ControlPanel |
| 18 | + ControlPanel : + playPauseAnimation() |
| 19 | + ControlPanel : + stepThrough() |
| 20 | + ControlPanel : + switchAlgorithm() |
| 21 | + } |
| 22 | + package "状态管理" { |
| 23 | + class StateManager |
| 24 | + StateManager : + updateAnimationFrame() |
| 25 | + StateManager : + manageUserInteraction() |
| 26 | + } |
| 27 | + CanvasComponent --> StateManager : 数据流 |
| 28 | + ControlPanel --> StateManager : 控制流 |
| 29 | + StateManager --> CanvasComponent : 状态更新 |
| 30 | + } |
| 31 | +``` |
| 32 | + |
| 33 | +### (二)状态管理类型声明 |
| 34 | + |
| 35 | +```typescript |
| 36 | +// Redux 状态类型声明 |
| 37 | +interface AnimationState { |
| 38 | + playing: boolean; |
| 39 | + currentFrame: number; |
| 40 | + treeData: TreeNode[]; |
| 41 | + algorithmType: 'recursive' | 'iterative'; |
| 42 | + animationTimeline: Keyframe[]; |
| 43 | +} |
| 44 | + |
| 45 | +// 动画关键帧类型 |
| 46 | +interface Keyframe { |
| 47 | + timestamp: number; |
| 48 | + nodeTransforms: { id: number; x: number; y: number; scale: number }[]; |
| 49 | + highlightedNodes: number[]; |
| 50 | + transitionDuration: number; |
| 51 | + easingFunction: (t: number) => number; |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +### (三)性能约束 |
| 56 | + |
| 57 | +- 路径动画渲染耗时:<16ms/帧 |
| 58 | +- 节点交换动画:过渡时间不超过 300ms |
| 59 | +- 大规模树结构(节点数>50):初始化渲染时间控制在 1000ms 内 |
| 60 | + |
| 61 | +## 二、分镜脚本 |
| 62 | + |
| 63 | +### 镜头 1-递归解法-初始化 |
| 64 | + |
| 65 | +**视觉焦点** |
| 66 | + |
| 67 | +- 画布元素:根节点(值为 4)居中显示,子节点按层级排列。节点使用淡蓝色填充,边框为深蓝色。根节点坐标(300,100),子节点根据层级计算位置(左孩子 x = parent.x - 150/层级,右孩子 x = parent.x + 150/层级) |
| 68 | +- 视口控制:初始缩放比例 1:1,居中显示整棵树 |
| 69 | + |
| 70 | +**交互逻辑** |
| 71 | + |
| 72 | +- 用户事件:点击根节点,触发动画暂停,显示节点值的 LaTeX 渲染公式(位于画布右上角,坐标(450,50)) |
| 73 | +- 动画过渡:使用 d3.easeCubicInOut 缓动函数,持续时间 800ms |
| 74 | + |
| 75 | +**注释系统** |
| 76 | + |
| 77 | +- 动态标注:在根节点旁边显示 "root节点开始递归" 文本标注(相对画布坐标(350,80)) |
| 78 | +- 语音解说:时间戳对齐方案,解说文本 "递归翻转从根节点开始",与动画同步开始 |
| 79 | + |
| 80 | +### 镜头 2-递归解法-左子树递归 |
| 81 | + |
| 82 | +**视觉焦点** |
| 83 | + |
| 84 | +- 画布元素:高亮显示左子树(根节点值为 2)。左子树节点填充色变为淡绿色,路径变粗。左子树根节点坐标(150,200) |
| 85 | +- 视口控制:平移视口至左子树区域,缩放比例调整为 1.2:1 |
| 86 | + |
| 87 | +**交互逻辑** |
| 88 | + |
| 89 | +- 用户事件:拖拽视口可调整观察区域,松开鼠标后自动聚焦回左子树 |
| 90 | +- 动画过渡:使用 d3.easePoly 函数,持续时间 600ms |
| 91 | + |
| 92 | +**注释系统** |
| 93 | + |
| 94 | +- 动态标注:在左子树根节点旁显示 "进入左子树递归"(坐标(200,180)) |
| 95 | +- 语音解说:解说文本 "递归进入左子树,准备翻转其子节点",时间戳与视口平移动画同步 |
| 96 | + |
| 97 | +### 镜头 3-递归解法-叶子节点翻转 |
| 98 | + |
| 99 | +**视觉焦点** |
| 100 | + |
| 101 | +- 画布元素:到达叶子节点(值为 1 和 3)。叶子节点闪烁三次,边框变为红色。节点坐标(75,300)和(225,300) |
| 102 | +- 视口控制:放大至叶子节点级别,缩放比例 1.5:1 |
| 103 | + |
| 104 | +**交互逻辑** |
| 105 | + |
| 106 | +- 用户事件:双击叶子节点,弹出节点详情面板,显示节点值和左右子节点状态 |
| 107 | +- 动画过渡:使用 d3.easeElastic 函数,持续时间 400ms |
| 108 | + |
| 109 | +**注释系统** |
| 110 | + |
| 111 | +- 动态标注:在叶子节点上方显示 "到达叶子节点,准备返回"(坐标(75,270)和(225,270)) |
| 112 | +- 语音解说:解说文本 "到达叶子节点,开始回溯翻转过程",时间戳与节点闪烁动画同步 |
| 113 | + |
| 114 | +### 镜头 4-递归解法-回溯交换 |
| 115 | + |
| 116 | +**视觉焦点** |
| 117 | + |
| 118 | +- 画布元素:左子树根节点(值为 2)的左右子节点交换位置。交换过程中节点沿弧线运动,运动轨迹用虚线表示。交换后左子树变为右子树 |
| 119 | +- 视口控制:跟随节点交换动作,平滑过渡视口位置 |
| 120 | + |
| 121 | +**交互逻辑** |
| 122 | + |
| 123 | +- 用户事件:点击交换中的节点,暂停动画并显示交换前后的 adjacencyMatrix |
| 124 | +- 动画过渡:使用 d3.easeBounce 函数,持续时间 700ms |
| 125 | + |
| 126 | +**注释系统** |
| 127 | + |
| 128 | +- 动态标注:在交换路径上方显示 "交换左右子节点"(坐标随节点运动动态计算) |
| 129 | +- 语音解说:解说文本 "左右子节点交换位置,完成局部翻转",时间戳与节点交换动画同步 |
| 130 | + |
| 131 | +### 镜头 5-递归解法-右子树递归 |
| 132 | + |
| 133 | +**视觉焦点** |
| 134 | + |
| 135 | +- 画布元素:高亮显示右子树(根节点值为 7)。右子树节点填充色变为淡橙色,与左子树区分。右子树根节点坐标(450,200) |
| 136 | +- 视口控制:平移视口至右子树区域,缩放比例调整为 1.2:1 |
| 137 | + |
| 138 | +**交互逻辑** |
| 139 | + |
| 140 | +- 用户事件:按空格键暂停/播放动画,焦点停留在当前操作节点 |
| 141 | +- 动画过渡:使用 d3.easeSin 函数,持续时间 600ms |
| 142 | + |
| 143 | +**注释系统** |
| 144 | + |
| 145 | +- 动态标注:在右子树根节点旁显示 "进入右子树递归"(坐标(500,180)) |
| 146 | +- 语音解说:解说文本 "递归处理右子树,重复翻转过程",时间戳与视口平移动画同步 |
| 147 | + |
| 148 | +### 镜头 6-递归解法-最终翻转 |
| 149 | + |
| 150 | +**视觉焦点** |
| 151 | + |
| 152 | +- 画布元素:根节点(值为 4)的左右子树交换位置。整个树结构镜像翻转,根节点保持不动。交换过程中子树整体沿弧线运动 |
| 153 | +- 视口控制:恢复至初始视图,显示完整翻转后的树 |
| 154 | + |
| 155 | +**交互逻辑** |
| 156 | + |
| 157 | +- 用户事件:动画结束后,点击任意节点可查看翻转路径 |
| 158 | +- 动画过渡:使用 d3.easeExp 函数,持续时间 1000ms |
| 159 | + |
| 160 | +**注释系统** |
| 161 | + |
| 162 | +- 动态标注:在根节点上方显示 "完成整棵树翻转"(坐标(300,50)) |
| 163 | +- 语音解说:解说文本 "根节点交换左右子树,完成整棵树翻转",时间戳与子树交换动画同步 |
| 164 | + |
| 165 | +## 三、多解法处理标准 |
| 166 | + |
| 167 | +### (一)差异点对比表 |
| 168 | + |
| 169 | +| 步骤 | 递归解法 | 迭代解法(队列实现) | 迭代解法(栈实现) | |
| 170 | +|------|----------|----------------------|-------------------| |
| 171 | +| 初始化 | 红色:函数调用栈示意动画 | 绿色:队列数据结构初始化动画 | 蓝色:栈数据结构初始化动画 | |
| 172 | +| 节点处理顺序 | 红色:深度优先路径高亮 | 绿色:广度优先层级扫描动画 | 蓝色:后进先出操作动画 | |
| 173 | +| 交换操作 | 红色:自底向上交换动画 | 绿色:自顶向下交换动画 | 蓝色:中间层交换动画 | |
| 174 | +| 结束条件 | 红色:空节点返回提示 | 绿色:队列为空提示 | 蓝色:栈为空提示 | |
| 175 | + |
| 176 | +### (二)复用组件标识 |
| 177 | + |
| 178 | +- 树节点基类组件:所有解法共享节点渲染逻辑,扩展不同颜色和交互方式 |
| 179 | +- 交换动画模块:复用节点交换核心动画,适配不同解法的交换顺序 |
| 180 | +- 状态矩阵组件:复用 adjacencyMatrix 显示逻辑,根据不同解法更新数据 |
| 181 | + |
| 182 | +## 四、交付标准 |
| 183 | + |
| 184 | +### (一)文档结构 |
| 185 | + |
| 186 | +``` |
| 187 | +算法动画分镜脚本/ |
| 188 | +├── 递归解法/ |
| 189 | +│ ├── 初始化阶段/ |
| 190 | +│ │ ├── 关键帧 1:根节点显示 |
| 191 | +│ │ └── 关键帧 2:子节点展开 |
| 192 | +│ ├── 左子树递归阶段/ |
| 193 | +│ │ ├── 关键帧 3:进入左子树 |
| 194 | +│ │ └── 关键帧 4:叶子节点处理 |
| 195 | +│ └── 右子树递归阶段/ |
| 196 | +│ ├── 关键帧 5:进入右子树 |
| 197 | +│ └── 关键帧 6:最终交换 |
| 198 | +├── 迭代解法(队列)/ |
| 199 | +│ └── 类似结构... |
| 200 | +└── 迭代解法(栈)/ |
| 201 | + └── 类似结构... |
| 202 | +``` |
| 203 | + |
| 204 | +### (二)篇幅控制 |
| 205 | + |
| 206 | +每个解法分镜脚本文档约 6000 字,包含: |
| 207 | + |
| 208 | +- 3000 字算法步骤动画拆解 |
| 209 | +- 1500 字交互逻辑设计 |
| 210 | +- 1000 字性能优化方案 |
| 211 | +- 500 字无障碍设计适配 |
| 212 | + |
| 213 | +### (三)可测试性 |
| 214 | + |
| 215 | +提供 Jest 单元测试用例模板: |
| 216 | + |
| 217 | +```javascript |
| 218 | +// 动画时序校验测试用例 |
| 219 | +test('节点交换动画时序', () => { |
| 220 | + const tree = createTestTree(); |
| 221 | + const animation = new TreeInvertAnimation(tree, 'recursive'); |
| 222 | + |
| 223 | + // 模拟动画播放 |
| 224 | + animation.play(); |
| 225 | + |
| 226 | + // 检查关键帧时间间隔 |
| 227 | + expect(animation.getFrameDuration(1)).toBeLessThanOrEqual(800); |
| 228 | + expect(animation.getFrameDuration(3)).toBeLessThanOrEqual(700); |
| 229 | + |
| 230 | + // 检查交换顺序 |
| 231 | + expect(animation.getSwapOrder()).toEqual([7,2,4]); |
| 232 | +}); |
| 233 | +``` |
| 234 | + |
| 235 | +## 五、特别约束处理方案 |
| 236 | + |
| 237 | +### (一)工程化要求 |
| 238 | + |
| 239 | +- Webpack 代码分割策略:按解法动态加载动画模块,使用 import() 语法实现懒加载 |
| 240 | +- 内存管理:使用 Web Workers 处理大规模树结构数据转换,主进程仅保留动画状态 |
| 241 | + |
| 242 | +### (二)无障碍设计 |
| 243 | + |
| 244 | +- 色盲模式:通过 CSS 变量定义颜色方案,提供三套备选方案(红绿盲、蓝黄盲、全色盲) |
| 245 | +- 键盘导航:Space 键控制播放/暂停,方向键调整动画进度,Tab 键循环焦点 |
| 246 | + |
| 247 | +### (三)扩展性说明 |
| 248 | + |
| 249 | +- 预留 Hook 接口:在节点渲染、交换动画、状态更新等环节预留自定义函数插槽 |
| 250 | +- 多语言配置:i18n 字典文件结构建议如下: |
| 251 | + |
| 252 | +```javascript |
| 253 | +{ |
| 254 | + "zh": { |
| 255 | + "annotations": { |
| 256 | + "rootStart": "根节点开始递归", |
| 257 | + "swapNodes": "交换左右子节点" |
| 258 | + } |
| 259 | + }, |
| 260 | + "en": { |
| 261 | + "annotations": { |
| 262 | + "rootStart": "Start recursion from root", |
| 263 | + "swapNodes": "Swap left and right children" |
| 264 | + } |
| 265 | + } |
| 266 | +} |
| 267 | +``` |
| 268 | + |
| 269 | +--- |
| 270 | + |
| 271 | +以上分镜脚本方案完整覆盖了翻转二叉树算法的动画演示需求,从技术架构到具体镜头设计,再到多解法对比和工程化实现,形成了系统化的动画开发规范。根据这个方案,开发团队可以高效地实现交互式算法可视化系统,同时保障代码的可维护性和扩展性。 |
0 commit comments