渲染管线与扩展讨论 (renderCanvas)
概述
renderCanvas() 是整个排版系统的渲染入口,协调文本测量、算法执行和 Canvas 绑制。其设计遵循测量-计算-绑制三阶段模式,并特别关注高清屏幕适配。
完整渲染流程
flowchart TD
subgraph 初始化
A[document.fonts.ready] --> B[获取容器宽度]
B --> C[计算列宽<br/>colWidth = min容器 1024]
C --> D[计算内部宽度<br/>innerWidth = colWidth - PAD×2]
end
subgraph 文本测量
D --> E[创建临时Canvas<br/>测量字体]
E --> F[测量 NORMAL_SPACE_W<br/>空格宽度]
F --> G[测量 HYPHEN_WIDTH<br/>连字符宽度]
end
subgraph 文本预处理
G --> H[遍历每个段落PARAGRAPHS]
H --> I[split tokens<br/>保留空格]
I --> J[hyphenateWord<br/>断词处理]
J --> K[join软连字符]
K --> L[prepareWithSegments<br/>生成segments+widths]
H --> L
end
subgraph 算法求解
L --> M[optimalLayout<br/>计算最优断点]
M --> N[allLines<br/>所有段落行布局]
end
subgraph Canvas绘制
N --> O[setupCanvas<br/>高清适配]
O --> P[fillRect白底]
P --> Q[clip裁剪区域]
Q --> R{遍历每行}
R -->|非最后行<br/>且≥60%宽| S[两端对齐]
R -->|其他| T[左对齐]
S --> U[计算间距js]
T --> V[逐字绘制]
U --> V
V --> R
R -->|完成| W[ctx.restore<br/>恢复状态]
end
style H fill:#e3f2fd
style M fill:#fff3e0
style S fill:#c8e6c9
style W fill:#e8f5e9
代码逐段解析
阶段一:字体加载与宽度计算
为什么等待 document.fonts.ready?
Canvas 文本测量依赖字体加载完成,否则测量结果可能不准确(回退字体)。
阶段二:文本测量
为什么用独立Canvas测量?
临时创建一个离屏Canvas,不影响主Canvas状态。
阶段三:文本预处理流水线
预处理流程图:
flowchart LR
A["The relationship..."] --> B["The", " ", "relationship", "..."]
B --> C{每个token}
C -->|空格| D[保留原样]
C -->|单词| E[hyphenateWord]
E -->|拆分| F["re", "la", "tion", "ship"]
F --> G[join ""]
G --> H["relationship"]
H --> I[prepareWithSegments]
I --> J[segments + widths]
阶段四:算法求解
返回值结构:
阶段五:Canvas 高清适配
高清适配原理:
flowchart TD
subgraph 普通屏幕 DPR=1
A[逻辑尺寸 400×300] --> B[物理尺寸 400×300]
A --> C[1像素=1像素]
end
subgraph Retina DPR=2
D[逻辑尺寸 400×300] --> E[物理尺寸 800×600]
D --> F[1像素=4像素<br/>更细腻]
end
style E fill:#fff3e0
阶段六:两行对齐绘制
两行对齐图解:
flowchart LR
subgraph 原始状态
A[The] --> B[ ] --> C[relationship]
A1[_____60%宽度_____]
end
subgraph 对齐后
D[The] --> E[ ] --> F[relationship]
D1[___________100%宽度___________]
end
E -.->|js更宽| G[间距扩大]
A --> D[间距从4px变为约12px]
生命周期管理
为什么要监听 resize?
容器宽度可能因侧边栏折叠、窗口缩放等改变,需要重新计算布局。
扩展讨论:逻辑复用与延伸
1. 提取独立排版引擎
当前逻辑可以封装为通用库:
2. 支持 RTL 语言
扩展方向:
3. 导出为 PDF/SVG
4. 响应式排版策略
5. 与 React 组件集成
6. 性能优化:Web Worker
将计算密集型算法移至 Worker:
设计亮点总结
| 特性 | 实现方式 | 价值 |
|---|---|---|
| 三阶段分离 | 测量→算法→渲染 | 职责清晰,易测试 |
| useCallback 稳定渲染 | 避免不必要重绘 | 性能优化 |
| Resize 节流 | 每次resize都重算 | 布局始终正确 |
| 高清适配 | devicePixelRatio | Retina清晰 |
| 两行对齐算法 | 等比拉伸间距 | 专业排版效果 |