HarmonyOS鸿蒙Next中使用clipShape进行裁剪后,borderRadius无法生效怎么处理

HarmonyOS鸿蒙Next中使用clipShape进行裁剪后,borderRadius无法生效怎么处理

【问题现象】

对容器组件使用clipShape进行裁剪后,再使用borderRadius对被裁剪容器设置圆角时无法生效,如下图所示效果:

点击放大

【背景知识】

1. 设置组件圆角的方法

1.1 borderRadius

borderRadius属性用于设置组件边框的圆角,可以同时设置四个角,也可以分别对四个角的圆角大小进行设置。为了避免因子组件尺寸大于组件,导致子组件覆盖圆角,可以搭配属性clip使用。

1.2 clipShape

clipShape属性用于对组件进行形状裁剪,通过传入不同的组件类型,将组件裁剪为对应的形状。

2. 绘制圆角的方法

2.1 Path

  • Path是路径绘制组件,可以通过commands属性绘制出需求的形状,包括圆角(圆角多边形)。
  • 关于贝塞尔曲线和控制点的关系:由一组控制点的向量决定,给定的控制点按顺序连接构成控制多边形。

2.2 Path和clipShape的区别

  • Path是绘制组件,通过设置路径绘制出需求的形状,其填充区域一般是颜色而非图片。
  • clipShape是通用属性,通过设置不同组件类型对组件进行裁剪,裁剪后的形状背景是组件的一部分。比如对Image组件进行裁剪,裁剪后的形状背景是该Image组件图片的一部分。

【定位思路】

borderRadius属性从规格上是相对于组件的大小而言的,当组件同时设置borderRadius和clipShape时,borderRadius会首先生效,对整个组件设置圆角效果,然后clipShape裁剪效果会覆盖borderRadius的圆角效果,导致borderRadius不生效。

【解决方案】

1. 对裁剪的组件设置圆角

使用clipShape对组件进行裁剪时,根据需求,对需设置为圆角的角进行圆角裁剪处理。被裁剪的组件可以是容器组件(如Column、Row等)或Image组件。

注意

不能设置两次clipShape属性进行多次裁剪,否则最后一个clipShape的裁剪将会覆盖前面的clipShape裁剪。

以下示例对Image组件设置clipShape属性,使用PathShape形状描述组件被裁剪后的形状。

代码示例如下:

@Entry
@Component
struct ClipFilletCorner {
  // 定义PathShape绘制的路线
  commands1:string=`M0 0 L${vp2px(300)} 0 L${vp2px(300)}${vp2px(200)} L0 ${vp2px(200)} Z`
  commands2:string='M0 0 L600 0 L600 300 Z'
  commands3:string='M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z'
  @State shapeNum:number=1

  build() {
    Column() {
      // 待裁剪图片
      Image($r('app.media.startIcon'))
        .height(200)
        .width(300)
        .margin({top:10, bottom:10})
        .objectFit(ImageFit.Cover)
        .borderRadius({topRight:5})
        .clipShape(newPathShape().commands(this.shapeNum===1?this.commands1:this.shapeNum===2?this.commands2:this.commands3))

      // 定义命令控制器
      Row() {
        Button('Original')
          .type(ButtonType.Capsule)
          .width(80)
          .onClick(() => {
            this.shapeNum=1
          })

        Button('Triangle')
          .type(ButtonType.Capsule)
          .width(80)
          .onClick(() => {
            this.shapeNum=2
          })

        Button('Irregular')
          .type(ButtonType.Capsule)
          .width(80)
          .onClick(() => {
            this.shapeNum=3
          })
      }.width(300)
      .height(100)
      .justifyContent(FlexAlign.SpaceEvenly)
    }.width('100%')
    .height('40%')
    .backgroundColor(Color.Orange)
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

效果图:

点击放大

2. 绘制带圆角的组件

某些场景下可能需要绘制出带有圆角或其他形状的图形,此时可以使用Path组件进行绘制。

代码示例如下:

@Entry
@Component
struct PathFilletCorner {
  build() {
    Row() {
      // 绘制上一示例的带圆角的不规则图形
      Path()
        .fill(Color.Pink)
        .stroke(Color.Blue)
        .commands('M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z')

      // 绘制带圆角的三角形
      Path()
        .fill(Color.Brown)
        .commands('M120 150 L480 150 S600 150 480 90 L360 30 S300 0 240 30 L120 90 S0 150 120 150Z')
    }.width('100%')
    .height('40%')
    .backgroundColor(Color.Orange)
    .justifyContent(FlexAlign.SpaceEvenly)
    .alignItems(VerticalAlign.Center)
  }
}

效果图:

点击放大

【总结】

  • 当对组件进行圆角设置时,可以使用borderRadius属性。
  • 当需要对裁剪后的组件进行圆角设置时,borderRadius属性的效果会被覆盖,可以在使用clipShape对组件进行裁剪时,使用PathShape形状按需要进行形状和圆角的裁剪。
  • 当需要绘制带圆角的图形时,可以使用Path组件进行绘制。

更多关于HarmonyOS鸿蒙Next中使用clipShape进行裁剪后,borderRadius无法生效怎么处理的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于HarmonyOS鸿蒙Next中使用clipShape进行裁剪后,borderRadius无法生效怎么处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,使用clipShape进行裁剪后,borderRadius无法生效的原因

在HarmonyOS鸿蒙Next中,使用clipShape进行裁剪后,borderRadius无法生效的原因是clipShape的裁剪效果会覆盖borderRadius的圆角效果。解决方案如下:

1. 对裁剪的组件设置圆角

在使用clipShape进行裁剪时,直接通过PathShape形状描述组件被裁剪后的形状,并在PathShape中设置所需的圆角。例如:

@Entry
@Component
struct ClipFilletCorner {
  commands1: string = `M0 0 L${vp2px(300)} 0 L${vp2px(300)}${vp2px(200)} L0 ${vp2px(200)} Z`
  commands2: string = 'M0 0 L600 0 L600 300 Z'
  commands3: string = 'M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z'
  @State shapeNum: number = 1

  build() {
    Column() {
      Image($r('app.media.startIcon'))
        .height(200)
        .width(300)
        .margin({top:10, bottom:10})
        .objectFit(ImageFit.Cover)
        .borderRadius({topRight:5})
        .clipShape(newPathShape().commands(this.shapeNum===1?this.commands1:this.shapeNum===2?this.commands2:this.commands3))
    }
  }
}

2. 绘制带圆角的组件

如果需要绘制带圆角的图形,可以使用Path组件进行绘制。例如:

@Entry
@Component
struct PathFilletCorner {
  build() {
    Row() {
      Path()
        .fill(Color.Pink)
        .stroke(Color.Blue)
        .commands('M0 100 S0 0 100 0 H300 S400 0 400 100 V300 S400 400 300 400 H200Z')
      Path()
        .fill(Color.Brown)
        .commands('M120 150 L480 150 S600 150 480 90 L360 30 S300 0 240 30 L120 90 S0 150 120 150Z')
    }
  }
}

通过以上方法,可以在使用clipShape进行裁剪时实现圆角效果。

回到顶部