vue后台水印实现

2023-10-30

<template>
    <router-view
        v-waterMark="waterCode"
    ></router-view>
</template>

<script>
import waterMark from 'common/utils/watermark';
export default {
    directives: {
        waterMark: waterMark,
    },
    computed: {
        waterCode() {
            return {text: `平台机密数据`,
                    style: {
                        'width': 700, // 单个水印的宽
                        'height': 300, // 单个水印的高
                        'font': 'normal 22px Microsoft Yahei', // 设置样式
                        'fillStyle': 'rgba(112, 113, 114, 0.1)', // 水印字体颜色
                        'rotate': (30 * Math.PI / 180), // 水印偏转角度
                    },
            };
        },
    },
};
</script>

/**
 * @file 网页水印
 */
/*eslint-disable*/
let watermark = {
    text: 'text',
    style: {},
    isAllowDele: false,
    maskDiv: '',
    init: (text) => {
        let canvas = document.createElement('canvas');
        canvas.id = 'canvas';
        canvas.width = watermark.style.width; // 单个水印的宽高
        canvas.height = watermark.style.height;
        watermark.maskDiv = document.createElement('div');
        let ctx = canvas.getContext('2d');
        ctx.font = watermark.style.font; // 设置样式
        ctx.fillStyle = watermark.style.fillStyle; // 水印字体颜色
        ctx.rotate(watermark.style.rotate); // 水印偏转角度
        // convas 设置换行
        CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {
            if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {
                return;
            }
            var context = this;
            var canvas = context.canvas;
            if (typeof maxWidth == 'undefined') {
                maxWidth = (canvas && canvas.width) || watermark.style.width;
            }
            if (typeof lineHeight == 'undefined') {
                lineHeight = (canvas && parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight);
            }
            // 字符分隔为数组
            var arrText = text.split('');
            var line = '';
            for (var n = 0; n < arrText.length; n++) {
                var testLine = line + arrText[n];
                var metrics = context.measureText(testLine);
                var testWidth = metrics.width;
                if (testWidth > maxWidth && n > 0) {
                    context.fillText(line, x, y);
                    line = arrText[n];
                    y += lineHeight;
                } else {
                    line = testLine;
                }
            }
            context.fillText(line, x, y);
        };
        ctx.wrapText(watermark.text, 30, 20);
        let src = canvas.toDataURL('image/png');
        watermark.maskDiv.style.position = 'fixed';
        watermark.maskDiv.style.zIndex = '9999';
        watermark.maskDiv.id = '_waterMark';
        watermark.maskDiv.style.top = '60px';
        watermark.maskDiv.style.left = '0';
        watermark.maskDiv.style.height = '100%';
        watermark.maskDiv.style.width = '100%';
        watermark.maskDiv.style.pointerEvents = 'none';
        watermark.maskDiv.style.backgroundImage = 'URL(' + src + ')';
        // 水印节点插到body下
        document.body.appendChild(watermark.maskDiv);
    },
    // 防删机制
    monitor: () => {
        let body = document.getElementsByTagName('body')[0];
        let options = {
            childList: true,
            attributes: true,
            characterData: true,
            subtree: true,
            attributeOldValue: true,
            characterDataOldValue: true
        }
        let observer = new MutationObserver(watermark.callback);
        observer.observe(body, options); // 监听body节点
    },
    // DOM改变执行callback
    callback: (mutations, observer) => {
        // 当attribute属性被修改
        if (mutations[0].target.id === '_waterMark') {
            watermark.removeMaskDiv();
        }
        // 当id被改变时
        if (mutations[0].attributeName === 'id') {
            watermark.removeMaskDiv();
            watermark.init();
        }
        // 当节点被删除
        if (mutations[0].removedNodes[0] && mutations[0].removedNodes[0].id === '_waterMark') {
            watermark.init();
        }
    },
    /* public */
    // 手动销毁水印DOM
    removeMaskDiv: () => {
        document.body.removeChild(watermark.maskDiv);
    },
    render: () => {
        // let maskBox = document.querySelector('#_waterMark');
        if (!watermark.maskDiv) {
            watermark.init();
            // 是否允许通过js或开发者工具等途径修改水印DOM节点(水印的id,attribute属性,节点的删除),true为允许, 默认不允许
            if (!watermark.isAllowDele) {
                // 设置水印节点修改的DOM事件
                watermark.monitor();
            }
        }
    }
  }

  export default {
    bind(el, binding, vnode) {
        const options = binding.value;
        watermark.style =  options.style;
        watermark.text = options.text;
        watermark.isAllowDele = options.isAllowDele;
        watermark.render();
    },
    update(element, data) {
        if (data.value.text !== data.oldValue.text) {
            watermark.text = data.value.text;
            watermark.removeMaskDiv();
            watermark.render();
        }
    },
  };
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue后台水印实现 的相关文章

随机推荐

  • Java给定一个正整数n,求1+2+3+...+n之和并输出。

    package com haitong homeworktwo import java util Scanner public class One public static void main String args System out
  • python excel修改数据库_【超详细】用Python行云流水地操作Excel和数据库

    前言 本想就着这个机会学习下Java读取Excel的 奈何搜了一圈 发现还是Pandas最为简单明了 打算先就Python写一版 后面在学习时可能还会发一篇 用Java优雅地操作Excel和数据库 准备工作 软件包 关于软件安装和环境配置
  • 【C++】volatile关键字

    我们都知道当使用编译器时候 编译器会为我们的代码做出一些优化 关于validate关键字的功能和原理我们将用一个例子来给出解释 功能 当一个变量被volidate关键字修饰时 意味着当我们每次使用这个变量时都会从变量所在的内存中去获取 而不
  • 技术经验总结之——“&”符在XML中的转义

    1 符在XML的转义 lt action name docadd class com huawei netforce dcm ui DocAddAction gt lt result name success type dispatcher
  • yolor 测试笔记

    模型147M 测试图片发现 没有比yolov5好 下图测试 漏检了3个物体 论文 https arxiv org pdf 2105 04206 pdf 开源代码 https github com WongKinYiu yolor 前言 人们
  • 【C++】异常处理

    一 什么是异常处理 一句话 异常处理就是处理程序中的错误 二 为什么需要异常处理 以及异常处理的基本思想 C 之父Bjarne Stroustrup在 The C Programming Language 中讲到 一个库的作者可以检测出发生
  • java getparentfile_java中File 类的getParentFile()方法

    getParentFile 函数是可以获得上级目录了 我们下面来为各位介绍一篇关于java中File 类的getParentFile 方法使用详细 希望对大家有帮助 getParentFile 的作用是获得父目录 问题就是 mkdirs 这
  • ESXi直通Intel网卡接口出现reset故障解决

    最近买了个intel 82576的双口网卡 想直通给虚拟机做软路由使用 设置好直通 虚拟机添加PCI设备后 开机后接口一直报reset错误 无法使用 ESXI的直通设置如下 启动后报错如下 21 053132 igb 0000 0b 00
  • 基于循环神经网络股票预测系统

    循环神经网络 Simple RNN RNN神经网络模型是一种常用的深度神经网络模型 已成功应用于语言识别 文本分类等多个研究领域 相比其他网络模型 RNN最大的优势在于引入了时序与定向循环的概念 能够很好地解决输入数据前后之间相互关联的问题
  • 调用mysql数据_调用数据库的五种方式

    ThinkPHP 内置了抽象数据库访问层 把不同的数据库操作封装起来 我们只需要使用 公共的 Db 类进行操作 无须针对不同的数据库写不同的代码和底层实现 Db 类会自动调用 相应的数据库驱动来处理 一 全局配置定义 在common con
  • 明明导入Jar包却抛出ClassNotFoundException

    项目中添加过Jar包 显示ClassNotFoundException 因为在Tomcat中找不到mysql jar包 手动添加Jar包到tomcat bin下 出现错误的原因是 delete调用了executeQuery 方法
  • 私有代码存放仓库 BitBucket介绍及入门操作

    本文主要来自于萧 瑟BLOG 和牛仔的移动开发博客 并综合了多篇网上文章 代码版本控制系统在局域网内Subvision用的比较多 但其局限性太多 在代码审查 异地合作等功能方面比较弱 目前比较出名的分布式版本控制系统有Bitbucket和G
  • 求多边形面积公式(已知顶点坐标)

    下面介绍一种求多边形面积的方法 首先已知各定点的坐标分别为 x1 y1 x2 y2 x3 y3 Xn Yn 则该多边形的面积公式为 s 1 2 x1 y2 x2 y1 x2 y3 x3 y2 Xk Yk 1 Xk 1 Yk Xn y1 x1
  • JavaScript检查null与undefined以及==和===之间的差异

    如何检查变量是否为null或undefined并且null和undefined什么区别 和 什么区别 很难在Google上搜索 1楼 区别是微妙的 在JavaScript中 undefined变量是从未声明或从未分配值的变量 假设您声明va
  • 生信必会格式:Fasta & Fastq 简介及转换

    文章目录 前言 FASTA 例子 血红蛋白 的核酸和蛋白质序列 FASTQ FASTA FASTQ 对比 FASTQ 转为 FASTA 使用基本的命令 sed paste awk 使用现有工具 Bioawk Seqtk FASTA 到 FA
  • sql注入详细解释

    sql注入以及应对措施 sql注入是什么 sql注入的危害 sql注入的几种方式 数字型注入 字符串注入 关于mybatis中传递变量用 的原因 sql注入是什么 sql是我们操作数据库与其交互的语言 而sql注入是用户将Web页面的原UR
  • waymo数据集下载

    下载waymo数据集下载报错 gsutil不能使用怎么办 安装谷歌云 gcloud init gcloud auth login gcloud auth application default login gsutil config 然后就
  • Linux内核调度框架和CFS调度算法

    进程调度 暂时以2 6 24内核版本讲解 该版本是CFS调度器注入Linux内核之后的第二个版本 在框架和数据结构上与4 x之后没有本质上的区别 但是由于4 x对CFS调度做了很大的优化 代码量暴增10倍之多 故不容易把握算法与框架的本质
  • 【两阶段鲁棒优化问题】用列和约束生成方法求解两阶段鲁棒优化问题(Matlab代码实现)

    个人主页 研学社的博客 欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 文献来源 4 Matlab代码及文章 1 概述 文献来源 鲁棒优
  • vue后台水印实现