-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
154 lines (146 loc) · 4.21 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* @Author: cbw
* @Date: 2022-09-23 16:21:05
* @LastEditors: cbw
* @LastEditTime: 2022-12-28 18:41:47
* @Description:
*/
class WaterMark {
#canvasOptions; // canvas默认配置
#waterMarkStyle; // 水印默认配置
#wm; // 水印DOM
#Uuid; // 唯一id
#waterMarkStyleStr; // style字符串
constructor(canvasOptions = {}, waterMarkStyle = {}) {
// canvas默认配置
this.#canvasOptions = {
width: 400, // canvas宽
height: 400, // canvas高
font: "normal 16px 思源黑体_ Regular",
fillStyle: "rgba(10, 100, 80, .2)", // 文本颜色
textAlign: "center",
fillTextArr: ["Boen", "3150987521986"], // 文本
rotate: -20, // 旋转角度
fillTextX: 100, // 文本横坐标
fillTextY: 100, // 文本纵坐标
...canvasOptions, // 合并个性化配置
};
// 水印默认配置
this.#waterMarkStyle = {
position: "absolute",
left: 0,
top: 0,
right: 0,
bottom: 0,
"z-index": "99999",
"pointer-events": "none", // 永远不成为鼠标事件的 target
container: document.body, // 水印创建位置
...waterMarkStyle, // 合并个性化配置
};
// 初始化
this.#init();
}
/**
* 创建canvas
* @param {Object} options 选项
* @returns canvasUrl
*/
createCanvasUrl(options = {}) {
const canvas = document.createElement("canvas"); // 创建canvas
// 设置属性
canvas.setAttribute("width", options?.width);
canvas.setAttribute("height", options?.height);
const ctx = canvas.getContext("2d");
ctx.font = options?.font;
ctx.fillStyle = options?.fillStyle;
ctx.textAlign = options?.textAlign;
ctx.rotate((Math.PI / 180) * options?.rotate);
const fillTextArr = options?.fillTextArr;
for (let i = 0; i < fillTextArr.length; i++) {
const fillText = fillTextArr[i];
// 防止多文本重叠
ctx.fillText(fillText, options?.fillTextX, options?.fillTextY + 20 * i);
}
const canvasUrl = canvas.toDataURL(); // 获取base64图片URL
return canvasUrl;
}
/**
* 创建水印
* @param {String} bgcImgUrl
* @param {Object} options
*/
createWaterMark(bgcImgUrl, options = {}) {
this.#Uuid = this.getUuid();
const waterMark = document.createElement("div");
waterMark.setAttribute("id", this.#Uuid);
this.#waterMarkStyleStr = "";
// 拼接成style字符串
for (let key in this.#waterMarkStyle) {
this.#waterMarkStyleStr += key + `:${options?.[key]};`;
}
this.#waterMarkStyleStr += `background-image:url(${bgcImgUrl});`;
waterMark.setAttribute("style", this.#waterMarkStyleStr); // 设置style属性
options?.container?.appendChild(waterMark);
return waterMark;
}
/**
* 生成uuid
* @returns
*/
getUuid() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(
/[xy]/g,
function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
}
);
}
/**
* 初始化
*/
#init() {
const base64Url = this.createCanvasUrl(this.#canvasOptions); // base64图片
this.#wm = this.createWaterMark(base64Url, this.#waterMarkStyle); // 创建水印
this.#observer(); // 防止控制台删除水印
}
/**
* 移除水印
*/
#remove() {
const wmDiv = document.getElementById(this.#Uuid);
// 防止预移出节点不存在
if (!wmDiv) {
this.#waterMarkStyle.container.removeChild(this.#wm);
}
}
/**
* 防止控制台删除水印
*/
#observer() {
const targetNode = this.#waterMarkStyle.container; // 监听节点
// 监听配置
const observerConfig = {
subtree: true,
childList: true,
attributes: true,
};
// 创建observer对象
const observer = new MutationObserver(() => {
const wmDiv = document.getElementById(this.#Uuid);
// wmDiv不存在
if (!wmDiv) {
this.#init();
return;
}
// css样式被修改
if (wmDiv.getAttribute("style") !== this.#waterMarkStyleStr) {
wmDiv.setAttribute("style", this.#waterMarkStyleStr);
}
});
// 开始监听
observer.observe(targetNode, observerConfig);
}
}
export { WaterMark };