前端添加水印

实现水印的步骤:

  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;
    pointer-events: none; // 这个div就不会影响其他元素的hover或者click事件;(透过water-box)
  }
</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: 99999,
        devicePixelRatio: 2
      }
    }
  },
  components: {WaterMark}
}
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值