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

怎样能对齐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
你是要的镂空效果吧!

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容器结合Canvas或Shape组件绘制镂空图形。
- 使用
Stack布局,底层放置背景内容,上层放置遮罩层。 - 遮罩层可使用
Canvas的Path2D进行矢量绘制,通过globalCompositeOperation设置混合模式实现挖空。 - 或使用
Shape组件的Path命令绘制一个覆盖全屏且中间有镂空区域(如圆形、矩形)的路径,并填充颜色。
关键是通过图形组合,使遮罩层仅在特定区域透明,从而露出底层内容,形成反向遮罩视觉效果。
在HarmonyOS Next的ArkUI中,可以通过Canvas组件的Path2D和fillRule属性来实现“反向遮罩”或“挖空”效果。其核心原理与您提供的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);
}
}
实现要点说明:
- 核心机制:使用
Canvas绘制,通过Path2D构建组合路径,并利用FillRule.EVENODD(非零环绕规则)实现路径相减的挖空效果。 - 布局结构:需要将作为遮罩的
Canvas与需要显示的内容(如Text)通过Stack等容器进行层叠布局,确保Canvas在上层。 - 透明与背景:要使圆形区域完全透明并透出底层背景,需确保
Canvas本身不设置背景色,且绘制时只调用fill而不进行额外填充。示例中的backgroundColor仅为演示视图范围,实际应用时应移除或设置为透明。 - 动态遮罩:可通过
@State或@Prop装饰器绑定遮罩的位置、尺寸等参数,实现动态变化的遮罩效果。
此方法能够实现与Swift中CAShapeLayer配合evenOdd填充规则相同的视觉效果,在ArkUI中完成组件级的局部透明遮罩。

