前端添加水印

实现水印的步骤:

  1. 用canvas 绘制水印(图片或者文字),将绘制好的canvas 转为base64码,作为背景;
  2. 监听界面的dom操作(MutationObserver),如果删除的是水印,则要重新在界面上添加水印;

具体代码如下:

setWaterMark.js

// 设置水印
const initProps = {
  width: 200, // canvas 的大小
  height: 150,
  font: '25px arial,sans-serif', // 如果水印是文字
  text: '',
  img: { // 如果水印是图片
    src: require('@/assets/images/logo-white.png'),
    imgWidth: 200,
    imgHeight: 50
  },
  zIndex: 1, // 水印所在层index
  devicePixelRatio: 1, // 图像缩放比例
}

const setMark = (parentDom, waterMarkProp) => {
  const props = Object.assign({...initProps}, {...waterMarkProp});
  let dataUrlType = ''; // 转为 base64 的格式
  let styleSize = props.width / props.devicePixelRatio;
  const canvas = document.createElement('canvas');
  let context = canvas.getContext('2d');
  canvas.width = props.width;
  canvas.height = props.height;
  canvas.style.border = '1px solid red';
  console.log(canvas)
  
  context.translate(props.width / 3, props.height / 2);
  context.rotate((Math.PI / 180) * 25);
  
  // 之所以要动态添加一个div,是因为后面界面要监听这个dom元素
  const div = document.createElement('div');
  div.style.backgroundSize =  `${styleSize}px ${styleSize}px`;
  div.style.backgroundRepeat = 'repeat';
  div.style.width = '100%';
  div.style.height = '100%';
  div.style.zIndex = props.zIndex;
  div.style.opacity = '0.5';
  div.style.position = 'absolute';
  div.style.top = '0'
  div.className = 'water-mark-bg'

  if (initProps?.img) {
    let img = new Image();
    img.src = initProps.img.src;
    img.style.border = '1px solid #000';
    console.log(img)
    const { imgWidth, imgHeight } = props.img;
    dataUrlType = 'image/png';
    img.onload = function () { // 如果是图片,要等待图片加载完才可以
      context.drawImage(img, 0, 0, imgWidth / 2, imgHeight / 2);
      // context.fillRect(0,0,imgWidth / 2,imgHeight / 2); 
      div.style.backgroundImage = `url("${canvas.toDataURL(dataUrlType)}")`;
      parentDom.appendChild(div);
    }
  } else {
    context.fillStyle = 'rgba(0, 0, 0, 0.3)';
    context.font = props.font;
    context.textAlign = 'center';
    context.fillText(props.text, 0, 0);
    context.textBaseline = 'middle';
    div.style.backgroundImage = `url("${canvas.toDataURL(dataUrlType)}")`;
    parentDom.appendChild(div)
  }
}
export { setMark }

组件 waterMark.vue

<template>
  <div class="water-box" ref="waterMarkRef">
    <slot>slot>
  div>
template>
<script>
  import {setMark} from '@/utils/setWaterMark'
  export default {
    props: {
      waterMarkProp: {
        type: Object,
        default: () => {}
      }
    },
    data () {
      return {}
    },
    mounted () {
      const waterMarkRef = this.$refs.waterMarkRef;
      setMark(waterMarkRef, this.waterMarkProp);
      var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
      let ob = new MutationObserver(function (mutationRecoards, observer) {
        // observer 观察者实例
        mutationRecoards.forEach((record) => {
          
        (record?.removedNodes || []).forEach(element => {
          if (element.className === 'water-mark-bg') {
            setMark(waterMarkRef);
          }
        });
        })
      })
      ob.observe(this.$refs.waterMarkRef, {
        cattributes: true, childList: true, subtree: true
      })
    }
  }
script>
<style lang="scss" scoped>
  .water-box {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
  }
style>

具体使用

<div class="bigImg" ref="bigImgRef">
  <img v-if="currentImg?.indexOf('.mp4') === -1" :src='currentImg'/>
  <video v-else :src="currentImg" controls>video>
  <WaterMark :waterMarkProp="waterMarkProp">WaterMark>
div>
<script>
import WaterMark from '@/components/water-mark.vue'
export default {
  data() {
    return {
	  waterMarkProp: {
        zIndex: 1,
        devicePixelRatio: 2
      }
    }
  },
  components: {WaterMark}
}
script>

你可能感兴趣的:(vue,前端,javascript,html)