怎么添加水印效果_html网页全屏防盗水印代码

作者:袖梨 2026-06-28
真正可用的水印必须用 Canvas + 定位遮罩实现,因其能覆盖所有内容层、随滚动实时重绘、文字不可选不可复制;CSS background-image 方案因截图、打印、禁用样式即失效且无法滚动覆盖而无效。

水印为什么不能只靠 CSS background-image

直接用 background-image 加一张带文字的 PNG,看似简单,但实际无效:截图、打印、开发者工具禁用样式后水印立刻消失;更关键的是,它无法随页面滚动动态覆盖内容,尤其在长页面中,水印只固定在视口初始位置,中间大片区域完全空白。

真正可用的水印必须满足三个条件:覆盖所有内容层、随滚动实时重绘、文字不可选不可复制。这只能靠 Canvas + 定位遮罩实现。

用 Canvas 动态绘制全屏水印的最小可行代码

核心思路是创建一个 position: fixed 的全屏 <canvas>,用 ctx.fillText() 在多个偏移位置重复绘制文字,并设置透明度和旋转角度。关键不是画一次,而是按网格密度反复绘制。

  • canvas 插入 <body> 底部,z-index 设为 -1 不干扰操作,但需加 pointer-events: none 防止遮挡点击
  • 字体大小建议用 px 单位(如 24px),避免 rem/vw 在缩放时失真
  • 旋转角度推荐 -25-35 度,太小显不出斜纹感,太大影响阅读识别
  • 文字透明度控制在 0.08–0.12,再低看不见,再高干扰阅读
<canvas id="watermark" style="position:fixed;top:0;left:0;width:100%;height:100%;z-index:-1;pointer-events:none;"></canvas><script>const canvas = document.getElementById('watermark');const ctx = canvas.getContext('2d');function drawWatermark() {  const dpr = window.devicePixelRatio || 1;  canvas.width = window.innerWidth * dpr;  canvas.height = window.innerHeight * dpr;  ctx.scale(dpr, dpr);  ctx.font = '24px Microsoft YaHei';  ctx.fillStyle = 'rgba(0,0,0,0.1)';  ctx.textAlign = 'center';  ctx.textBaseline = 'middle';  const spacing = 120;  const rotate = -30;  for (let x = -spacing; x < window.innerWidth + spacing; x += spacing) {    for (let y = -spacing; y < window.innerHeight + spacing; y += spacing) {      ctx.save();      ctx.translate(x + spacing/2, y + spacing/2);      ctx.rotate(rotate * Math.PI / 180);      ctx.fillText('机密-禁止转载', 0, 0);      ctx.restore();    }  }}drawWatermark();window.addEventListener('resize', drawWatermark);</script>

防止用户右键保存或选中水印文字的关键配置

Canvas 绘制的内容天然不可选、不可右键保存——这是它比 SVG 或伪元素方案强的核心点。但要注意两个隐藏风险:

立即学习“前端免费学习笔记(深入)”;

  • 如果页面有 user-select: all 全局设置(比如某些富文本编辑器),会意外让 Canvas 上的文字被双击选中,必须单独重置:canvas { user-select: none; }
  • 部分浏览器(如旧版 Safari)对 pointer-events: none 支持不一致,若发现点击失效,可改用 canvas { pointer-events: auto; } #watermark::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; } 做一层透明覆盖
  • 不要给 <canvas>tabindex,否则键盘焦点可能意外停驻其上,暴露 DOM 结构

移动端适配与性能注意事项

在 iOS Safari 或安卓 Chrome 中,Canvas 滚动时容易出现闪烁或绘制延迟,根本原因是未启用硬件加速和未处理 DPR 变化。

  • 务必在 drawWatermark() 中重新计算 canvas.width/height 并调用 ctx.scale(dpr, dpr),否则高清屏下文字模糊或错位
  • 避免在 scroll 事件里重绘(性能爆炸),只监听 resizeorientationchange;滚动过程中的水印偏移靠 CSS transform: translateZ(0) 触发 GPU 渲染即可
  • 如果页面有 Web Components 或 Shadow DOM,需确保 canvas 插入在 <body> 最外层,否则会被 Shadow Root 隔离而失效

真正的难点不在画出水印,而在让它既“存在感足够”又“不被绕过”。哪怕加了 Canvas,只要源码可见,有人就能删掉 script 标签或覆盖 drawWatermark 函数——水印从来不是技术牢笼,而是行为提示。别花时间对抗截图,重点确保水印文字本身包含可追溯信息,比如加上当前用户 ID 或时间戳。

相关文章

精彩推荐