
阅读时长:约 18 分钟 | 难度:★★★★☆ | 篇章:第 4 篇 · 二十八星宿模块
对应源码:
entry/src/main/ets/pages/mansion/MansionListPage.ets、MansionDetailPage.ets

前言
玄象项目星宿相关页面大量使用 Canvas 路径绘制------星宿列表页的四象圆盘、详情页的星宿连线、星野分野页的古地图星线,都通过 moveTo / lineTo / stroke 三步法实现。本篇将深入剖析玄象项目 Canvas 路径绘制的核心技巧:从 moveTo 移动画笔、lineTo 绘制线段、stroke 描边输出,到 closePath 封闭路径、lineWidth 线宽控制、strokeStyle 颜色设置。掌握这套 Canvas 路径绘制方法论,您就能为任何 HarmonyOS 应用绘制复杂的几何图形。
提示:Canvas 路径绘制是 ArkUI 中最常用的图形绘制方式。玄象项目从星宿连线到罗盘刻度,都依赖路径绘制 API。
一、路径绘制三步法
1.1 核心 API
typescript
// 1. 开始新路径
canvas.beginPath();
// 2. 移动画笔到起点
canvas.moveTo(x, y);
// 3. 绘制线段到目标点
canvas.lineTo(x, y);
// 4. 描边输出
canvas.stroke();
1.2 玄象项目星宿连线示例
typescript
canvas.strokeStyle = Colors.PRIMARY_GOLD;
canvas.lineWidth = 1.5;
canvas.beginPath();
canvas.moveTo(points[0][0], points[0][1]);
for (let i = 1; i < points.length; i++) {
canvas.lineTo(points[i][0], points[i][1]);
}
canvas.stroke();
二、重点 API 详解
2.1 beginPath
beginPath() 开始新路径,重置当前路径列表。
2.2 moveTo
moveTo(x, y) 将画笔移动到指定坐标,不画线。
2.3 lineTo
lineTo(x, y) 从当前画笔位置画线到指定坐标。
2.4 stroke
stroke() 使用当前 strokeStyle 描边路径。
三、路径绘制参数
3.1 strokeStyle
typescript
canvas.strokeStyle = Colors.PRIMARY_GOLD; // 金色
canvas.strokeStyle = 'rgba(212, 168, 67, 0.3)'; // 半透明金
3.2 lineWidth
typescript
canvas.lineWidth = 1.5; // 星宿连线
canvas.lineWidth = 0.5; // 网格线(极细)
canvas.lineWidth = 2; // 外圈(较粗)
3.3 lineCap
typescript
canvas.lineCap = 'round'; // 圆头端点
canvas.lineCap = 'butt'; // 平头端点(默认)
四、星宿列表页圆盘路径绘制
4.1 四象分区扇区
typescript
for (let i = 0; i < 4; i++) {
const startAngle = (i * 90 - 90) * Math.PI / 180;
const endAngle = ((i + 1) * 90 - 90) * Math.PI / 180;
canvas.fillStyle = siXiangColors[i] + '22';
canvas.beginPath();
canvas.moveTo(cx, cy);
canvas.arc(cx, cy, outerR, startAngle, endAngle);
canvas.closePath();
canvas.fill();
}
五、路径绘制最佳实践
5.1 状态隔离
typescript
// 错误的:状态污染
canvas.strokeStyle = 'gold';
canvas.moveTo(0, 0);
canvas.lineTo(100, 100);
canvas.stroke(); // 正确
canvas.lineTo(200, 200);
canvas.stroke(); // 错误:路径累积
// 正确的:每个路径独立
canvas.beginPath();
canvas.moveTo(0, 0);
canvas.lineTo(100, 100);
canvas.stroke();
canvas.beginPath();
canvas.moveTo(100, 100);
canvas.lineTo(200, 200);
canvas.stroke();
5.2 性能优化
typescript
// 批量绘制:一次 beginPath + 多次 lineTo + 一次 stroke
canvas.beginPath();
canvas.moveTo(points[0][0], points[0][1]);
for (let i = 1; i < points.length; i++) {
canvas.lineTo(points[i][0], points[i][1]);
}
canvas.stroke(); // 一次性描边,性能更优
六、玄象项目路径绘制应用
6.1 应用场景
| 页面 | 路径用途 | 绘制数量 |
|---|---|---|
| 启动页 | 银河渐变、星宿连线 | 6 条折线 |
| 星宿列表 | 四象圆盘、星宿点 | 28 个星点 |
| 星宿详情 | 星宿连线 | 5 个点连线 |
| 星野分野 | 古地图星线 | 5 条连线 |
| 风水罗盘 | 罗盘刻度 | 360 条线 |
六、路径绘制的高级技巧
6.1 路径缓存 (Path2D)
对于复杂且重复使用的路径,可使用 Path2D 缓存:
typescript
private cachedPath: Path2D | null = null;
private buildStarPath(w: number, h: number): Path2D {
if (this.cachedPath) return this.cachedPath;
const path = new Path2D();
path.moveTo(w * 0.2, h * 0.6);
path.lineTo(w * 0.35, h * 0.4);
path.lineTo(w * 0.5, h * 0.3);
path.lineTo(w * 0.65, h * 0.35);
path.lineTo(w * 0.8, h * 0.5);
this.cachedPath = path;
return path;
}
6.2 路径绘制性能对比
| 绘制方式 | 100 条线段 | 1000 条线段 | 10000 条线段 |
|---|---|---|---|
| 逐条 beginPath/stroke | ~1ms | ~10ms | ~100ms |
| 批量 lineTo + 单次 stroke | ~0.5ms | ~3ms | ~30ms |
| Path2D 缓存 | ~0.1ms | ~0.5ms | ~5ms |
6.3 玄象项目路径绘制应用场景
| 页面 | 路径用途 | 线段数 | 绘制方式 |
|---|---|---|---|
| 启动页 | 星宿连线 | 6 | 批量 lineTo |
| 太极图 | 阴阳半圆 | 2 | 单次 arc |
| 星宿列表 | 圆盘分区 | 8 | 批量 arc + closePath |
| 星宿详情 | 星点连线 | 5 | 批量 lineTo |
| 星野分野 | 古地图星线 | 5 | 批量 lineTo |
七、路径绘制的调试技巧
7.1 路径可视化调试
Canvas 路径绘制时,可用不同颜色区分不同路径段:
typescript
// 调试:用红色标注路径起点,蓝色标注路径终点
canvas.strokeStyle = '#FF0000';
canvas.lineWidth = 3;
canvas.beginPath();
canvas.moveTo(points[0][0], points[0][1]);
for (let i = 1; i < points.length; i++) {
canvas.strokeStyle = i === points.length - 1 ? '#0000FF' : Colors.PRIMARY_GOLD;
canvas.lineTo(points[i][0], points[i][1]);
canvas.stroke();
canvas.beginPath();
canvas.moveTo(points[i][0], points[i][1]);
}
7.2 路径绘制常见错误
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| 路径不闭合 | 缺少 closePath | 在 stroke 前调用 closePath |
| 路径重叠 | 未调用 beginPath | 每条新路径前调用 beginPath |
| 颜色不对 | strokeStyle 未设置 | 确保 stroke 前设置 strokeStyle |
| 线宽不对 | lineWidth 未设置 | 确保 stroke 前设置 lineWidth |
7.3 路径绘制的性能基准
typescript
// 测量路径绘制耗时
private measurePathPerformance(): void {
const start = performance.now();
// 绘制路径
this.drawStarPath();
const end = performance.now();
hilog.info(0x0000, 'Canvas', 'Path draw took: %{public}d ms', end - start);
}
总结
本篇以玄象项目 Canvas 路径绘制为蓝本,深入剖析了 ArkUI 路径绘制核心 API:从 moveTo 移动画笔、lineTo 绘制线段、stroke 描边输出,到 beginPath 路径重置、closePath 封闭路径、lineWidth 线宽控制。掌握这套 Canvas 路径绘制方法论,您就能为任何 HarmonyOS 应用绘制复杂的几何图形。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- HarmonyOS 官方文档:CanvasRenderingContext2D
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net