客户从事房产中介行业,对房源及客户的信息保密性要求较高,希望能实现以登录用户手机号后四位的动态重复水印。
网页中水印可以通过 css 背景图方式实现,而微信小程序环境却无法顺利运行。最终我选择使用 canvas 的方式实现。
示例代码
util.js
/*
页面水印,页面中要有id="watermarkCanvas",type="2d"的canvas
<canvas class="watermark" canvas-id="watermarkCanvas" id="watermarkCanvas" type="2d"></canvas>
*/
export const watermark = (context, canvasId = "watermarkCanvas") => {
const user = uni.getStorageSync('user');
//console.log(user);
//console.log('watermark');
if (!user || !user.phone) return;
// 获取手机号后四位
const text = user.phone.slice(-4);
const query = uni.createSelectorQuery().in(context);
query.select(`#${canvasId}`)
.fields({ node: true, size: true })
.exec((res) => {
if (res[0] && res[0].node) {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const dpr = uni.getSystemInfoSync().pixelRatio;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
ctx.scale(dpr, dpr);
const textWidth = 100;
const textHeight = 50;
const gap = 50;
ctx.font = '14px Arial';
ctx.fillStyle = 'rgba(85, 170, 255, 0.5)';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
for (let x = 0; x < canvas.width; x += textWidth + gap) {
for (let y = 0; y < canvas.height; y += textHeight + gap) {
ctx.save();
ctx.translate(x + textWidth / 2, y + textHeight / 2);
ctx.rotate(-30 * Math.PI / 180);
ctx.fillText(text, 0, 0);
ctx.restore();
}
}
} else {
console.error('Failed to get canvas node.');
}
});
}
room.vue
<template>
<view class="watermark-container">
<!-- 隐藏的 Canvas 元素 -->
<canvas class="watermark" canvas-id="watermarkCanvas" id="watermarkCanvas" type="2d"></canvas>
<view class="container">
<!--页面主体内容-->
</view>
</view>
</template>
<script>
import { watermark } from '@/utils/util'
onReady() {
watermark(this)
},
</script>
<style>
.watermark-container {
position: relative;
width: 100%;
min-height: 100vh;
height: 100%; /*确保容器有高度 */
background-size: auto; /* 确保背景图片按原尺寸显示 */
}
.watermark {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
opacity: 0.5;
z-index: -1;
}
</style>

注意事项
- 页面中要有 id=”watermarkCanvas”,type=”2d” 的 canvas 元素,注意必须设置 type=”2d”。
- .watermark-container 要设置 min-height: 100vh;,否则水印可能只加载到页面内容结束位置。
- 水印方法要在 onReady 中调用,因为 onLoad 或者 onShow 中,页面结构可能还没加载完。
- 如果页面数据列表动态加载导致页面变长,那么需要定期监听页面高度变化重新调用 watermark 方法。