HarmonyOS鸿蒙Next中ArkUI如何实现“反向遮罩”效果?

HarmonyOS鸿蒙Next中ArkUI如何实现“反向遮罩”效果? 怎么实现在任意 Component 上加一个反向遮罩呢?例如给Text加一个圆形遮罩,预期效果是:这个圆形区域内是纯透明的,其他区域才会渲染文本内容。 cke_749.png

怎样能对齐Swift中的如下实现,达到类似的样式效果? extension UIView {

/// 给 view 添加一个可变的挖空 mask(挖掉自身 rect 内的区域) func applyHole(rect: CGRect, cornerRadius: CGFloat = 0) { let path = UIBezierPath(rect: bounds) let holePath = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius) path.append(holePath) path.usesEvenOddFillRule = true

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
maskLayer.fillRule = .evenOdd
self.layer.mask = maskLayer

} }

二编:补充一下想要的效果示意图👇圆形区域是全透明的,不是单纯盖一个白色的Circle。例如有背景图的场景,圆形是能透过去显示背景图的。 图片


更多关于HarmonyOS鸿蒙Next中ArkUI如何实现“反向遮罩”效果?的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

你是要的镂空效果吧!

cke_441.png

Column({ space: 10 }) {
  Stack() {
    Text('鸿蒙镂空效果')
      .fontSize(40)
      .fontWeight(FontWeight.Bold)
      .blendMode(BlendMode.XOR, BlendApplyType.OFFSCREEN)
  }
  .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN)
  .backgroundColor(Color.Black)
  .width('100%').height(80)
  Stack() {
    Text('鸿蒙镂空效果')
      .fontSize(40)
      .fontWeight(FontWeight.Bold)
      .fontColor(Color.Red)
    Circle({ width: 35, height: 35 })
      .blendMode(BlendMode.XOR, BlendApplyType.OFFSCREEN)
  }
  .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN)
  .backgroundColor(Color.Black)
  .width('100%').height(80)
  Stack() {
    Text('鸿蒙镂空效果')
      .fontSize(40)
      .fontWeight(FontWeight.Bold)
      .fontColor(Color.Red)
    Circle({ width: 35, height: 35 })
      .clipShape(new CircleShape({width:35,height:35}))
      .blendMode(BlendMode.CLEAR, BlendApplyType.OFFSCREEN)
  }
  .blendMode(BlendMode.SRC_OVER, BlendApplyType.OFFSCREEN)
  .width('100%').height(80)
}.width('100%')
.height('100%')
.backgroundImage($r('app.media.fig1'))
.backgroundImageSize({width:'100%',height:'35%'})

更多关于HarmonyOS鸿蒙Next中ArkUI如何实现“反向遮罩”效果?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


是的是的!就是这样的效果!谢谢!

@Entry
@Component
struct MyTest {
  build() {
    Column() {
      Stack({ alignContent: Alignment.Center }) {
        Text('CXHandleTypeGeneric')
          .width('100%')
          .height('100%')
          .textAlign(1)
        Circle()
          .width(20)
          .height(20)
          .fill(Color.Red)
      }
      .width('100%')
      .height(16)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

不知道您要的是不是这个效果呢

不是不是,可以看下我编辑补充的示意图,不是简单盖一个视图上去~,

在ArkUI中实现反向遮罩效果,主要使用Stack容器结合CanvasShape组件绘制镂空图形。

  1. 使用Stack布局,底层放置背景内容,上层放置遮罩层。
  2. 遮罩层可使用CanvasPath2D进行矢量绘制,通过globalCompositeOperation设置混合模式实现挖空。
  3. 或使用Shape组件的Path命令绘制一个覆盖全屏且中间有镂空区域(如圆形、矩形)的路径,并填充颜色。

关键是通过图形组合,使遮罩层仅在特定区域透明,从而露出底层内容,形成反向遮罩视觉效果。

在HarmonyOS Next的ArkUI中,可以通过Canvas组件的Path2DfillRule属性来实现“反向遮罩”或“挖空”效果。其核心原理与您提供的Swift代码类似:创建一个覆盖整个组件区域的大路径,然后追加一个作为“洞”的路径(如圆形),并应用'evenodd'填充规则。

以下是实现给Text组件添加圆形反向遮罩的关键代码示例:

import { Canvas, Text, Path2D, FillRule } from '@kit.ArkGraphics2D';

@Entry
@Component
struct HoleMaskExample {
  build() {
    Column() {
      // 1. 创建Canvas作为遮罩层
      Canvas(this.onDraw)
        .width('100%')
        .height(200)
        .backgroundColor('#F0F0F0') // 此处仅为示例背景色,实际应透出底层内容

      // 2. 被遮罩的文本内容,通过布局叠在Canvas下方
      Text('Hello HarmonyOS')
        .fontSize(20)
        .fontColor('#000000')
        .position({ x: 0, y: 0 }) // 需要与Canvas位置匹配
    }
  }

  // Canvas绘制函数
  onDraw = (ctx: CanvasRenderingContext2D) => {
    const width = 394; // 匹配Canvas宽度
    const height = 112; // 匹配Canvas高度
    const centerX = width / 2;
    const centerY = height / 2;
    const radius = 40; // 圆形遮罩半径

    // 创建主路径(整个区域)
    const path = new Path2D();
    path.rect(0, 0, width, height);

    // 创建圆形路径(作为挖空区域)
    const holePath = new Path2D();
    holePath.arc(centerX, centerY, radius, 0, Math.PI * 2);

    // 追加圆形路径,形成组合路径
    path.addPath(holePath);

    // 设置填充规则为'evenodd'实现挖空效果
    ctx.fill(path, FillRule.EVENODD);
  }
}

实现要点说明:

  1. 核心机制:使用Canvas绘制,通过Path2D构建组合路径,并利用FillRule.EVENODD(非零环绕规则)实现路径相减的挖空效果。
  2. 布局结构:需要将作为遮罩的Canvas与需要显示的内容(如Text)通过Stack等容器进行层叠布局,确保Canvas在上层。
  3. 透明与背景:要使圆形区域完全透明并透出底层背景,需确保Canvas本身不设置背景色,且绘制时只调用fill而不进行额外填充。示例中的backgroundColor仅为演示视图范围,实际应用时应移除或设置为透明。
  4. 动态遮罩:可通过@State@Prop装饰器绑定遮罩的位置、尺寸等参数,实现动态变化的遮罩效果。

此方法能够实现与Swift中CAShapeLayer配合evenOdd填充规则相同的视觉效果,在ArkUI中完成组件级的局部透明遮罩。

回到顶部