sroxck

sroxck

元素添加水印功能的实现

在网页开发中,水印是一种常用的保护内容的方式。通过添加水印,可以有效地防止内容被未经授权的用户盗用。本文将介绍如何通过自定义指令来为元素添加水印,并实现防盗功能。

实现思路#

  1. 使用 Canvas 生成水印图

    • 首先,我们创建一个 canvas 元素,并根据目标元素的宽高设置其大小。
    • 使用 CanvasRenderingContext2DfillText 方法将水印文字绘制到画布上。
    • 通过调整水印的倾斜角度和间距,实现更灵活的水印效果。
  2. 将生成的图像设置为背景

    • 通过 canvas.toDataURL("image/png") 将画布内容转为 Base64 格式的图片,并将其设置为目标元素的背景。
  3. 使用 MutationObserver 监听 DOM 变动

    • 为了防止用户通过修改 DOM 来去除水印,我们使用 MutationObserver 监控目标元素的属性变化。
    • 一旦检测到属性变化(例如 styleid),我们会恢复水印的设置。
  4. 防盗功能

    • 通过监听 DOM 的变化,确保水印始终存在于目标元素中,增强了内容的保护。

具体实现代码#

以下是实现水印功能的 TypeScript 代码:

/**
 * @param text  水印文字
 * @param font  水印字体
 * @param color 水印颜色
 * @param deg   水印倾斜角度,负数上坡正数下坡
 * @param gap   相邻两个水印的间距
 */

const config = {
  attributes: true,
  attributeOldValue: true,
  attributeFilter: ["class", "id", "style"],
  characterData: true,
  childList: true,
  subtree: true,
  characterDataOldValue: true,
};

function addWaterfall(
  el,
  {
    text = "我是水印",
    font = "bold 18px STHeiti",
    color = "rgba(180,180,180,0.8)",
    deg = -30,
    gap = 200,
  }
) {
  const ob = new MutationObserver(changeOb);

  function beginWatch() {
    ob.observe(el, config);
  }

  function stopWatch() {
    ob.disconnect();
  }

  function changeOb(mutationList) {
    stopWatch();
    console.log("修改了dom");
    mutationList.forEach((mutation) => {
      switch (mutation.type) {
        case "attributes": {
          const attr = mutation.attributeName;
          if (attr === "style") {
            mutation.target.style = mutation.oldValue;
          } else if (attr === "id") {
            mutation.target.id = mutation.oldValue;
          }
        }
      }
    });
    beginWatch();
  }

  function createWaterfall() {
    stopWatch();
    const box_w = parseFloat(document.defaultView.getComputedStyle(el).width);
    const box_h = parseFloat(document.defaultView.getComputedStyle(el).height);
    const canvas = document.createElement("canvas");
    canvas.id = "canvas";
    canvas.width = box_w;
    canvas.height = box_h;
    const ctx = canvas.getContext("2d");
    ctx.rotate((deg * Math.PI) / 180);
    ctx.font = font;
    ctx.fillStyle = color;
    ctx.textBaseline = "middle";

    const MAX_NUM = parseInt(Math.max(box_w, box_h) / gap) + 1;
    const LEFT = Math.floor((MAX_NUM / Math.sqrt(2)) * -1);
    const RIGHT = Math.ceil(MAX_NUM + MAX_NUM / Math.sqrt(2));

    for (let i = LEFT; i <= RIGHT; i++) {
      for (let j = LEFT; j <= RIGHT; j++) {
        ctx.fillText(text, gap * i, gap * j);
      }
    }
    el.style.background = `url(${canvas.toDataURL("image/png")})`;
    beginWatch();
  }

  return createWaterfall;
}

export default addWaterfall;

使用示例#

<div v-waterfall="{ text: '这是水印', }" </div>

总结#

通过以上方法,我们可以轻松地为网页元素添加水印,并实现一定程度的防盗保护。这种方法不仅简单易用,而且具有较高的灵活性,可以根据需求调整水印的样式和位置。希望这篇文章能帮助你在项目中实现水印功能。

此文由 Mix Space 同步更新至 xLog
原始链接为 http://www.sroxck.top/posts/fontend/waterfall


加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。