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 应用绘制复杂的几何图形。

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


相关资源:

相关推荐
echohelloworld115 小时前
HarmonyOS应用开发实战:猫猫大作战-springMotion 三参数、responsiveSpringMotion 响应式弹簧、与 EaseO
harmonyos·鸿蒙
达子6668 小时前
第13章_HarmonyOs开发图解 视频
华为·音视频·harmonyos
fiona20268 小时前
HarmonyOS应用开发实战:猫猫大作战-如何精准设置缓存数量来平衡内存与滚动流畅度
harmonyos·鸿蒙
程序员黑豆9 小时前
鸿蒙应用开发之父子组件传参:@Prop 装饰器使用教程
前端·后端·harmonyos
FF2501_940228589 小时前
HarmonyOS应用《玄象》开发实战:宜忌标签云:ForEach + padding + borderRadius 的 chip 实现
harmonyos·鸿蒙
程序员黑豆9 小时前
鸿蒙应用开发之V2状态管理:@Local、@ObservedV2、@Trace 使用教程
前端·后端·harmonyos
LEO111109 小时前
HarmonyOS应用开发实战:猫猫大作战-onHover 触发时机、HoverType 类型判定、与 onTouch 的差异、TV/PC 场景应用四
harmonyos·鸿蒙
程序员黑豆9 小时前
鸿蒙应用开发之@State 装饰器详解:从基本类型到 @Observed/@ObjectLink/@Track 嵌套监听
前端·harmonyos