页面水印实现

222 阅读1分钟

对于页面水印的实现思路是:

创建一个元素,让他浮在页面最上层,让他有种蒙了一层水印的效果

水印的效果我们可以给这个元素一个背景图(background-image),背景图就用svg生成。具体实现如下:

  1. 创建水印元素让他浮在最上层

    <style>
      #water-mark {
        height: 100%;
        width: 100%;
        z-index: 999999;
        position: fixed;
        left: 0;
        top: 0;
        pointer-events: none; // 使元素的所有事件都失效,很关键!
      }
    </style>
    <div id="water-mark"></div>
    
  2. 编写水印生成工具类

export default class WaterMark {
  constructor(elem, options) {
    this.elem = elem || document.querySelector('body')
    const defaultOptions = {
      text: '文字内容', // 文字内容
      color: '#000', // 文字颜色
      fontSize: 10, // 文字大小
      opacity: 0.1, // 透明度
      spaceX: 80, // 文字水平方向间距
      spaceY: 60, // 文字垂直方向间距
      textRotate: -22, // 旋转角度
      fontFamily: 'Helvetica Neue' // 文字字体
    }
    this.options = { ...defaultOptions, ...options }
    this.init()
  }

  init() {
    this.calcTextSize()
    const options = this.options
    const width = options.spaceX + options.txtAttr.width
    const height = options.spaceY + options.txtAttr.height
    const height_2 = height * 2
    const width_0_5 = width / 2
    const svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="none">
      <defs>
        <pattern id="pattern1" x="0" y="0" width="${width}" height="${height_2}" patternUnits="userSpaceOnUse" patternTransform="rotate(${options.textRotate})">
          <text x="0" y="${options.fontSize}" style="font-family:${options.fontFamily}; font-size:${options.fontSize}; fill:${options.color}; fill-opacity:${options.opacity}">${options.text}</text>
        </pattern>
        <pattern id="pattern2" x="${width_0_5}" y="${height}" width="${width}" height="${height_2}" patternUnits="userSpaceOnUse" patternTransform="rotate(${options.textRotate})">
          <text x="0" y="${options.fontSize}" style="font-family:${options.fontFamily}; font-size:${options.fontSize}; fill:${options.color}; fill-opacity:${options.opacity}">${options.text}</text>
        </pattern>
      </defs>
      <rect x="0" y="0" width="100%" height="100%" style="fill:url(#pattern1); fill-opacity:1;" />
      <rect x="0" y="0" width="100%" height="100%" style="fill:url(#pattern2); fill-opacity:1;" />
    </svg>`
    const svgBase64 = window.btoa(unescape(encodeURIComponent(svg)))
    setTimeout(() => {
      this.elem.style.backgroundImage = `url(data:image/svg+xml;base64,${svgBase64})`
    })
  }

  calcTextSize() {
    const { text, fontFamily } = this.options
    const $span = document.createElement('span')
    $span.innerHTML = text
    $span.setAttribute('style', `font-family: ${fontFamily}; font-size: 12px; visibility: hidden; display: inline-block`)
    document.querySelector('body').appendChild($span)
    this.options.txtAttr = {
      text,
      width: $span.offsetWidth,
      height: $span.offsetHeight
    }
    $span.remove()
  }
}
  1. 在页面中调用方法类

    new WaterMark(document.querySelector('#water-Mark'), {
      fontSize: 14,
      opacity: 0.2
    })
    

最终实现效果如下: