关键词:鸿蒙、水印、Watermark、页面、触摸问题
注:本期文章同样适用 OpenHarmony 的开发
在app开发过程中时常会出现敏感信息页面,为保护信息安全和及时的数据追踪,通常会采用给页面加水印的形式,那么本期文章会介绍如何在鸿蒙应用中实现页面水印的功能。
本期文章代码比较简单,核心逻辑为 ①对触摸事件的穿透控制,②组件 .overlay() 浮层的使用,可自行修改 Watermark() 构建函数代码调整至自己业务所适合的样式。
触摸测试控制可参考官方文档:文档中心
效果如下:
完整代码:
如下代码使用 Canvas 画布绘制水印,计算当前屏幕展示水印个体个数进行渲染。当然也可以自行使用网格或其他布局实现效果。overlay 浮层也可替换使用 Stack() 层叠布局,本质在上方覆盖一层文本浮层即可。
需要注意的是:浮层是在跟容器组件的上层,所以需要给上层组件设置 .hitTestBehavior(HitTestMode.Transparent) 属性,穿透触摸事件至根容器,避免触摸事件被水印层拦截。
@Entry
@Component
struct Index {
@State message: string = '你好鸿蒙 Hello Harmony,这是一段普通文本测试水印效果';
private settings: RenderingContextSettings = new RenderingContextSettings(true);
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
// 水印容器宽高
private water1wh: number = 140
/**
* 水印构造器
* @param waterText 水印文本
* @param fontSize 字号
* @param fontColor 颜色
*/
@Builder
Watermark2(waterText: string, fontSize: string, fontColor: string) {
Canvas(this.context)
.width("100%")
.height("100%")// 设置触摸测试控制,不影响跟节点触摸
.hitTestBehavior(HitTestMode.Transparent)
.onReady(() => {
this.context.fillStyle = fontColor;
this.context.font = fontSize;
this.context.textAlign = "center"; // 单个容器中垂直居中
// 计算屏幕中可摆放多少个水印个体,遍历渲染
for (let i = 0; i < this.context.width / this.water1wh; i++) {
this.context.translate(this.water1wh, 0);
let j = 0;
for (; j < this.context.height / this.water1wh; j++) {
this.context.rotate(-Math.PI / 180 * 30);
// 设置文本偏移
this.context.fillText(waterText, -(this.water1wh / 2), -(this.water1wh / 2));
this.context.rotate(Math.PI / 180 * 30);
this.context.translate(0, this.water1wh);
}
this.context.translate(0, -this.water1wh * j);
}
})
}
build() {
// overlay 浮层用法
RelativeContainer() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.id("Text1")
.onClick(() => {
console.log("luvi > 触摸测试")
})
.alignRules({
middle: { anchor: "__container__", align: HorizontalAlign.Center },
center: { anchor: "__container__", align: VerticalAlign.Center }
})
.id("base")
}
// 在当前组件上,增加叠加自定义组件以作为该组件的浮层
.overlay(this.Watermark2("20241012 张三", "15vp", "#2a000000"))
.height('100%')
.width('100%')
// 层叠布局用法
// Stack() {
// RelativeContainer() {
// Text(this.message)
// .fontSize(50)
// .fontWeight(FontWeight.Bold)
// .id("Text1")
// .onClick(() => {
// console.log("luvi > 触摸测试")
// })
// .alignRules({
// middle: { anchor: "__container__", align: HorizontalAlign.Center },
// center: { anchor: "__container__", align: VerticalAlign.Center }
// })
// .id("base")
// }
// .height('100%')
// .width('100%')
//
// this.Watermark2("20241012 张三", "15vp", "#2a000000")
// }
}
}
水了水了...