博客园

super.hill

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

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  158 随笔 :: 0 文章 :: 10 评论 :: 24万 阅读
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
 

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

前端实现方式,是通过创建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 };
复制代码

 

在代码里调用

1
2
3
4
5
6
7
8
9
10
11
var opts = {
          mark: "测试加水印",
          el: "water-mark",
          height: 200,
          width: 400,
          offsetLeft: 20,
          offsetTop: 10,
          color: "red",
        };
 
watermark.init(opts);

 

水印效果图

 

posted on   超岭  阅读(470)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2021-03-03 Vue Element-ui axios 多文件上传
博客园
点击右上角即可分享
微信分享提示