鸿蒙开发-想画虚线和特效路径?PathEffect来帮忙
·
想画虚线?PathEffect 让线条不再单调
你有没有注意过,地图上的国界线是虚线,设计稿里的辅助线是虚线,流程图里的判断分支也是虚线。在 HarmonyOS 的 drawing 模块里,画虚线靠的是 PathEffect。
PathEffect 是什么?
PathEffect(路径效果)可以对 Pen 描绘的路径做"变形"。最常用的就是把实线变成虚线,但它还能做更多——比如用自定义形状来做虚线段,让线条看起来像一串小箭头、一串小圆点,甚至一串小星星。
下面是 PathEffect 的类型和使用流程:
画虚线:createDashPathEffect
最基础的用法:
import { drawing } from '@kit.ArkGraphics2D';
let intervals = [10, 5]; // 实线10像素,空白5像素
let effect = drawing.PathEffect.createDashPathEffect(intervals, 0);
intervals 是一个数组,描述虚线的"实线-空白"交替模式:
- 数组长度必须是偶数,至少 2 个元素
- 奇数位置(第0、2、4…个)是实线部分的长度
- 偶数位置(第1、3、5…个)是空白部分的长度
几个常见的虚线样式:
// 标准虚线:10px 实线 + 5px 空白
[10, 5]
// 长虚线:20px 实线 + 10px 空白
[20, 10]
// 点线交替:10px 实线 + 3px 空白 + 2px 实线 + 3px 空白
[10, 3, 2, 3]
// 点状线:2px 实线 + 5px 空白
[2, 5]
phase 参数是偏移量——控制虚线从哪个位置开始。比如 phase=5 意味着从实线的第 5 个像素开始画。你可以动态改变这个值来做出"虚线滚动"的动画效果。
把虚线效果用在 Pen 上
const pen = new drawing.Pen();
pen.setColor(255, 0, 0, 255);
pen.setStrokeWidth(2);
let effect = drawing.PathEffect.createDashPathEffect([10, 5], 0);
pen.setPathEffect(effect);
canvas.attachPen(pen);
canvas.drawLine(20, 50, 380, 50); // 画一条蓝色虚线
canvas.detachPen();
用完后清除效果:
pen.setPathEffect(null);
自定义形状虚线:createPathDashEffect(API 18+)
如果你觉得普通的虚线太无聊了,可以用 createPathDashEffect 把自定义形状当作"虚线段":
// 创建一个小三角形作为虚线段
let dashPath = new drawing.Path();
dashPath.moveTo(0, 0);
dashPath.lineTo(10, 5);
dashPath.lineTo(0, 10);
dashPath.close();
let pathEffect = drawing.PathEffect.createPathDashEffect(
dashPath, // 用这个形状作为虚线段
50, // 步长(每个虚线段之间的距离)
0, // 偏移量
drawing.PathDashStyle.MORPH // 样式
);
pen.setPathEffect(pathEffect);
PathDashStyle 有三种样式:
- MORPH:虚线段会沿着路径的方向旋转,平滑过渡
- ROTATE:虚线段会旋转,但在拐角处不会平滑过渡
- TRANSLATE:虚线段不会旋转,始终保持原始方向
一般用 MORPH 效果最好——沿着曲线走的时候,虚线段会跟着转弯。
用圆形做虚线
let circlePath = new drawing.Path();
circlePath.addCircle(0, 0, 3); // 半径 3 的小圆
let pathEffect = drawing.PathEffect.createPathDashEffect(
circlePath, 30, 0, drawing.PathDashStyle.MORPH
);
这样画出来的虚线就是一串小圆点,像铁轨上的铆钉一样。
自定义形状虚线的三种 PathDashStyle 效果对比如下:
完整示例:多种虚线效果
import { RenderNode } from '@kit.ArkUI';
import { common2D, drawing } from '@kit.ArkGraphics2D';
class DashLineRenderNode extends RenderNode {
draw(context: DrawContext) {
const canvas = context.canvas;
// 标准虚线
const pen1 = new drawing.Pen();
pen1.setColor(255, 255, 0, 0);
pen1.setStrokeWidth(2);
pen1.setPathEffect(drawing.PathEffect.createDashPathEffect([10, 5], 0));
canvas.attachPen(pen1);
canvas.drawLine(20, 30, 380, 30);
canvas.detachPen();
// 点状线
const pen2 = new drawing.Pen();
pen2.setColor(255, 0, 150, 0);
pen2.setStrokeWidth(3);
pen2.setPathEffect(drawing.PathEffect.createDashPathEffect([2, 8], 0));
canvas.attachPen(pen2);
canvas.drawLine(20, 70, 380, 70);
canvas.detachPen();
// 三角形虚线
let triPath = new drawing.Path();
triPath.moveTo(0, 0);
triPath.lineTo(8, 4);
triPath.lineTo(0, 8);
triPath.close();
const pen3 = new drawing.Pen();
pen3.setColor(255, 0, 0, 200);
pen3.setStrokeWidth(2);
pen3.setPathEffect(drawing.PathEffect.createPathDashEffect(
triPath, 40, 0, drawing.PathDashStyle.MORPH
));
canvas.attachPen(pen3);
canvas.drawLine(20, 110, 380, 110);
canvas.detachPen();
// 圆形虚线
let circlePath = new drawing.Path();
circlePath.addCircle(0, 0, 4);
const pen4 = new drawing.Pen();
pen4.setColor(255, 200, 0, 200);
pen4.setStrokeWidth(2);
pen4.setPathEffect(drawing.PathEffect.createPathDashEffect(
circlePath, 30, 0, drawing.PathDashStyle.MORPH
));
canvas.attachPen(pen4);
canvas.drawLine(20, 150, 380, 150);
canvas.detachPen();
}
}
这段代码画了四种不同风格的虚线:红色标准虚线、绿色点状线、蓝色三角形虚线、紫色圆形虚线。
动态虚线动画
还记得 phase 参数吗?如果你在 draw 方法里根据时间改变 phase,就能做出虚线"流动"的效果:
let phase = (Date.now() / 50) % 15; // 每 50ms 偏移 1 像素
let effect = drawing.PathEffect.createDashPathEffect([10, 5], phase);
pen.setPathEffect(effect);
这在加载动画、路径引导等场景中很常见——虚线像水流一样沿着路径流动。
小结
- createDashPathEffect:标准虚线,用
intervals数组定义"实线-空白"模式。 - createPathDashEffect:自定义形状虚线,用 Path 定义虚线段的形状。
phase参数控制偏移量,可以做虚线动画。PathDashStyle.MORPH让虚线段沿路径方向旋转,效果最自然。setPathEffect(null)清除虚线效果。
下一篇我们进入场景三:AR 增强现实,看看怎么用 AR Engine 做平面识别和图像跟踪。
更多推荐


所有评论(0)