明水印
1. 背景图
通过css的background-image加载背景图
2. canvas+background水印
前端水印实现思路与示例代码
一、核心实现思路
-
Canvas动态生成水印
通过Canvas绘制文本或图案,将生成的图像转为Base64格式,作为背景图重复平铺到目标元素上。例如:
javascriptfunction createWatermark(text) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = 200; canvas.height = 150; ctx.font = '12px Arial'; ctx.fillStyle = 'rgba(200,200,200,0.2)'; ctx.rotate(-30 * Math.PI / 180); // 倾斜角度 ctx.fillText(text, 10, 100); return canvas.toDataURL('image/png'); }
-
防篡改机制
- 使用
MutationObserver
监听DOM变化,若水印元素被删除则重新注入 - 禁止控制台操作:禁用右键菜单、屏蔽开发者工具快捷键
javascriptdocument.addEventListener('contextmenu', e => e.preventDefault());
- 使用
-
容器绑定
将水印作为独立图层覆盖在目标内容上方,通过CSS确保全屏状态仍可见:
css.watermark-container { position: relative; } .watermark-layer { position: absolute; pointer-events: none; z-index: 9999; background: url('data:image/png;base64,...'); }
二、完整示例代码
html
<!DOCTYPE html>
<html>
<body>
<style>
.watermark-container {
position: relative;
}
.watermark-layer {
position: absolute;
pointer-events: none;
z-index: 9999;
background: url('data:image/png;base64,...');
}
</style>
<div id="content">需要保护的内容</div>
<script>
function createWatermark (text) {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = 200
canvas.height = 150
ctx.font = '12px Arial'
ctx.fillStyle = 'rgba(200,200,200,0.2)'
ctx.rotate(-30 * Math.PI / 180) // 倾斜角度
ctx.fillText(text, 10, 100)
return canvas.toDataURL('image/png')
}
function initWatermark (text = '机密文件') {
const watermark = document.createElement('div')
watermark.style.backgroundImage = `url(${createWatermark(text)})`
watermark.style.position = 'fixed'
watermark.style.top = 0
watermark.style.bottom = 0
watermark.style.right = 0
watermark.style.left = 0
watermark.style.pointerEvents = 'none'
// 防删除监听
const observer = new MutationObserver(mutations => {
if (!document.contains(watermark)) {
document.body.appendChild(watermark)
}
})
observer.observe(document.body, { childList: true })
document.body.appendChild(watermark)
}
initWatermark('严禁复制');
</script>
</body>
</html>
三、注意事项
-
动态水印
可添加时间戳、用户ID等可变信息增强追踪能力:
javascriptconst dynamicText = `${username} ${new Date().toLocaleString()}`;
-
样式优化
- 使用
background-repeat: repeat
平铺 - 调整
rgba
透明度值平衡可见性与内容遮挡
- 使用
-
跨框架实现
Vue/React可通过高阶组件封装水印逻辑,例如:
jsconst withWatermark = (Component) => (props) => ( <div className="watermark-wrapper"> <Component {...props} /> </div> )
纯canvas水印
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas水印示例</title>
<style>
.watermark {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
pointer-events: none;
opacity: 0.2;
}
</style>
</head>
<body>
<canvas id="watermarkCanvas" class="watermark"></canvas>
<div>
<h1>内容区域</h1>
<p>这是需要加水印的内容</p>
</div>
<script>
window.onload = function() {
var canvas = document.getElementById('watermarkCanvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var text = '水印文本';
var width = canvas.width;
var height = canvas.height;
ctx.font = '30px Arial';
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// 旋转并重复绘制水印文本
for (var x = 0; x < width; x += 200) {
for (var y = 0; y < height; y += 200) {
ctx.save();
ctx.translate(x, y);
ctx.rotate(- Math.PI / 4);
ctx.fillText(text, 0, 0);
ctx.restore();
}
}
};
</script>
</body>
</html>
svg水印
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVG水印示例</title>
<style>
.watermark {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
pointer-events: none;
opacity: 0.2;
}
</style>
</head>
<body>
<div class="watermark">
<svg width="100%" height="100%">
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="30" fill="rgba(0,0,0,0.1)" transform="rotate(-45, 50, 50)">水印文本</text>
</svg>
</div>
<div>
<h1>内容区域</h1>
<p>这是需要加水印的内容</p>
</div>
</body>
</html>