头图

在日常的鸿蒙应用开发工作中,我常常会遇到需要绘制各种图形和路径的场景。无论是简单的直线、折线,还是复杂的曲线、椭圆弧,传统的布局方式很难满足多样化的图形绘制需求。直到我接触到了 ArkTS 中的 Path 组件,它就像一把神奇的画笔,为我打开了创意绘图的大门。通过灵活运用 Path 组件,我能够轻松地在应用中绘制出各种精美的图形,为用户带来更加丰富和生动的视觉体验。为了帮助更多开发者快速掌握这个强大的组件,我决定将自己的学习经验整理成这篇自学指南。

一、Path 组件概述

Path 组件从 API Version 7 开始就被引入到 ArkTS 中,为开发者提供了强大的图形绘制能力。它可以在应用界面上绘制各种复杂的路径和图形,并且支持在 ArkTS 卡片(从 API version 9 开始)和元服务(从 API version 11 开始)中使用,其系统能力依赖于 SystemCapability.ArkUI.ArkUI.Full

1. 接口与参数

Path 组件的接口为 Path(options?: PathOptions),其中 options 参数用于指定 Path 绘制区域,不过该参数并非必填项。

PathOptions 对象说明(从 API version 14 开始)

  • width:路径所在矩形的宽度,可以是字符串或数字类型。若值为异常值或缺省,将按照自身内容需要的宽度处理,默认单位为 vp。例如,width: '200vp' 表示路径所在矩形的宽度为 200 虚拟像素。
  • height:路径所在矩形的高度,同样可以是字符串或数字类型。处理方式与 width 类似,默认单位也是 vp
  • commands:路径绘制的命令字符串,用于定义路径的具体形状。若值为异常值或缺省,将按照自身内容需要的宽度处理,默认值为空字符串。

2. 支持的属性

Path 组件除了支持通用属性外,还提供了一系列用于控制路径绘制效果的属性。

2.1 commands 属性

用于设置路径绘制的命令字符串,单位为 px。像素单位转换方法需参考像素单位转换相关文档。例如:

Path()
  .commands('M0 0 L100 100') // 从 (0, 0) 点绘制一条直线到 (100, 100) 点

2.2 fill 属性

设置填充区域的颜色,若设置异常值将按照默认值处理。当与通用属性 foregroundColor 同时设置时,后设置的属性生效。默认填充颜色为 Color.Black。例如:

Path()
  .commands('M0 0 L100 0 L100 100 L0 100 Z') // 绘制一个矩形
  .fill(Color.Red) // 填充为红色

2.3 fillOpacity 属性

设置填充区域的透明度,取值范围是 [0.0, 1.0]。若给定值小于 0.0,则取值为 0.0;若给定值大于 1.0,则取值为 1.0;其余异常值按 1.0 处理。默认透明度为 1。例如:

Path()
  .commands('M0 0 L100 0 L100 100 L0 100 Z')
  .fill(Color.Blue)
  .fillOpacity(0.5) // 填充区域半透明

2.4 stroke 属性

设置边框颜色,若不设置则默认没有边框线条。设置异常值时不会绘制边框线条。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Green) // 设置边框颜色为绿色

2.5 strokeDashArray 属性

设置线条间隙,线段相交时可能会出现重叠现象。异常值按照默认值处理,默认值为空数组,默认单位为 vp。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .strokeDashArray([5, 10]) // 线条为 5vp 实线,10vp 间隙交替

2.6 strokeDashOffset 属性

设置线条绘制起点的偏移量,异常值按照默认值处理,默认值为 0,默认单位为 vp。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .strokeDashArray([5, 10])
  .strokeDashOffset(5) // 线条起点偏移 5vp

2.7 strokeLineCap 属性

设置线条端点绘制样式,默认值为 LineCapStyle.Butt。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .strokeLineCap(LineCapStyle.Round) // 线条端点为圆角样式

2.8 strokeLineJoin 属性

设置线条拐角绘制样式,默认值为 LineJoinStyle.Miter。例如:

Path()
  .commands('M0 0 L50 50 L100 0')
  .stroke(Color.Black)
  .strokeLineJoin(LineJoinStyle.Bevel) // 线条拐角为斜角样式

2.9 strokeMiterLimit 属性

设置斜接长度与边框宽度比值的极限值,该属性需在 strokeLineJoin 属性取值为 LineJoinStyle.Miter 时生效。合法值范围应当大于等于 1.0,当取值范围在 [0,1) 时按 1.0 处理,其余异常值按默认值处理,默认值为 4。例如:

Path()
  .commands('M0 0 L50 50 L100 0')
  .stroke(Color.Black)
  .strokeLineJoin(LineJoinStyle.Miter)
  .strokeMiterLimit(2) // 设置斜接长度与边框宽度比值的极限值为 2

2.10 strokeOpacity 属性

设置线条透明度,取值范围是 [0.0, 1.0]。若给定值小于 0.0,则取值为 0.0;若给定值大于 1.0,则取值为 1.0;其余异常值按 1.0 处理。默认透明度为 1。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .strokeOpacity(0.3) // 线条半透明

2.11 strokeWidth 属性

设置线条宽度,若为字符串类型,暂不支持百分比,百分比按照 1px 处理。默认宽度为 1,默认单位为 vp。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .strokeWidth(5) // 线条宽度为 5vp

2.12 antiAlias 属性

设置是否开启抗锯齿效果,默认值为 true。例如:

Path()
  .commands('M0 0 L100 100')
  .stroke(Color.Black)
  .antiAlias(false) // 关闭抗锯齿效果

二、绘制命令详解

commands 属性支持一系列绘制命令,通过组合这些命令可以绘制出各种复杂的图形。

1. Mmoveto)命令

在给定的 (x, y) 坐标处开始一个新的子路径。例如,M 0 0 表示将 (0, 0) 点作为新子路径的起始点。

2. Llineto)命令

从当前点到给定的 (x, y) 坐标画一条线,该坐标成为新的当前点。例如,L 50 50 表示绘制当前点到 (50, 50) 点的直线,并将 (50, 50) 点作为新子路径的起始点。

3. Hhorizontal lineto)命令

从当前点绘制一条水平线,等效于将 y 坐标指定为 0 的 L 命令。例如,H 50 表示绘制当前点到 (50, 0) 点的直线,并将 (50, 0) 点作为新子路径的起始点。

4. Vvertical lineto)命令

从当前点绘制一条垂直线,等效于将 x 坐标指定为 0 的 L 命令。例如,V 50 表示绘制当前点到 (0, 50) 点的直线,并将 (0, 50) 点作为新子路径的起始点。

5. Ccurveto)命令

使用 (x1, y1) 作为曲线起点的控制点,(x2, y2) 作为曲线终点的控制点,从当前点到 (x, y) 绘制三次贝塞尔曲线。例如,C100 100 250 100 250 200 表示绘制当前点到 (250, 200) 点的三次贝塞尔曲线,并将 (250, 200) 点作为新子路径的起始点。

6. Ssmooth curveto)命令

(x2, y2) 作为曲线终点的控制点,绘制从当前点到 (x, y) 的三次贝塞尔曲线。若前一个命令是 C 或 S,则起点控制点是上一个命令的终点控制点相对于起点的映射。例如,C100 100 250 100 250 200 S400 300 400 200 第二段贝塞尔曲线的起点控制点为 (250, 300)。如果没有前一个命令或者前一个命令不是 C 或 S,则第一个控制点与当前点重合。

7. Qquadratic Belzier curve)命令

使用 (x1, y1) 作为控制点,从当前点到 (x, y) 绘制二次贝塞尔曲线。例如,Q400 50 600 300 表示绘制当前点到 (600, 300) 点的二次贝塞尔曲线,并将 (600, 300) 点作为新子路径的起始点。

8. Tsmooth quadratic Belzier curveto)命令

绘制从当前点到 (x, y) 的二次贝塞尔曲线。若前一个命令是 Q 或 T,则控制点是上一个命令的终点控制点相对于起点的映射。例如,Q400 50 600 300 T1000 300 第二段贝塞尔曲线的控制点为 (800, 350)。如果没有前一个命令或者前一个命令不是 Q 或 T,则第一个控制点与当前点重合。

9. Aelliptical Arc)命令

从当前点到 (x, y) 绘制一条椭圆弧。椭圆的大小和方向由两个半径 (rx, ry) 和 x-axis-rotation 定义,指示整个椭圆相对于当前坐标系如何旋转(以度为单位)。large-arc-flag 和 sweep-flag 确定弧的绘制方式。

10. Zclosepath)命令

通过将当前路径连接回当前子路径的初始点来关闭当前子路径。

例如,commands('M0 20 L50 50 L50 100 Z') 定义了一个三角形,起始于位置 (0, 20),接着绘制点 (0, 20) 到点 (50, 50) 的直线,再绘制点 (50, 50) 到点 (50, 100) 的直线,最后绘制点 (50, 100) 到 (0, 20) 的直线关闭路径,形成封闭三角形。

三、示例代码分析与拓展

下面我们来分析官方示例代码,并对其进行一些拓展。

// xxx.ets
@Entry
@Component
struct PathExample {
  build() {
    Column({ space: 10 }) {
      Text('Straight line')
        .fontSize(11)
        .fontColor(0xCCCCCC)
        .width('90%')
      // 绘制一条长600px,宽3vp的直线
      Path()
        .width('600px')
        .height('10px')
        .commands('M0 0 L600 0')
        .stroke(Color.Black)
        .strokeWidth(3)

      Text('Straight line graph')
        .fontSize(11)
        .fontColor(0xCCCCCC)
        .width('90%')
      // 绘制直线图形
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
        Path()
          .width('210px')
          .height('310px')
          .commands('M100 0 L200 240 L0 240 Z')
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 0 H200 V200 H0 Z')
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
        Path()
          .width('210px')
          .height('310px')
          .commands('M100 0 L0 100 L50 200 L150 200 L200 100 Z')
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
      }.width('95%')

      Text('Curve graphics').fontSize(11).fontColor(0xCCCCCC).width('90%')
      // 绘制弧线图形
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
        Path()
          .width('250px')
          .height('310px')
          .commands("M0 300 S100 0 240 300 Z")
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 150 C0 100 140 0 200 150 L100 300 Z')
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 100 A30 20 20 0 0 200 100 Z')
          .fillOpacity(0)
          .stroke(Color.Black)
          .strokeWidth(3)
      }.width('95%')
    }.width('100%')
    .margin({ top: 5 })
  }
}

1. 代码分析

  • 直线绘制:通过 commands('M0 0 L600 0') 绘制了一条长度为 600px 的水平直线,设置边框颜色为黑色,宽度为 3vp。
  • 直线图形绘制:使用不同的 commands 字符串绘制了三个不同形状的直线图形,如三角形、矩形等,并设置填充透明度为 0,只显示边框。
  • 曲线图形绘制:利用 SCA 等命令绘制了弧线图形,同样设置填充透明度为 0,突出显示边框。

2. 拓展示例

我们可以对上述示例进行一些拓展,改变颜色、线条样式等,让图形更加丰富。

// xxx.ets
@Entry
@Component
struct ExtendedPathExample {
  build() {
    Column({ space: 10 }) {
      Text('Modified Straight line')
        .fontSize(11)
        .fontColor(0xFF0000) // 红色文字
        .width('90%')
      // 绘制一条长500px,宽5vp的蓝色虚线直线
      Path()
        .width('500px')
        .height('10px')
        .commands('M0 0 L500 0')
        .stroke(Color.Blue)
        .strokeWidth(5)
        .strokeDashArray([10, 5]) // 虚线样式

      Text('Modified Straight line graph')
        .fontSize(11)
        .fontColor(0xFF0000)
        .width('90%')
      // 绘制直线图形,填充颜色并改变边框样式
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
        Path()
          .width('210px')
          .height('310px')
          .commands('M100 0 L200 240 L0 240 Z')
          .fill(Color.Yellow) // 填充黄色
          .fillOpacity(0.8) // 填充半透明
          .stroke(Color.Yellow) // 紫色边框
          .strokeWidth(4)
          .strokeLineCap(LineCapStyle.Round) // 圆角端点
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 0 H200 V200 H0 Z')
          .fill(Color.Green)
          .fillOpacity(0.7)
          .stroke(Color.Orange)
          .strokeWidth(3)
          .strokeLineJoin(LineJoinStyle.Bevel) // 斜角拐角
        Path()
          .width('210px')
          .height('310px')
          .commands('M100 0 L0 100 L50 200 L150 200 L200 100 Z')
          .fill(Color.Pink)
          .fillOpacity(0.6)
          .stroke(Color.Pink)
          .strokeWidth(5)
          .strokeMiterLimit(3) // 调整斜接长度与边框宽度比值的极限值
      }.width('95%')

      Text('Modified Curve graphics').fontSize(11).fontColor(0xFF0000).width('90%')
      // 绘制弧线图形,改变颜色和透明度
      Flex({ justifyContent: FlexAlign.SpaceBetween }) {
        Path()
          .width('250px')
          .height('310px')
          .commands("M0 300 S100 0 240 300 Z")
          .fill(Color.Red)
          .fillOpacity(0.5)
          .stroke(Color.Gray)
          .strokeWidth(4)
          .strokeOpacity(0.8) // 线条半透明
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 150 C0 100 140 0 200 150 L100 300 Z')
          .fill(Color.Orange)
          .fillOpacity(0.4)
          .stroke(Color.Green)
          .strokeWidth(3)
          .strokeDashOffset(2) // 线条起点偏移
        Path()
          .width('210px')
          .height('310px')
          .commands('M0 100 A30 20 20 0 0 200 100 Z')
          .fill(Color.Black)
          .fillOpacity(0.3)
          .stroke(Color.Blue)
          .strokeWidth(5)
          .antiAlias(false) // 关闭抗锯齿效果
      }.width('95%')
    }.width('100%')
    .margin({ top: 5 })
  }
}

通过以上拓展,我们改变了文字颜色、图形的填充颜色、边框颜色、线条样式等,让图形更加生动和多样化。

四、总结

Path 组件为 ArkTS 开发者提供了强大而灵活的图形绘制能力。通过合理运用各种绘制命令和属性,我们可以绘制出各种各样的复杂图形,满足不同应用场景的需求。在实际开发中,建议多尝试不同的命令组合和属性设置,发挥创意,打造出独特而精美的界面效果。同时,要注意处理异常值,确保图形绘制的稳定性和准确性。希望这篇自学指南能够帮助你快速掌握 Path 组件的使用,开启创意绘图之旅!

最后如果这篇文章对你有帮助,希望您能关注,点赞,加收藏哦~~~~


李游Leo
6k 声望1.8k 粉丝

曾在百度、时趣互动、乐视等公司担任过高级前端(软件)开发工程师。后在北京一所当地大学任教,主要职务是教学主任,也为网易云课堂微专业的前端课程负责人。因为本身也是一名IT技术人员,所以非常关注网站制作...