回复
HarmonyOS 6 页面水印最佳实践:看得到、碰不到 原创
全栈若城
发布于 2025-10-27 22:51
浏览
1收藏
@toc
引言
本文将带你在应用页面中叠加一层不干扰操作的文字水印,实现“可见但不抢事件”的效果。我们通过 Canvas 绘制水印,并利用容器的 .overlay() 将其覆盖在内容之上,从而兼顾视觉呈现与交互体验。
适用场景
- 需要在页面中展示防泄露标记(如用户名、时间戳、企业标识)。
- 要求保持按钮点击、列表滑动等正常交互。
- 希望以低侵入方式覆盖全页面内容。
实现思路总览
- 使用
Canvas作为画布绘制斜体、重复排列的文字水印。 - 通过
.overlay()将画布叠加到页面内容上。 - 设置
HitTestMode.Transparent使水印不拦截用户事件(点击、滑动)。
效果演示

叠加水印后,点击按钮仍有正常交互反馈。
实现步骤
1. Canvas 画布与透明命中
定义相关变量 :
@State waterMarkText: string = '';
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
页面加载时获取水印相关内容:
aboutToAppear(): void {
const context = this.getUIContext().getHostContext();
if (context) {
this.waterMarkText = context.resourceManager.getStringSync($r('app.string.watermark'));
}
}
2. 水印界面绘制
核心在于斜切、平铺与行列遍历 :
@Builder
waterMark() {
Canvas(this.context)
.width('100%')
.height('100%')
.hitTestBehavior(HitTestMode.Transparent)
.onReady(() => {
this.context.fillStyle = '#000000';
this.context.font = '14vp';
this.context.textAlign = 'start';
let posY = 0;
let row = 0;
while (posY < this.context.height) {
this.context.resetTransform();
posY = WATERMARK_HEIGHT * row;
this.context.translate(0, posY);
this.context.rotate(-30 * DEGREE);
for (let i = 0; i <= Math.ceil(this.context.width / WATERMARK_WIDTH); i++) {
this.context.fillText(this.waterMarkText, 0, WATERMARK_HEIGHT / 2);
this.context.translate(WATERMARK_WIDTH, 0);
posY -= WATERMARK_WIDTH * Math.sin(30 * DEGREE);
}
this.context.rotate(30 * DEGREE);
row++;
}
});
}
3. 主体界面使用水印效果
将水印通过 .overlay() 叠加到页面内容上 :
@Builder
pageContent() {
Column() {
Text('水印效果展示界面')
Image($r('app.media.222')).width('100%').height(400)
Button('点击按钮').onClick(() => {
promptAction.showToast({
message: '点击了按钮',
duration:3000
})
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
.overlay(this.waterMark());
}
在页面中直接使用该 Builder 布局 :
build() {
Navigation() {
this.pageContent();
}
.height('100%')
.width('100%')
.hideToolBar(true)
.backgroundColor("#ffffff");
}
相关物料
在主页面中引入如下常量 :
import { DEGREE, WATERMARK_HEIGHT, WATERMARK_WIDTH } from '../constants/Constants';
其内容如下 :
export const WATERMARK_HEIGHT = 100;
export const WATERMARK_WIDTH = 160;
export const DEGREE = Math.PI / 180;
水印文案在 string.json 中定义:

总结
通过 Canvas + .overlay() + HitTestMode.Transparent 的组合,我们能够在不影响用户交互的前提下,为页面添加可控、可复用的文字水印。 简单明了,写的有些着急了,不过代码可以直接拿去使用哦, 下课~~
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
赞
2
收藏 1
回复
相关推荐



















