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

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。