# P3-02: 白板统一渲染方案
> **状态**: ✅ 已完成 (2026-04-06)
> **优先级**: P3 (非阻塞)
> **依赖**: ClassroomPlayer 重构
## 1. 现状分析
当前存在两套白板渲染实现,职责重叠但能力不等:
| 方面 | SceneRenderer (活跃) | WhiteboardCanvas (闲置) |
|------|---------------------|------------------------|
| **文件** | `SceneRenderer.tsx:82-89, 194-219` | `WhiteboardCanvas.tsx:1-296` |
| **技术** | 内联 SVG in JSX | 独立 SVG 组件 + 网格背景 |
| **支持类型** | `draw_text`, `draw_shape` (2种) | `draw_text`, `draw_shape`, `draw_chart`, `draw_latex` (4种) |
| **图表** | 不支持 | 支持 BarChart + LineChart |
| **LaTeX** | 不支持 | 支持 (黄色高亮代码块) |
| **状态管理** | 内部 useState + useEffect 自动推进 | 纯展示组件,接收 `items` props |
| **使用状态** | ClassroomPlayer 直接引用 | 导出但无父组件使用 |
## 2. 统一方案
### 目标
- 删除 SceneRenderer 中的内联白板 SVG 代码
- 将 WhiteboardCanvas 作为唯一白板渲染器
- SceneRenderer 保留 Agent 头像和场景布局,白板区域委托给 WhiteboardCanvas
### 实施步骤
#### Step 1: 重构 SceneRenderer 白板区域
将 SceneRenderer.tsx 中的内联白板 SVG(lines 82-89, 194-219)替换为:
```tsx
import { WhiteboardCanvas, WhiteboardItem } from './WhiteboardCanvas';
// 在白板区域:
```
#### Step 2: 数据适配
SceneRenderer 的 `processAction()` 产出的 `{ type, data: SceneAction }` 格式与 WhiteboardCanvas 的 `WhiteboardItem` 接口一致(已确认 `WhiteboardItem = { type: string; data: SceneAction }`),无需额外转换。
#### Step 3: 删除 SceneRenderer 内联渲染代码
移除 `renderWhiteboardItem()` 函数(lines 194-219),该函数只处理 text 和 shape 两种类型,且功能已被 WhiteboardCanvas 完全覆盖。
#### Step 4: 验证
- [x] ClassroomPlayer 中白板绘制正常(text/shape)
- [x] Chart 渲染正常(bar/line)
- [x] LaTeX 渲染正常
- [x] 自动推进动作序列正常
- [x] 白板清空 (`whiteboard_clear`) 正常
- [x] TypeScript 类型检查通过
## 3. 影响范围
| 文件 | 变更类型 |
|------|---------|
| `desktop/src/components/classroom_player/SceneRenderer.tsx` | 修改:删除内联白板,引入 WhiteboardCanvas |
| `desktop/src/components/classroom_player/WhiteboardCanvas.tsx` | 无变更(已完整) |
| `desktop/src/components/classroom_player/ClassroomPlayer.tsx` | 无变更(通过 SceneRenderer 间接使用) |
## 4. 风险评估
- **低风险**: WhiteboardCanvas 是纯展示组件,数据接口已对齐
- **潜在问题**: WhiteboardCanvas 未在生产环境验证过 chart/latex 渲染效果
- **缓解**: 统一后在 classroom 生成时验证所有 4 种动作类型
## 5. 后续优化(可选)
- 白板导出功能(SVG → PNG/PDF)可直接基于 WhiteboardCanvas 的 SVG 输出
- 添加画笔/批注交互能力
- 支持动画效果(逐步绘制)