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