水印是安全中的一部分,或者可以推广加上自己的一些信息
前端实现方式,是通过创建canvas,将文本或图片添加到canvas,然后导出图片作为背景图
以下实现方法 /watermark.js
1 const watermark = { 2 uuid: 0, 3 dom: null, 4 waterDom: null, 5 defaultOpts: { 6 width: 200, 7 height: 200, 8 offsetLeft: 0, 9 offsetTop: 0, 10 angle: 30, 11 opacity: 0.5, 12 zIndex: 99999, 13 color: "#000000", 14 font: "18px Microsoft YaHei", 15 mark: "", 16 }, 17 opts: {}, 18 init: function (opts) { 19 this.opts = { ...this.defaultOpts, ...opts }; 20 this.opts.bgcUrl = this.generateWaterPic(); 21 this.getEl(); 22 this.addWaterMark(); 23 this.observerMark(); 24 }, 25 // 生成水印图 26 generateWaterPic: function () { 27 const { height, width, angle, offsetLeft, offsetTop, color, font, mark } = this.opts; 28 29 const can = document.createElement("canvas"); 30 can.width = width; 31 can.height = height; 32 33 const ctx = can.getContext("2d"); 34 let h = Math.sin(angle / 360) * width; 35 36 ctx.rotate(-angle / 360); 37 ctx.font = font; 38 ctx.fillStyle = color; 39 ctx.textAlign = "left"; 40 41 // 设置文字开始位置 42 ctx.fillText(mark, 0 + offsetLeft, h + offsetTop); 43 44 return can.toDataURL("image/png"); 45 }, 46 // 生成加水印的dom元素 47 addWaterMark: function () { 48 const { el, opacity, zIndex, bgcUrl, left = 0, right = 0, top = 0, bottom = 0 } = this.opts; 49 const div = document.createElement("div"); 50 this.uuid++; 51 div.id = `water-mark-${this.uuid}`; 52 let styles = { 53 "pointer-events": "none", 54 opacity: opacity, 55 "z-index": zIndex, 56 left: left + "px", 57 right: right + "px", 58 top: top + "px", 59 bottom: bottom + "px", 60 background: `url(${bgcUrl}) left top repeat`, 61 }; 62 63 if (!el) { 64 styles.position = "fixed"; 65 } else { 66 this.dom.style.position = "relative"; 67 styles.position = "absolute"; 68 } 69 let str = ""; 70 Object.keys(styles).forEach((k) => { 71 str += `${k}: ${styles[k]};`; 72 }); 73 this.opts.style = str; 74 div.style = str; 75 this.waterDom = div; 76 this.dom.appendChild(div); 77 }, 78 // 获取添加水印的dom元素,如果没有写,默认加到body上 79 getEl: function () { 80 const { el } = this.opts || this.defaultOpts; 81 let dom; 82 if (!el) { 83 dom = document.body; 84 } else { 85 dom = document.getElementById(el); 86 } 87 if (!dom) { 88 dom = document.body; 89 } 90 this.dom = dom; 91 }, 92 // 清除上一个水印 93 clear: function () { 94 if (this.waterDom) { 95 this.waterDom.remove(); 96 } 97 }, 98 // 监测水印防止删除,或改动 99 observerMark() { 100 const { style } = this.opts; 101 const body = document.body; 102 const waterDom = this.waterDom; 103 const _this = this; 104 const MutationObserver = window.MutationObserver || window.WebKitMutationObserver; 105 if (MutationObserver) { 106 let mo = new MutationObserver(function () { 107 // 108 if ((waterDom && waterDom.getAttribute("style") !== style) || !waterDom) { 109 // 避免一直触发 110 mo.disconnect(); 111 mo = null; 112 _this.clear(); 113 _this.addWaterMark(); 114 _this.observerMark(); 115 } 116 }); 117 118 mo.observe(body, { 119 attributes: true, 120 subtree: true, 121 childList: true, 122 }); 123 } 124 }, 125 // 对dom元素截图 126 cropImg({ id }) { 127 html2canvas(document.getElementById(id)).then((canvas) => { 128 const a = document.createElement("a"); 129 a.href = canvas.toDataURL("image/png"); 130 a.download = `${Date.now()}.png`; 131 document.body.appendChild(a); 132 a.click(); 133 document.body.removeChild(a); 134 }); 135 }, 136 };
在代码里调用
var opts = { mark: "测试加水印", el: "water-mark", height: 200, width: 400, offsetLeft: 20, offsetTop: 10, color: "red", }; watermark.init(opts);
水印效果图