HarmonyOS:绘制几何图形 (Shape)

一、几何图形绘制概述

绘制几何图形有两种方法:一是通过绘制组件Shape 直接绘制出几何图形;二是通过形状裁剪属性clipShape将组件裁剪成几何图形。

1.1 使用场景

绘制方式 使用场景
绘制几何图形 (Shape) 用于创建指定形状的组件,在页面上直接绘制出几何图形。
形状裁剪 (clipShape) 用于将组件裁剪为指定的几何图形。

1.2 约束限制

  • 对绘制组件,既可用Shape组件作为父组件实现类似SVG的效果,也可单独使用各种形状的子组件进行绘制。
  • 对形状裁剪属性,裁剪不会导致被裁剪区域无法响应绑定的手势事件。

二、Shape组件简介

绘制组件用于在页面绘制图形,Shape组件是绘制组件的父组件,父组件中会描述所有绘制组件均支持的通用属性。具体用法请参考Shape。

三、创建绘制组件

绘制组件可以由以下两种形式创建:

  • 绘制组件使用Shape作为父组件,实现类似SVG的效果。接口调用为以下形式:
bash 复制代码
Shape(value?: PixelMap)

该接口用于创建带有父组件的绘制组件,其中value用于设置绘制目标,可将图形绘制在指定的PixelMap对象中,若未设置,则在当前绘制目标中进行绘制。

bash 复制代码
Shape() {
  Rect().width(300).height(50)
}
  • 绘制组件单独使用,用于在页面上绘制指定的图形。有7种绘制类型,分别为Circle(圆形)、Ellipse(椭圆形)、Line(直线)、Polyline(折线)、Polygon(多边形)、Path(路径)、Rect(矩形)。以Circle的接口调用为例:
bash 复制代码
Circle(value?: { width?: string | number, height?: string | number })

该接口用于在页面绘制圆形,其中width用于设置圆形的宽度,height用于设置圆形的高度,圆形直径由宽高最小值确定。

bash 复制代码
Circle({ width: 150, height: 150 })

四、形状视口viewPort

bash 复制代码
viewPort(value: { x?: number | string, y?: number | string, width?: number | string, height?: number | string })

形状视口viewPort指定用户空间中的一个矩形,该矩形映射到为关联的SVG元素建立的视区边界。viewPort属性的值包含x、y、width和height四个可选参数,x和y表示视区的左上角坐标,width和height表示其尺寸。

以下三个示例说明如何使用viewPort:

  • 通过形状视口对图形进行放大与缩小。
    效果图

ViewPortShape.ets代码

bash 复制代码
class tmp {
  x: number = 0
  y: number = 0
  width: number = 75
  height: number = 75
}

class tmp1 {
  x:number = 0
  y:number = 0
  width:number = 300
  height:number = 300
}
@Component
export default struct ViewPortShape {
  viep: tmp = new tmp();
  viep1: tmp1 = new tmp1();

  build() {
    Column() {
      Text('通过形状视口对图形进行放大与缩小').fontColor(Color.Blue).fontSize(20).fontWeight(FontWeight.Medium).margin({ top: 40 })
      // 画一个宽高都为75的圆
      Text('原始尺寸Circle组件').margin({top: 16})
      Circle({ width: 75, height: 75 }).fill('#E87361')

      Row({ space: 10 }) {
        Column() {
          // 创建一个宽高都为150的shape组件,背景色为黄色,一个宽高都为75的viewPort。
          // 用一个蓝色的矩形来填充viewPort,在viewPort中绘制一个直径为75的圆。
          // 绘制结束,viewPort会根据组件宽高放大两倍。
          Text('shape内放大的Circle组件')
          Shape() {
            Rect().width('100%').height('100%').fill('#0097D4')
            Circle({ width: 75, height: 75 }).fill('#E87361')
          }
          .viewPort(this.viep)
          .width(150)
          .height(150)
          .backgroundColor('#F5DC62')
        }

        Column() {
          // 创建一个宽高都为150的shape组件,背景色为黄色,一个宽高都为300的viewPort。
          // 用一个绿色的矩形来填充viewPort,在viewPort中绘制一个直径为75的圆。
          // 绘制结束,viewPort会根据组件宽高缩小两倍。
          Text('Shape内缩小的Circle组件')
          Shape() {
            Rect().width('100%').height('100%').fill('#BDDB69')
            Circle({width: 75, height: 75}).fill('#E87361')
          }
          .viewPort(this.viep1)
          .width(150)
          .height(150)
          .backgroundColor('#F5DC62')
        }
      }
    }
  }
}
  • 创建一个宽高都为300的shape组件,背景色为黄色,创建一个宽高都为300的viewPort。用一个蓝色的矩形来填充viewPort,在viewPort中绘制一个半径为75的圆。
    效果图

示例代码

bash 复制代码
class tmp {
  x: number = 0
  y: number = 0
  width: number = 300
  height: number = 300
}

@Entry
@Component
struct Index {
  viep: tmp = new tmp();

  build() {
    Column() {
      Shape() {
        Rect().width("100%").height("100%").fill("#0097D4")
        Circle({ width: 150, height: 150 }).fill("#E87361")
      }
      .viewPort(this.viep)
      .width(300)
      .height(300)
      .backgroundColor("#F5DC62")
    }
  }
}
  • 创建一个宽高都为300的shape组件,背景色为黄色,创建一个宽高都为300的viewPort。用一个蓝色的矩形来填充viewPort,在viewPort中绘制一个半径为75的圆,将viewPort向右方和下方各平移150。
    效果图

示例代码

bash 复制代码
class tmp {
  x: number = -150
  y: number = -150
  width: number = 300
  height: number = 300
}

@Entry
@Component
struct Index {
  viep: tmp = new tmp();

  build() {
    Column() {
      Shape() {
        Rect().width("100%").height("100%").fill("#0097D4")
        Circle({ width: 150, height: 150 }).fill("#E87361")
      }
      .viewPort(this.viep)
      .width(300)
      .height(300)
      .backgroundColor("#F5DC62")
    }
  }
}

五、自定义样式

绘制组件支持通过各种属性更改组件样式。

  • 通过fill可以设置组件填充区域颜色。 效果图

示例代码

bash 复制代码
@Component
export default struct PathShape {
  build() {
    Column({ space: 10 }) {
      Path()
        .width(100)
        .height(100)
        .commands('M150 0 L300 300 L0 300 Z')
        .fill("#E87361")
        .strokeWidth(0)
    }
    .margin({top: 20})
  }
}
  • 通过stroke可以设置组件边框颜色。 效果图

示例代码

bash 复制代码
Path()
  .width(100)
  .height(100)
  .fillOpacity(0)
  .commands('M150 0 L300 300 L0 300 Z')
  .stroke(Color.Red)
  • 通过strokeOpacity可以设置边框透明度。 效果图

示例代码

bash 复制代码
Path()
  .width(100)
  .height(100)
  .fillOpacity(0)
  .commands('M150 0 L300 300 L0 300 Z')
  .stroke(Color.Red)
  .strokeWidth(10)
  .strokeOpacity(0.2)
  • 通过strokeLineJoin可以设置线条拐角绘制样式。拐角绘制样式分为Bevel(使用斜角连接路径段)、Miter(使用尖角连接路径段)、Round(使用圆角连接路径段)。 效果图

示例代码

bash 复制代码
Polyline()
  .width(100)
  .height(100)
  .fillOpacity(0)
  .stroke(Color.Red)
  .strokeWidth(8)
  .points([[20, 0], [0, 100], [100, 90]])
   // 设置折线拐角处为圆弧
  .strokeLineJoin(LineJoinStyle.Round)
  • 通过strokeMiterLimit设置斜接长度与边框宽度比值的极限值。 斜接长度表示外边框外边交点到内边交点的距离,边框宽度即strokeWidth属性的值。strokeMiterLimit取值需大于等于1,且在strokeLineJoin属性取值LineJoinStyle.Miter时生效。 效果图

示例代码

bash 复制代码
Polyline()
  .width(100)
  .height(100)
  .fillOpacity(0)
  .stroke(Color.Red)
  .strokeWidth(10)
  .points([[20, 0], [20, 100], [100, 100]])
  // 设置折线拐角处为尖角
  .strokeLineJoin(LineJoinStyle.Miter)
  // 设置斜接长度与线宽的比值
  .strokeMiterLimit(1/Math.sin(45))
Polyline()
  .width(100)
  .height(100)
  .fillOpacity(0)
  .stroke(Color.Red)
  .strokeWidth(10)
  .points([[20, 0], [20, 100], [100, 100]])
  .strokeLineJoin(LineJoinStyle.Miter)
  .strokeMiterLimit(1.42)
  • 通过antiAlias设置是否开启抗锯齿,默认值为true(开启抗锯齿)。 效果图

示例代码

bash 复制代码
//开启抗锯齿
Circle()
  .width(150)
  .height(200)
  .fillOpacity(0)
  .strokeWidth(5)
  .stroke(Color.Black)

关闭抗锯齿

示例代码

bash 复制代码
//关闭抗锯齿
Circle()
  .width(150)
  .height(200)
  .fillOpacity(0)
  .strokeWidth(5)
  .stroke(Color.Black)
  .antiAlias(false)

六、场景示例

6.1 绘制封闭路径

在Shape的(-80, -5)点绘制一个封闭路径,填充颜色0x317AF7,线条宽度3,边框颜色红色,拐角样式锐角(默认值)。
效果图

示例代码

bash 复制代码
@Entry
@Component
struct ShapeExample {
  build() {
    Column({ space: 10 }) {
      Shape() {
        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)
      .strokeLineJoin(LineJoinStyle.Miter)
      .strokeMiterLimit(5)
    }.width('100%').margin({ top: 15 })
  }
}

6.2 绘制圆和圆环

绘制一个直径为150的圆,和一个直径为150、线条为红色虚线的圆环(宽高设置不一致时以短边为直径)。
效果图

示例代码

bash 复制代码
@Entry
@Component
struct CircleExample {
  build() {
    Column({ space: 10 }) {
      //绘制一个直径为150的圆
      Circle({ width: 150, height: 150 })
      //绘制一个直径为150、线条为红色虚线的圆环
      Circle()
        .width(150)
        .height(200)
        .fillOpacity(0)
        .strokeWidth(3)
        .stroke(Color.Red)
        .strokeDashArray([1, 2])
    }.width('100%')
  }
}

6.3 UI视觉属性作用效果

说明 backgroundColor、linearGradient等通用属性作用于组件的背景区域,而不会在组件具体的内容区域生效。
效果图

示例代码

bash 复制代码
@Entry
@Component
struct CircleExample {
  build() {
    Column({ space: 10 }) {
      //绘制一个直径为150的圆
      Circle()
        .width(150)
        .height(200)
        .backgroundColor(Color.Pink) // 会生效在一个150*200大小的矩形区域,而非仅在绘制的一个直径为150的圆形区域
    }.width('100%')
  }
}
相关推荐
遇到困难睡大觉哈哈2 小时前
HarmonyOS —— Remote Communication Kit 拦截器(Interceptor)高阶定制能力笔记
笔记·华为·harmonyos
遇到困难睡大觉哈哈3 小时前
HarmonyOS —— Remote Communication Kit 定制处理行为(ProcessingConfiguration)速记笔记
笔记·华为·harmonyos
氤氲息3 小时前
鸿蒙 ArkTs 的WebView如何与JS交互
javascript·交互·harmonyos
遇到困难睡大觉哈哈3 小时前
HarmonyOS支付接入证书准备与生成指南
华为·harmonyos
赵浩生3 小时前
鸿蒙技术干货10:鸿蒙图形渲染基础,Canvas绘图与自定义组件实战
harmonyos
赵浩生3 小时前
鸿蒙技术干货9:deviceInfo 设备信息获取与位置提醒 APP 整合
harmonyos
BlackWolfSky4 小时前
鸿蒙暂未归类知识记录
华为·harmonyos
L、2186 小时前
Flutter 与开源鸿蒙(OpenHarmony):跨平台开发的新未来
flutter·华为·开源·harmonyos
L、2187 小时前
Flutter 与 OpenHarmony 深度融合实践:打造跨生态高性能应用(进阶篇)
javascript·flutter·华为·智能手机·harmonyos