vue项目页面添加水印实现方法

1、整体思路:

用 Canvas 画一个带旋转的文字水印 → 转成图片 → 当作 background-image 铺满整个页面 → 固定在页面最上层
2、核心流程图

javascript 复制代码
setWaterMark(str1, str2)
   ↓
setWatermark()
   ↓
创建 canvas
   ↓
canvas 上写字(旋转)
   ↓
canvas → base64 图片
   ↓
创建 div,用这张图做背景
   ↓
div fixed 覆盖全屏
   ↓
append 到 body

3、具体实现方法:

先创建一个watermark.js文件,代码如下

javascript 复制代码
  // 水印添加方法
  let setWatermark = (str1, str2) => {
    let id = 'watermark_id';
    if (document.getElementById(id) !== null) {
      document.body.removeChild(document.getElementById(id));
    }
    let can = document.createElement('canvas');
    // 设置canvas画布大小
    can.width = 350;
    can.height = 250;
    let cans = can.getContext('2d');
    cans.rotate(-20 * Math.PI / 180); // 水印旋转角度
    cans.font = '18px Vedana';
    cans.fillStyle = '#000000';
    cans.textAlign = 'center';
    cans.textBaseline = 'middle';
    cans.fillText(str1, can.width / 2, can.height) // 水印在画布的位置x,y轴
    cans.fillText(str2, can.width / 2, can.height + 22);
	
    let div = document.createElement('div')
    div.id = id;
    div.style.pointerEvents = 'none'; // 不拦截鼠标事件
    div.style.top = '40px';
    div.style.left = '0px';
    div.style.opacity = '0.10';
    div.style.position = 'fixed';
    div.style.zIndex = '100000';
    div.style.width = document.documentElement.clientWidth + 'px';
    div.style.height = document.documentElement.clientHeight  + 'px';
    div.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat';
    document.body.appendChild(div);
    return id;
  }
 
  // 添加水印方法
  export const setWaterMark = (str1, str2) => {
    let id = setWatermark(str1, str2);
    if (document.getElementById(id) === null) {
      id = setWatermark(str1, str2);
    }
  }
 
  // 移除水印方法
  export const removeWatermark = () => {
    let id = 'watermark_id';
    if (document.getElementById(id) !== null) {
      document.body.removeChild(document.getElementById(id))
    }
  }

4、项目中具体使用:

如果是全局页面都使用,可以直接添加在app.vue页面中,如下:

javascript 复制代码
<template>
  <div id="app">
    <router-view />
  </div>
</template>
<script>
import { removeWatermark, setWaterMark } from '@/assets/js/watermark.js'
export default {
  name: 'App',
  beforeDestory(){
    removeWatermark();
  },
  data(){
    return {}
  },
  watch:{
    $route:{
      handler(val){
          setWaterMark("你好呀",this.getCurrentDateTime())
      },
      deep:true,
      immediate:true
    }
  },
  mounted(){},
  methods:{
    getCurrentDateTime() {
      const now = new Date();
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0');
      const day = String(now.getDate()).padStart(2, '0');
      const hour = String(now.getHours()).padStart(2, '0');
      const minute = String(now.getMinutes()).padStart(2, '0');

      return `${year}年${month}月${day}日${hour}点${minute}分`;
    }
  }
}
</script>
<style>
#nprogress .bar {
  background: rgb(233, 85, 110) !important;
}
</style>
相关推荐
To_OC1 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
咩咩啃树皮2 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny2 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹2 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny2 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
To_OC3 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
小林ixn3 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker3 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜4 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康4 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端