vue水印效果实现指南

10,301次阅读
没有评论

共计 5082 个字符,预计需要花费 13 分钟才能阅读完成。

前言

页面水印大家应该都不陌生,它可以用于验证数字媒体的来源和完整性,还可以用于版权保护和信息识别,这些信息可以在不影响媒体质量的情况下嵌入,‌并在需要时进行提取。‌本文将介绍如何在 vue 中通过插件和指令两种方式来实现水印效果,帮助大家更好的应用水印效果到你的项目中。


一、watermark-dom 插件

watermark.js 是基于 DOM 对象实现的 BS 系统的水印,确保系统保密性,安全性,降低数据泄密风险,简单轻量,支持多属性配置,动态计算水印,水印防被删(监听水印组件元素删除并重新添加,监听改变水印的属性并重新添加)。


1.1 特性

  • 多属性配置,简单易上手;
  • 动态计算水印;
  • 水印防被删 (监听水印组件元素删除并重新添加,监听改变水印的属性并重新添加);
  • 支持 2 种导入使用:本地引用,npm 引用;
  • 水印测试工具:testTool 工具;
  • 内置 3 种全局 API 方法:init()load(), remove()
  • 原理:pointer-events 事件穿透属性,Shadow DOM(影子 DOM),opacity 等。

1.2 安装

npm install watermark-dom

1.3 引入

import watermark from 'watermark-dom'

1.4 内置方法

1. watermark.init(setting)

这个方法用于初始化水印,可以设置水印的样式、内容和位置等参数。

栗子

watermark.init({
  watermark_txt: '测试水印',
  watermark_color: 'gray',
  watermark_fontsize: '24px',
})

2. watermark.load(setting)

用于手动加载水印。

栗子

const options = {
  watermark_txt: '测试水印',
  watermark_color: 'gray',
  watermark_fontsize: '24px',
}
watermark.load(options)

3. watermark.remove()

这个方法用于移除已加载的水印。

栗子

watermark.remove();

1.5 常用的属性和配置

watermark_id: 'wm_div_id',          // 水印总体的 id
watermark_prefix: 'mask_div_id',    // 小水印的 id 前缀
watermark_txt:"测试水印",            // 水印的内容
watermark_x:20,                     // 水印起始位置 x 轴坐标
watermark_y:20,                     // 水印起始位置 Y 轴坐标
watermark_rows:0,                   // 水印行数
watermark_cols:0,                   // 水印列数
watermark_x_space:100,              // 水印 x 轴间隔
watermark_y_space:50,               // 水印 y 轴间隔
watermark_font:'微软雅黑',           // 水印字体
watermark_color:'black',            // 水印字体颜色
watermark_fontsize:'18px',          // 水印字体大小
watermark_alpha:0.15,               // 水印透明度,要求设置在大于等于 0.005
watermark_width:100,                // 水印宽度
watermark_height:100,               // 水印长度
watermark_angle:15,                 // 水印倾斜度数
watermark_parent_width:0,           // 水印的总体宽度(默认值:body 的 scrollWidth 和 clientWidth 的较大值)watermark_parent_height:0,          // 水印的总体高度(默认值:body 的 scrollHeight 和 clientHeight 的较大值)watermark_parent_node:null          // 水印插件挂载的父元素 element, 不输入则默认挂在 body 上

1.6 实例代码

template>
  div style="height:100vh">div>
template>

script>
import watermark from 'watermark-dom'
export default {
  mounted() {
    const watermarkText = '测试水印内容'
    const options = {
      watermark_txt: watermarkText,
      watermark_color: 'gray',
      watermark_fontsize: '14px',
      watermark_alpha: 0.5,
      watermark_angle: 15,
      watermark_width: 100,
      watermark_height: 20,
    }
    watermark.load(options)
  },
}
script>

实现效果

vue 水印效果实现指南


1.7 非全屏展示

watermark_parent_node 属性用于指定水印的父节点,即确定水印应该显示在哪个 DOM 元素的内部。通过设置 watermark_parent_node 属性,可以控制水印的显示位置和范围。例如,如果你想要将水印显示在特定的 div 元素内部,可以将该 div 元素作为 watermark_parent_node。这样,水印将被限制在该 div 元素的范围内显示。

template>
  div class="box">
    div class="topBox">div>
    div id="watermarkId" class="cenBox">div>
    div class="bomBox">div>
  div>
template>

script>
import watermark from 'watermark-dom'
export default {
  mounted() {
    const watermarkText = '测试水印内容'
    const options = {
      watermark_txt: watermarkText,
      watermark_color: 'gray',
      watermark_fontsize: '14px',
      watermark_alpha: 0.5,
      watermark_angle: 15,
      watermark_width: 100,
      watermark_height: 20,
      watermark_parent_node: 'watermarkId',
    }
    watermark.load(options)
  },
}
script>
style scoped>
.box {
  width: 100%;
  height: 100vh;
}
.topBox {
  height: 30vh;
  background: cadetblue;
}
.cenBox {
  height: 50vh;
}
.bomBox {
  height: 20vh;
  background: cornflowerblue;
}
style>

实现效果
vue 水印效果实现指南


二、自定义指令实现

在处理水印效果时,一些人可能不愿意依赖插件。实际上,我们可以通过编写自定义指令的方法来实现这一效果,而非使用外部插件。

2.1 watermark.js 封装文件

import axios from 'axios'; 
import {API} from '@/apis/system/user'; 
import moment from "moment"; 

function generateWatermark(text, fontSize, color) {
    const canvas = document.createElement('canvas'); 
    canvas.width = 300; 
    canvas.height = 160; 
    const ctx = canvas.getContext('2d'); 
    ctx.font = `${fontSize}px Arial`; 
    ctx.fillStyle = color; 
    ctx.translate(20, canvas.height - 20); 
    ctx.rotate(-Math.PI / 6); 
    const currentTime = moment().format("YYYY-MM-DD HH:mm:ss");
    const watermarkText = text ? `${text} ${currentTime}` : `Watermark ${currentTime}`;
    ctx.fillText(watermarkText, 0, 0); 
    return canvas.toDataURL('image/png'); 
}


function applyWatermark(el, text, fontSize, color) {
    const watermarkUrl = generateWatermark(text, fontSize, color);
    const watermarkLayer = document.createElement('div');
    watermarkLayer.style.cssText = `  
        position: absolute;  
        top: 0; 
        left: 0;
        z-index:9999;
        width:100%;  
        height: 100%;  
        background-image: url(${watermarkUrl});  
        background-repeat: repeat;  
        pointer-events: none;  
    `;
    el.style.position = 'relative'; 
    el.appendChild(watermarkLayer); 
}

export default {
    bind(el, binding, vnode) {
        const defaultText = '默认水印'; 
        const defaultFontSize = 16; 
        const defaultColor = 'rgba(0, 0, 0, 0.15)'; 

        const text = binding.value && binding.value.text ? binding.value.text : null; 
        const fontSize = binding.value && binding.value.fontSize ? binding.value.fontSize : defaultFontSize; 
        const color = binding.value && binding.value.color ? binding.value.color : defaultColor; 

        if (text) {
            applyWatermark(el, text, fontSize, color); 
        } else {
            axios.get(API.POST_DEVICE_CONFIG)
                .then(res => {
                    if (res.data.code === '0') {
                        const userName = res.data.data[0].ii;
                        const watermarkText = userName ? `${userName}` : defaultText;
                        applyWatermark(el, watermarkText, defaultFontSize, defaultColor);
                    } else {
                        applyWatermark(el, defaultText, defaultFontSize, defaultColor); 
                    }
                })
                .catch(error => {
                    console.error(error);
                    applyWatermark(el, defaultText, defaultFontSize, defaultColor); 
                });
        }
    },
    unbind(el) {
        el.removeChild(el.lastChild);
    }
}

以上这段代码就实现了简单的一个页面水印自定义指令。首先我们定义了 generateWatermark 方法,用于生成包含水印文本和当前时间的图片。然后定义了 applyWatermark 方法,将生成的水印图片作为背景应用到指定元素上。在 vue 自定义指令中,通过 bind 钩子函数实现逻辑:优先显示用户传入的参数作为水印文本,如果用户未传入参数,则通过接口请求获取用户信息,并将用户名作为水印文本显示。如果接口请求失败或没有返回数据,则使用默认的水印文本。最后,在 unbind 钩子函数中实现移除水印效果的逻辑。

2.2 main.js 入口文件

注册水印自定义指令到 vue 实例。

import watermarkFile from './utils/watermark'
Vue.directive('watermark', watermarkFile)

2.3 使用

  • 不传参的写法

    div v-watermark> 占位内容 div>
    

    实现效果
    在这里插入图片描述

  • 传参的写法

    div v-watermark="{text:' 传入水印 ', fontSize: 14, color:'red'}"> 占位内容 div>
    

    实现效果

    在这里插入图片描述

原文地址: vue 水印效果实现指南

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-10-30发表,共计5082字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)