#星光不负 码向未来# 鸿蒙开发实战:几何图形绘制全流程解析与落地指南 原创 精华

陈花花花
发布于 2025-10-30 17:36
浏览
1收藏

目录

  • 前言

  • 创建绘制组件

  • 形状视口 viewport 使用

  • 自定义样式

  • 结束语

前言

在HarmonyOS全场景智慧生态中,应用的视觉呈现直接影响用户的使用体验与产品竞争力,而几何图形绘制作为视觉开发的核心基础,贯穿于界面布局、交互反馈、数据可视化等多个关键环节。从简单的按钮圆角、图标轮廓,到复杂的图表展示、动态图形效果,都离不开高效、灵活的图形绘制能力。鸿蒙系统凭借其跨设备适配特性与丰富的原生 API,为开发者提供了一套完善的图形绘制解决方案,其中 Shape 组件作为绘制组件的 “基石”,不仅统一了各类图形的通用属性,还支持类似 SVG 的矢量绘制逻辑,让开发者无需依赖第三方库,就能轻松实现多样化的视觉效果。接下来就来详细给大家介绍一下几何图形绘制相关的内容。

#星光不负 码向未来# 鸿蒙开发实战:几何图形绘制全流程解析与落地指南-鸿蒙开发者社区

创建绘制组件

首先来介绍一下绘制组件,绘制组件是鸿蒙图形绘制的 “载体”,根据使用场景不同,主要分为以下两种创建形式:

1、以 Shape 为父组件创建(支持 SVG-like 效果)

Shape 组件作为所有绘制组件的父组件,负责定义通用属性(比如填充色、边框等),并通过value参数指定绘制目标。若传入PixelMap对象,图形将绘制在该对象中;若不设置,则默认绘制在当前页面的绘制目标中。这种方式适合需要组合多个图形、实现复杂矢量效果的场景,其核心接口定义如下:

Shape(value?: PixelMap)

实战案例:在 Shape 父组件中嵌套 Rect(矩形)组件,绘制一个宽 300px、高 50px 的矩形,代码如下:

Shape() {​
  Rect().width(300).height(50)​
}

2、绘制组件单独使用(直接绘制指定图形)

当仅需绘制单个基础图形时,可直接使用鸿蒙提供的 7 种原生绘制组件,无需依赖 Shape 父组件,简化开发流程。这 7 种组件分别对应不同几何形状,覆盖常见开发需求:

  • Circle(圆形):绘制正圆或椭圆(宽高不一致时)

  • Ellipse(椭圆形):专门用于绘制椭圆

  • Line(直线):绘制单条直线段

  • Polyline(折线):绘制多条连续直线段(非闭合)

  • Polygon(多边形):绘制闭合的多边形

  • Path(路径):通过路径指令绘制任意复杂图形

  • Rect(矩形):绘制矩形(支持圆角)

这里以最常用的 Circle(圆形)组件为例,其核心接口定义如下,支持通过options参数设置宽高:

Circle(options?: {width?: string | number, height?: string | number})

实战案例:直接创建一个宽 150px、高 150px 的正圆,代码如下:

Circle({ width: 150, height: 150 })

形状视口 viewport 使用

形状视口(viewport)是鸿蒙图形绘制中实现 “坐标映射” 与 “图形缩放” 的核心属性,它的本质是定义 “用户空间的矩形区域” 与 “组件实际显示区域” 之间的映射关系 —— 通过调整 viewport 的参数,可实现图形的放大、缩小、平移等效果,而无需修改图形本身的尺寸属性,极大提升了图形适配的灵活性。

1、viewport 核心定义

viewport 属性包含 4 个可选参数,分别控制视口的位置与尺寸,具体说明如下:

viewPort{ 
  x?: number | string,    // 视口左上角x坐标(默认0)
  y?: number | string,    // 视口左上角y坐标(默认0)
  width?: number | string,// 视口宽度(默认0)
  height?: number | string// 视口高度(默认0)
}

  • 系统能力:SystemCapability.ArkUI.ArkUI.Full(需确保项目已开启对应权限)

  • 默认值:{ x:0, y:0, width:0, height:0 }

  • 核心逻辑:viewport 定义的矩形区域会完整映射到组件的显示区域(即组件的 width/height),若 viewport 的宽高与组件宽高比例不一致,图形会自动适配组件尺寸,不会出现拉伸变形。

2、实战案例解析

接下来通过以下 3 个简单的代码案例,让大家可直观理解 viewport 的缩放与平移效果。

案例 1:图形的放大与缩小

通过设置不同尺寸的 viewport,实现同一图形在相同组件尺寸下的放大与缩小效果,核心代码如下所示:

// 定义两个viewport配置:小视口(用于放大)、大视口(用于缩小)
class tmp{
  x:number = 0
  y:number = 0
  width:number = 75  // 小视口:宽高75px
  height:number = 75
}
let viep:tmp = new tmp()
class tmp1{
  x:number = 0
  y:number = 0
  width:number = 300 // 大视口:宽高300px
  height:number = 300
}
let viep1:tmp1 = new tmp1()
// 1. 原始尺寸:直接绘制宽高75px的圆
Text('原始尺寸Circle组件')
Circle({width: 75, height: 75}).fill('#E87361')
// 2. 对比放大与缩小效果(组件宽高均为150px)
Row({space:10}) {
  Column() {
    Text('shape内放大的Circle组件')
    Shape() {
      Rect().width('100%').height('100%').fill('#0097D4') // 填充视口的矩形
      Circle({width: 75, height: 75}).fill('#E87361')     // 原始尺寸的圆
    }
    .viewPort(viep)       // 绑定小视口(75px)
    .width(150).height(150)// 组件尺寸150px(视口放大2倍)
    .backgroundColor('#F5DC62')
  }
  Column() {
    Text('Shape内缩小的Circle组件')
    Shape() {
      Rect().width('100%').height('100%').fill('#BDDB69') // 填充视口的矩形
      Circle({width: 75, height: 75}).fill('#E87361')     // 原始尺寸的圆
    }
    .viewPort(viep1)      // 绑定大视口(300px)
    .width(150).height(150)// 组件尺寸150px(视口缩小2倍)
    .backgroundColor('#F5DC62')
  }
}


上面代码的效果,左侧组件中,75px 的视口映射到 150px 的组件,圆被放大 2 倍;右侧组件中,300px 的视口映射到 150px 的组件,圆被缩小 2 倍。

案例 2:默认视口的图形绘制

创建宽高 300px 的 Shape 组件,使用默认尺寸的 viewport,绘制圆与填充矩形,核心代码如下所示:

class tmp{
  x:number = 0
  y:number = 0
  width:number = 300 // 视口尺寸与组件尺寸一致
  height:number = 300
}
let viep:tmp = new tmp()
Shape() {
  Rect().width("100%").height("100%").fill("#0097D4") // 填充整个视口
  Circle({ width: 150, height: 150 }).fill("#E87361")  // 圆直径150px(居中显示)
}
.viewPort(viep)
.width(300).height(300)
.backgroundColor("#F5DC62")

上面代码效果:由于 viewport 尺寸与组件尺寸一致,图形按原始比例显示,矩形填满组件,圆居中且未被缩放。

案例 3:viewport 的平移效果

通过调整 viewport 的 x、y 坐标,实现图形在组件内的平移(以向右下方平移为例),核心代码如下所示:

class tmp1{
  x:number = -150 // x轴向左偏移150px(等效图形向右平移150px)
  y:number = -150 // y轴向上偏移150px(等效图形向下平移150px)
  width:number = 300
  height:number = 300
}
let viep1:tmp1 = new tmp1()
Shape() {
  Rect().width("100%").height("100%").fill("#0097D4") // 填充平移后的视口
  Circle({ width: 150, height: 150 }).fill("#E87361")  // 圆随视口平移
}
.viewPort(viep1)
.width(300).height(300)
.backgroundColor("#F5DC62")


上面代码的效果,viewport 的 x=-150、y=-150 表示视口左上角相对于组件左上角向左、向上各移动 150px,因此图形整体向右、向下平移 150px,部分区域可能超出组件显示范围。

自定义样式

最后再来介绍一下关于自定义样式相关的内容,鸿蒙绘制组件提供了丰富的样式属性,支持开发者从颜色、边框、线条样式等维度自定义图形外观,满足不同设计需求,同样介绍一下常用样式属性及实战案例。

1、核心样式属性说明


属性名


作用


可选值 / 说明


fill


设置图形填充区域颜色


颜色值(如#E87361、Color.Red、0x317AF7)


stroke


设置图形边框颜色


同 fill 的颜色值格式


strokeOpacity


设置边框透明度


0~1 的数值(0 完全透明,1 不透明)


strokeLineJoin


设置线条拐角样式


Bevel(斜角)、Miter(尖角,默认)、Round(圆角)


strokeMiterLimit


斜接长度与边框宽度的比值上限


数值(仅 Miter 样式生效,默认 4)


antiAlias


是否开启抗锯齿(优化图形边缘平滑度)


boolean(默认 true,建议开启)


strokeWidth


设置边框宽度


数值(单位 px,默认 0,即无边框)


strokeDashArray


设置虚线边框的 “实线 + 空白” 循环序列


数组(如[1,2]表示 1px 实线 + 2px 空白循环)

2、实战案例解析

案例 1:自定义路径与拐角样式

在 Shape 组件中通过 Path(路径)绘制封闭图形,并自定义填充色、边框样式与拐角效果,核心代码如下所示:

@Entry
@Component
struct ShapeExample {
  build() {
    Column({ space: 10 }) {
      Shape() {
        // 路径指令:M(起点)→ L(直线)→ Z(闭合),绘制梯形
        Path().width(200).height(60).commands('M0 0 L400 0 L400 150 Z')
      }
      .viewPort({ x: -80, y: -5, width: 500, height: 300 }) // 调整视口适配路径
      .fill(0x317AF7)                                       // 填充色:蓝色
      .stroke(Color.Red)                                    // 边框色:红色
      .strokeWidth(3)                                       // 边框宽:3px
      .strokeLineJoin(LineJoinStyle.Miter)                  // 拐角样式:尖角
      .strokeMiterLimit(5)                                  // 斜接比值上限:5
    }.width('100%').margin({ top: 15 })
  }
}

实现的效果,路径绘制的梯形填充蓝色,红色边框宽 3px,拐角为尖角,边缘因抗锯齿(默认开启)显得平滑。

案例 2:圆形与虚线圆环

同时绘制实心圆与虚线圆环,演示fillOpacity(填充透明度)与strokeDashArray(虚线)的使用,核心代码如下所示:

@Entry
@Component
struct CircleExample {
  build() {
    Column({ space: 10 }) {
      // 1. 实心圆:直径150px(宽高一致)
      Circle({ width: 150, height: 150 })
        .fill('#E87361') // 填充色:红色(默认无填充,此处手动设置)
      // 2. 虚线圆环:直径150px(以短边为准),无填充
      Circle()
        .width(150).height(200)       // 宽150px(短边),直径取150px
        .fillOpacity(0)               // 填充透明度0(完全透明,仅显示边框)
        .strokeWidth(3)               // 边框宽3px
        .stroke(Color.Red)            // 边框色:红色
        .strokeDashArray([1, 2])      // 虚线样式:1px实线+2px空白
    }.width('100%')
  }
}

上面代码的效果,上方为红色实心圆,下方为红色虚线圆环(因宽 < 高,圆环直径以宽 150px 为准,垂直方向居中显示)。

最后

鸿蒙应用的几何图形绘制,看似是 “基础操作”,实则是连接设计理念与用户体验的关键桥梁,无论是打造简洁美观的界面,还是实现生动的交互反馈,都需要开发者熟练掌握组件创建、视口控制、样式定制这三大核心能力。本文通过清晰的原理讲解与可落地的源码案例,梳理了鸿蒙图形绘制的全流程,从 “为什么用” 到 “怎么用”,再到 “如何用好”,为开发者提供了一套完整的实战指南。但技术的掌握离不开实践的打磨,建议大家在学习后,尝试将这些技巧应用到实际项目中。随着鸿蒙生态的持续升级,图形绘制 API 也在不断丰富,我们可关注鸿蒙官方文档,及时跟进新技术,将图形绘制与跨设备特性结合,创造出更具创新性的视觉效果。最后,希望本文能成为你鸿蒙开发之路上的 “实用手册”,帮助你快速攻克几何图形绘制的技术难点,让你的应用在视觉呈现上更具竞争力,期待看到更多基于鸿蒙图形能力的优秀应用,共同推动全场景智慧生态的发展。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
1
收藏 1
回复
举报
回复
    相关推荐