前端水印的实现,防止篡改

113 阅读1分钟
  1. 创建一个新的Canvas元素。
  2. 获取Canvas的2D渲染上下文。
  3. 绘制水印文本。
  4. 将Canvas内容转换为Base64编码的图片URL。

截屏2024-03-17 11.06.18.png

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <style>
      #content {
        width: 100%;
        height: 100vh;
      }
      #watermark {
        width: 100%;
        height: 100vh;
        background-color: burlywood;
        position: absolute;
        top: 0;
        left: 0;
        z-index: -1;
      }
      h1 {
        font-size: 40px;
      }
    </style>
  </head>
  <body>
    <div id="content">
      <h1>1119000</h1>
    </div>
  </body>
</html>
<script>
  let watermark = null;
  function createWaterMarkUrl() {
    // 创建一个新的Canvas元素
    const canvas = document.createElement("canvas");
    canvas.width = 150; // 设置Canvas的宽度
    canvas.height = 80; // 设置Canvas的高度
    // 获取Canvas的2D渲染上下文
    const ctx = canvas.getContext("2d");

    // 设置水印文本的样式
    const watermarkText = "张三专属";
    const textSize = 20;
    const xPos = 10;
    const yPos = canvas.height / 2 + textSize / 2;
    const metrics = ctx.measureText(watermarkText); // 获取文字宽度
    const textColor = "rgba(0, 0, 0, 0.3)"; // 半透明黑色
    const textFont = `${textSize}px Arial`;
    ctx.translate(canvas.width / 2, canvas.height / 2); // 将原点移动到Canvas中心
    ctx.rotate(-120); // 旋转90度
    // 绘制水印文本
    ctx.font = textFont;
    ctx.fillStyle = textColor;
    ctx.fillText(watermarkText, -metrics.width / 2, 10);
    ctx.restore();
    // 将Canvas内容转换为Base64编码的图片URL
    const watermarkedImageUrl = canvas.toDataURL("image/png");

    // 输出Base64编码的图片URL,或者根据需要将其用于其他操作
    console.log(watermarkedImageUrl);
    return watermarkedImageUrl;
  }
  const content = document.getElementById("content");
  function createWaterMark() {
    const watermarkedImageUrl = createWaterMarkUrl();
    if (document.getElementById("watermark")) {
      document.getElementById("watermark").remove();
    }

    watermark = document.createElement("div");
    watermark.id = "watermark";
    // watermark.textContent = "张三";
    watermark.style.fontSize = "20px";
    watermark.style.backgroundImage = `url(${watermarkedImageUrl})`;
    watermark.style.pointerEvents = "none";
    watermark.style.backgroundPosition = "0px 0px";
    watermark.style.backgroundRepeat = "repeat";
    content.appendChild(watermark);
  }
  createWaterMark();
//监听content元素及后代元素的变化
  const ob = new MutationObserver(function (entries) {
    for (let entry of entries) {
      for (let node of entry.removedNodes) {
        //删除水印
        if (node === watermark) {
          createWaterMark();
        }
      }
      if (entry.target === watermark) {
        //修改水印
        createWaterMark();
      }
    }
  });
  ob.observe(content, {
    childList: true, // 观察目标子节点的变化,是否有添加或者删除
    attributes: true, // 观察属性变动
    subtree: true, // 观察后代节点,默认为 false
  });
//离开页面记得断开元素监听
  // ob.disconnect()
</script>