news 2026/5/13 19:08:19

鸿蒙全局安全水印组件实践:支持动态更新、全局生效、自定义样式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙全局安全水印组件实践:支持动态更新、全局生效、自定义样式

1、需求背景


很多企业内部应用,都会有这样的需求:

效果如下:


2、核心思路


本方案采用纯 ArkUI 水印覆盖方案,核心实现思路:



3、方案特点



4、项目地址


GitHub:HarmonyWatermark

ohpm:@ericbyliang/lib_watermark


5、使用方法


5.1 安装组件

安装 ohpm 包:

ohpm install @ericbyliang/lib_watermark


5.2 页面使用

全局安全水印组件加入顶级根界面即可,永远处于页面最上层:

import { setWatermarkText, WatermarkComponent } from '@ericbyliang/lib_watermark';
build() { Root() { .... WatermarkComponent() } }

5.3 全局设置水印文本

import { setWatermarkText, WatermarkComponent } from '@ericbyliang/lib_watermark';
// 设置水印,比如登录后,设置一次即可
setWatermarkText("林俊杰 2000022");
// 取消水印,比如在登录页面
setWatermarkText("");


这意味着:

5.4 动态设置水印文本&自定义水印样式

组件支持动态传参:

WatermarkComponent({ waterText:'周杰伦 1000001', textSize: 14, textColor: 'rgba(80,80,80, 0.01)', angle: -20, grapX: 120, grapY: 180 })


支持参数:

参数

说明

waterText

水印文本

textSize

字体大小(rpx)

textColor

水印颜色/透明度

angle

旋转角度

gapX

水平间距

gapY

垂直间距


6、核心代码讲解

1、组件首先通过 emitter 监听全局水印事件,实现:

2、构建一个且唯一的全屏透明覆盖层,保证水印永远处于页面最上层

import { emitter } from "@kit.BasicServicesKit"; import { EventType } from "./EventType"; @Component export struct WatermarkComponent { @Prop waterText?: string @Prop textSize: number = 14 @Prop textColor: string = 'rgba(80,80,80,0.08)' @Prop angle: number = -20 @Prop gapX: number = 120 @Prop gapY: number = 180 aboutToAppear(): void { emitter.on(EventType.WaterMarkEvent, (eventData: emitter.EventData) => { const waterText = eventData?.data?.waterText as string //全局安全水印 this.waterText = waterText }); } aboutToDisappear(): void { emitter.off(EventType.WaterMarkEvent) } build() { // 全屏水印层 Stack() { // 在这里放重复水印 if (this.waterText) { this.renderWatermark(); } } .width('100%') .height('100%') .align(Alignment.Center) .backgroundColor(Color.Transparent) .hitTestBehavior(HitTestMode.Transparent) // 穿透点击 .zIndex(9999); } // 绘制多个水印 @Builder private renderWatermark() { Column() { ForEach(Array.from({ length: 100 }), (_: number, index: number) => { Row() { ForEach(Array.from({ length: 30 }), () => { Text(this.waterText) .fontSize(this.textSize) .fontColor(this.textColor) // 透明度 .padding({ right: this.gapX, bottom: this.gapY}) } ) }.rotate({ angle: this.angle, }).margin({left:index % 2 == 0?0:(this.textSize * (this.waterText||'').length) / 2}) }) }.margin({top:-100}) } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 19:05:08

对比按需计费与TokenPlan在长期项目中的成本体感差异

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比按需计费与TokenPlan在长期项目中的成本体感差异 在长期运行的AI项目中,成本控制是一个持续优化的过程。不同的计费…

作者头像 李华
网站建设 2026/5/13 19:03:24

ARM-2D:为Cortex-M GUI注入“灵魂”的2D加速库

1. 当温控面板卡成PPT:Cortex-M的GUI困境 我至今记得第一次调试某品牌智能温控器的经历。那块3.5英寸的触摸屏上,温度调节动画像老式幻灯片一样一帧一帧跳动,滑动菜单时甚至能看到像素级的拖影。拆开外壳后更让人震惊——主控芯片居然是颗Cor…

作者头像 李华