Skip to content

实现页面水印

简介

这里记录一下页面水印的实现方法,简单搭建一个 demo 项目(项目地址

具体的实现步骤如下:

  • 通过 canvas 生成水印信息
  • 将生成的 canvas 转成 base64
  • 将 base64 数据作为背景图片
  • MutationObserver 监听,防止用户手动更改移除

相关代码

下面代码是对水印封装的函数,只需要调用即可

js
function watermark(options = {}) {
  const {
    container = document.body, // 容器
    width = "240", // canvas元素宽
    height = "100", // canvas元素高
    textAlign = "left", // 文字对齐
    textBaseline = "bottom", // 基准线
    font = "16px Microsoft Yahei", // 字体大小及样式
    fillStyle = "#000", // 自定义水印的颜色
    content = "进制外传", // 水印内容
    globalAlpha = 0.3, // 设置图形和图像透明度的值
    rotate = 16, // 文字旋转角度
    zIndex = 1000, // 元素堆叠顺序
  } = options;

  const canvas = document.createElement("canvas");
  canvas.setAttribute("width", width);
  canvas.setAttribute("height", height);
  const ctx = canvas.getContext("2d"); // 获取 canvas2d 上下文
  ctx.globalAlpha = globalAlpha;
  ctx.textAlign = textAlign;
  ctx.textBaseline = textBaseline;
  ctx.font = font;
  ctx.fillStyle = fillStyle;
  ctx.rotate((Math.PI * rotate) / 180);
  // ctx.rotate(-10 * Math.PI / 140);
  ctx.fillText(content, 50, 50);

  const base64Url = canvas.toDataURL(); // 返回一个包含图片展示的 data URI

  const __wm = document.querySelector(".__wm"); // 选择器
  const watermarkDiv = __wm || document.createElement("div");
  const waterMarkStyle = `
    position:absolute;
    top:0px;
    left:0px;
    width:100%;
    height:100%;
    z-index:${zIndex};
    pointer-events:none;
    background-repeat:repeat;
    background-image:url('${base64Url}')`;

  watermarkDiv.setAttribute("style", waterMarkStyle);
  watermarkDiv.classList.add("__wm"); // 为元素添加“__wm”类名

  container.style.position = "relative";
  container.appendChild(watermarkDiv); // 添加元素

  // 监听删除 防止用户去手动删除,如果手动删除 ,在重新添加
  const MutationObserver =
    window.MutationObserver || window.WebKitMutationObserver;
  // 检查浏览器是否支持这个API
  if (MutationObserver) {
    const args = arguments[0];
    const __wm = document.querySelector(".__wm");
    let mo = new MutationObserver(function () {
      // 只在__wm元素变动才重新调用
      if (
        (__wm && __wm.getAttribute("style") !== waterMarkStyle) ||
        !__wm ||
        document.body.style.position !== "relative"
      ) {
        // 避免一直触发
        mo.disconnect();
        mo = null;
        watermark(args);
      }
    });
    mo.observe(__wm, {
      attributes: true, // 观察目标节点的属性节点
      subtree: false, // 观察目标节点的所有后代节点
      childList: true, // 观察目标节点的子节点
    });
  }
}
export default watermark;

项目中调用

vue
<template>
  <div class="hello-world-page">
    <button @click="createWaterMark">生成水印</button>
  </div>
</template>

<script>
import watermark from "@/utils/waterMark";
export default {
  data() {
    return {};
  },
  methods: {
    createWaterMark() {
      watermark();
    },
  },
};
</script>

<style lang="scss" scoped>
.hello-world-page {
  width: 100vw;
  height: 100vh;
}
</style>

总结

其实生成水印的原理很简单,就是将文字绘制到 canvas 上,然后将 canvas 转成 base64 数据作为背景图片,这样就实现了页面水印的效果。

另外,需要注意使用 MutationObserver 来监听 DOM 结构的变化,防止用户对页面进行操作,导致水印移除



⭐️⭐️⭐️ 好啦!!!本文章到这里就结束啦。⭐️⭐️⭐️

✿✿ ヽ(°▽°)ノ ✿

撒花 🌸🌸🌸🌸🌸🌸

上次更新于: