HarmonyOS应用《玄象》开发实战:Canvas 绘制星宿连线:moveTo / lineTo / stroke 路径绘制

阅读时长:约 18 分钟 | 难度:★★★★☆ | 篇章:第 4 篇 · 二十八星宿模块

对应源码:entry/src/main/ets/pages/mansion/MansionListPage.etsMansionDetailPage.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 应用绘制复杂的几何图形。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

相关推荐
独守一片天14 分钟前
HarmonyOS鸿蒙新生态智能体意图框架怎么设计?
华为·harmonyos
梦想不只是梦与想12 小时前
鸿蒙应用api的兼容性:参数配置(二)
harmonyos·sdk版本·sdkversion
北墨NoLimit17 小时前
鸿蒙线程间通信怎么选:TaskPool、TaskGroup、LongTask 与 Worker 实战
typescript·harmonyos
woshihuanglaoshi19 小时前
错题四科入库:鸿蒙错题本种子数据与复习队列效果
学习·华为·harmonyos·鸿蒙
kiros_wang20 小时前
鸿蒙ArkTS枚举实战|静态枚举、动态枚举业务选型、规范落地与避坑全解
harmonyos
2501_919749031 天前
华为鸿蒙免费音乐APP—小羊免费音乐
华为·harmonyos·鸿蒙
世人万千丶1 天前
物品借还闭环:鸿蒙物品清单种子数据与清单效果
学习·华为·harmonyos·鸿蒙
贾伟康1 天前
【知律|10】HarmonyOS ArkTS 案例边界实战:明确普法内容不替代法律意见
harmonyos·arkts·arkui·应用合规·内容治理
xq95271 天前
鸿蒙组件化设计横空出世
harmonyos