Skip to content

前端水印实现方案

原理

  • js方法
  • 配置水印内容,一般为登录系统后的账号
  • 配置是否展示水印,一般通过配置路由meta实现

js方法

水印功能模块,一般放在src/utils目录下

watermark.js
js
/**
 * 前端水印生成工具类
 * 支持自定义水印内容和位置
 */
let id = '' // 水印id
let watermarkTimer = null // 水印定时器

/**
 * 删除水印
 * 路由切换时,从需要水印页面到不需水印页面,需要删除水印并停止存在的水印定时器
 */
export const removeWatermark = () => {
  if (id && document.getElementById(id)) {
    document.body.removeChild(document.getElementById(id))
  }
  id = ''
  watermarkTimer && clearInterval(watermarkTimer)
  watermarkTimer = null
}

/**
 * 生成水印
 * @param {String} text 水印内容
 * @param {String} top 距离顶部位置
 * @param {String} left 距离左侧位置
 * @param {Number} width 签名宽度
 * @param {Number} height 签名高度
 * @returns 返回水印id
 */
const setWatermarkDIV = (text, top, left, width, height) => {
  removeWatermark()

  id = Math.random() * 10000 + '-' + Math.random() * 10000 + '/' + Math.random() * 10000

  const can = document.createElement('canvas')
  can.width = width
  can.height = height

  const cans = can.getContext('2d')
  cans.rotate(-20 * Math.PI / 180)
  cans.font = '15px Vedana'
  cans.fillStyle = 'rgba(0, 0, 0, .2)'
  cans.textAlign = 'left'
  cans.textBaseline = 'Middle'
  cans.fillText(text, can.width / 20, can.height)

  const waterDiv = document.createElement('div')
  waterDiv.id = id
  waterDiv.style.pointerEvents = 'none'
  waterDiv.style.background = 'url(' + can.toDataURL('image/png') + ') left top repeat'
  waterDiv.style.position = 'fixed'
  waterDiv.style.zIndex = '100000'
  waterDiv.style.width = '100%'
  waterDiv.style.height = '100%'
  waterDiv.style.top = top
  waterDiv.style.left = left
  document.body.appendChild(waterDiv)
}

/**
 * 设置水印,定时器2秒1次,删除后仍会自动生成
 * @param {String} text 水印内容
 * @param {String} top 距离顶部位置,默认0px
 * @param {String} left 距离左侧位置, 默认0px
 * @param {Number} width 签名宽度,默认200
 * @param {Number} height 签名高度,默认200
 */
export const setWatermark = (text, top = '0px', left = '0px', width = 200, height = 200) => {
  setWatermarkDIV(text, top, left, width, height)
  watermarkTimer = setInterval(() => {
    if (!document.getElementById(id)) {
      setWatermarkDIV(text, top, left, width, height)
    }
  }, 2000)
}

配置水印内容

登录系统后,根据账号配置获取是否展示水印,如需展示,则缓存中新增水印内容为账号信息

js
localStorage.setItem('watermark', '账号信息示例')

配置水印

路由信息meta中增加水印参数watermark

js
// 需要展示水印的路由页面
{
  path: '/watermark',
  component: () => import(/* webpackChunkName: "demo" */ './watermark.vue'),
  meta: {
    title: '展示水印',
    watermark: true,
  }
},

全局路由增加判断

main.js

js
import { setWatermark, removeWatermark } from '@/utils/watermark'

router.beforeEach((to, from, next) => {
  const watermarkInfo = localStorage.getItem('watermark')
  if (watermarkInfo && to.meta && to.meta.watermark) {
    setWatermark(watermarkInfo, '-100px', '150px', 180, 100)
  } else {
    removeWatermark()
  }
  next()
})

效果展示

水印实现

Released under the MIT License.