博客园

super.hill

记录搬砖中遇到的坑,欢迎批评指导!

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
 

水印是安全中的一部分,或者可以推广加上自己的一些信息

前端实现方式,是通过创建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);

 

水印效果图

 

posted on 2023-03-03 12:29  超岭  阅读(446)  评论(0编辑  收藏  举报
博客园