明水印
1. 背景圖
通過css的background-image加載背景圖
2. canvas+background水印
前端水印實現思路與示例代碼
一、核心實現思路
-
Canvas動態生成水印
通過Canvas繪制文本或圖案,將生成的圖像轉為Base64格式,作為背景圖重復平鋪到目標元素上。例如: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'); }
-
防篡改機制
- 使用
MutationObserver
監聽DOM變化,若水印元素被刪除則重新注入 - 禁止控制臺操作:禁用右鍵菜單、屏蔽開發者工具快捷鍵
document.addEventListener('contextmenu', e => e.preventDefault());
- 使用
-
容器綁定
將水印作為獨立圖層覆蓋在目標內容上方,通過CSS確保全屏狀態仍可見:.watermark-container {position: relative; } .watermark-layer {position: absolute;pointer-events: none;z-index: 9999;background: url('data:image/png;base64,...'); }
二、完整示例代碼
<!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 = 200canvas.height = 150ctx.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 = 0watermark.style.bottom = 0watermark.style.right = 0watermark.style.left = 0watermark.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等可變信息增強追蹤能力:const dynamicText = `${username} ${new Date().toLocaleString()}`;
-
樣式優化
- 使用
background-repeat: repeat
平鋪 - 調整
rgba
透明度值平衡可見性與內容遮擋
- 使用
-
跨框架實現
Vue/React可通過高階組件封裝水印邏輯,例如:const withWatermark = (Component) => (props) => (<div className="watermark-wrapper"><Component {...props} /></div> )
純canvas水印
<!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水印
<!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>