鸿蒙开发-想画虚线和特效路径?PathEffect来帮忙
想画虚线?PathEffect 让线条不再单调
你有没有注意过,地图上的国界线是虚线,设计稿里的辅助线是虚线,流程图里的判断分支也是虚线。在 HarmonyOS 的 drawing 模块里,画虚线靠的是PathEffect。
PathEffect 是什么?
PathEffect(路径效果)可以对 Pen 描绘的路径做"变形"。最常用的就是把实线变成虚线,但它还能做更多——比如用自定义形状来做虚线段,让线条看起来像一串小箭头、一串小圆点,甚至一串小星星。
下面是 PathEffect 的类型和使用流程:
画虚线:createDashPathEffect
最基础的用法:
import{drawing}from'@kit.ArkGraphics2D';letintervals=[10,5];// 实线10像素,空白5像素leteffect=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 上
constpen=newdrawing.Pen();pen.setColor(255,0,0,255);pen.setStrokeWidth(2);leteffect=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把自定义形状当作"虚线段":
// 创建一个小三角形作为虚线段letdashPath=newdrawing.Path();dashPath.moveTo(0,0);dashPath.lineTo(10,5);dashPath.lineTo(0,10);dashPath.close();letpathEffect=drawing.PathEffect.createPathDashEffect(dashPath,// 用这个形状作为虚线段50,// 步长(每个虚线段之间的距离)0,// 偏移量drawing.PathDashStyle.MORPH// 样式);pen.setPathEffect(pathEffect);PathDashStyle有三种样式:
- MORPH:虚线段会沿着路径的方向旋转,平滑过渡
- ROTATE:虚线段会旋转,但在拐角处不会平滑过渡
- TRANSLATE:虚线段不会旋转,始终保持原始方向
一般用MORPH效果最好——沿着曲线走的时候,虚线段会跟着转弯。
用圆形做虚线
letcirclePath=newdrawing.Path();circlePath.addCircle(0,0,3);// 半径 3 的小圆letpathEffect=drawing.PathEffect.createPathDashEffect(circlePath,30,0,drawing.PathDashStyle.MORPH);这样画出来的虚线就是一串小圆点,像铁轨上的铆钉一样。
自定义形状虚线的三种 PathDashStyle 效果对比如下:
完整示例:多种虚线效果
import{RenderNode}from'@kit.ArkUI';import{common2D,drawing}from'@kit.ArkGraphics2D';classDashLineRenderNodeextendsRenderNode{draw(context:DrawContext){constcanvas=context.canvas;// 标准虚线constpen1=newdrawing.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();// 点状线constpen2=newdrawing.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();// 三角形虚线lettriPath=newdrawing.Path();triPath.moveTo(0,0);triPath.lineTo(8,4);triPath.lineTo(0,8);triPath.close();constpen3=newdrawing.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();// 圆形虚线letcirclePath=newdrawing.Path();circlePath.addCircle(0,0,4);constpen4=newdrawing.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,就能做出虚线"流动"的效果:
letphase=(Date.now()/50)%15;// 每 50ms 偏移 1 像素leteffect=drawing.PathEffect.createDashPathEffect([10,5],phase);pen.setPathEffect(effect);这在加载动画、路径引导等场景中很常见——虚线像水流一样沿着路径流动。
小结
- createDashPathEffect:标准虚线,用
intervals数组定义"实线-空白"模式。 - createPathDashEffect:自定义形状虚线,用 Path 定义虚线段的形状。
phase参数控制偏移量,可以做虚线动画。PathDashStyle.MORPH让虚线段沿路径方向旋转,效果最自然。setPathEffect(null)清除虚线效果。
下一篇我们进入场景三:AR 增强现实,看看怎么用 AR Engine 做平面识别和图像跟踪。
