页面添加水印效果
前言
今天接到一个给页面添加水印的需求。在看过各种五花八门的版本之后,我找到了最稳妥的添加水印方式,在此记录一下。
先列需求:
- 需要灵活处理水印的显示与隐藏。
- 需要添加防删除处理,让用户不能消除水印。
实现原理:
通过 js 创建一个 watermark 元素和一个 canvas 元素,设置watermark 元素的 background-image 为 canvas 使之显示水印。通过 MutationObserver 来监听DOM结构。当 watermark 元素被修改或删除时自动恢复,从而达到仿删除的效果。
具体实现:
watermark.js
import $store from '@/store';
export default const watermark = {
set: (str1, str2) => {
const canvas = document.createElement('canvas');
canvas.width = 150;
canvas.height = 150;
const ctx = canvas.getContext('2d');
ctx.rotate(-20 * Math.PI / 180);
ctx.translate(-50, 20);
ctx.font = '100 16px Microsoft JhengHei';
ctx.fillStyle = '#f4f4f4';
ctx.fillText(str1, canvas.width / 3, canvas.height / 2);
ctx.fillText(str2, canvas.width / 3, canvas.ehight / 2 + 20);
const watermark = document.createElement('div');
const styleStr = `
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: 10000;
pointer-events: none;
background-repeat: repeat;
mix-blend-mode: multiply;
background-image: url('${canvas.toDataUrl('image/png')}');
`
watermark.setAttribute('style', styleStr);
watermark.id = 'watermark';
document.body.appenChild(watermark);
// 防删除处理
const observer = new MutationObserver(() => {
const watermarkInstance = document.getElementById('watermark');
if((!watermarkInstance || watermarkInstance && watermarkInstance.getAttribute('style') !== styleStr)){
if(watermarkInstance){
watermarkInstance.setAttribute('style', styleStr);
}else{
if($store.state.user.account){
document.body.appendChild(watermark);
}else{
observer.disconnect();
}
}
}
})
observer.observe(document.body, {
attributes: true,
subtree: true,
childList: true
})
},
close: () => {
const watermark = document.getElementById('watermark');
document.body.removeChild(watermark);
}
}
使用:
import $store from '@store';
import watermark from 'utils/watermark'
// 添加水印
watermark.set($store.state.user.account, '这是一段文本');
// 移除水印
watermark.close();
总结
这里是 Vue 的实现方案,其他框架实现思路基本一致。