在網頁開發中,水印是一種常用的保護內容的方式。通過添加水印,可以有效地防止內容被未經授權的用戶盜用。本文將介紹如何通過自定義指令來為元素添加水印,並實現防盜功能。
實現思路#
-
使用 Canvas 生成水印圖:
- 首先,我們創建一個
canvas
元素,並根據目標元素的寬高設置其大小。 - 使用
CanvasRenderingContext2D
的fillText
方法將水印文字繪製到畫布上。 - 通過調整水印的傾斜角度和間距,實現更靈活的水印效果。
- 首先,我們創建一個
-
將生成的圖像設置為背景:
- 通過
canvas.toDataURL("image/png")
將畫布內容轉為 Base64 格式的圖片,並將其設置為目標元素的背景。
- 通過
-
使用 MutationObserver 監聽 DOM 變動:
- 為了防止用戶通過修改 DOM 來去除水印,我們使用
MutationObserver
監控目標元素的屬性變化。 - 一旦檢測到屬性變化(例如
style
或id
),我們會恢復水印的設置。
- 為了防止用戶通過修改 DOM 來去除水印,我們使用
-
防盜功能:
- 通過監聽 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