Vue 页面添加水印功能 H5、PC

2 篇文章 0 订阅

主要用到 canvas.toDataURL API,为Vue页面添加水印功能,支持 修改、移除 水印等功能

示例图:
在这里插入图片描述

以不熟练的TS写法示例,可自己更改成JS版本

watermark.ts 水印类定义:

interface CanvasOption {
  width: number
  height: number
  rotate: number
  color: string
  alpha: number
  text: string | string[]
  fontSize: string
  fontFamily: string
  font: string
}
export default class Watermark {
  /**核心 - 一个接收实例的静态成员 */
  private static WatermarkSingle: Watermark
  canvas: HTMLCanvasElement
  watermarkId: string
  option: CanvasOption

  private constructor(props) {
    this.watermarkId = `watermark_${parseInt((+new Date()).toString(), 16)}`
    // 配置项
    this.option = {
      width: 150,
      height: 80,
      rotate: 20, // 旋转角度
      color: '#ccc', // 颜色
      alpha: 0.2, // 透明度
      text: '水印', // 文字
      fontSize: '14px', // 文字大小
      fontFamily: '-apple-system-font,Helvetica Neue,sans-serif',
      font: '',
      ...props
    }
    this.canvas = document.createElement('canvas') as HTMLCanvasElement
    this.createCanvasCtx(this.option)
  }

  static getInstance(props?): Watermark {
    if (this.WatermarkSingle == null) {
      this.WatermarkSingle = new Watermark(props || {})
    }
    return Watermark.WatermarkSingle
  }

  create() {
    this.remove()
    let watermark: HTMLElement = document.createElement('div')
    const styleStr = `
            position:fixed;
            top:0;
            left:0;
            width:100vw;
            height:100vh;
            z-index:99;
            pointer-events:none;
            background-repeat:repeat;
            mix-blend-mode: multiply;
            background-image:url('${this.canvas.toDataURL('image/png')}')`
    watermark.setAttribute('style', styleStr)
    watermark.setAttribute('id', this.watermarkId)
    watermark.classList.add('watermark')
    document.body.appendChild(watermark)
  }
  update(props = {}) {
    const newOption = { ...this.option, ...props }
    this.createCanvasCtx(newOption)
    this.create()
  }
  remove() {
    /* 关闭页面的水印,即要移除水印标签 */
    let watermark: HTMLElement | null = document.querySelector(`#${this.watermarkId}`)
    if (!watermark) {
      watermark = document.querySelector('.watermark')
    }
    watermark && document.body.removeChild(watermark)
  }
  private createCanvasCtx({ width, height, rotate, color, alpha, text, font, fontSize, fontFamily }) {

    this.canvas.width = width
    this.canvas.height = height
    this.canvas.style.display = 'none'

    let ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D

    ctx.clearRect(0, 0, width, height)
    // 控制文字的旋转角度和上下位置
    ctx.rotate((-rotate * Math.PI) / 180)
    ctx.translate(-40, 30)
    ctx.globalAlpha = alpha
    //文字颜色
    ctx.fillStyle = color
    //文字样式
    ctx.font = font ? font : `${fontSize} ${fontFamily}`

    const textAry = Array.isArray(text) ? text : [text]
    let len = textAry.length
    let i = 0
    for (; i < len; i++) {
      ctx.fillText(textAry[i], width / 5, height / 3 + 20 * i)
    }
  }
}

水印类方法:

import Watermark from '@/watermark'
const watermarkInstance: Watermark = Watermark.getInstance()

watermarkInstance.create({/*配置项*/}) // 创建水印

watermarkInstance.update({ text: `${水印文字1} ${水印文字2}`, ...{/*其它配置项*/} }) // 更新水印

watermarkInstance.remove() // 移除水印

vue3 使用示例:

app.ts

import Watermark from '@/watermark'

const watermarkInstance: Watermark = Watermark.getInstance()

watermarkInstance.create()
 
const App = createApp(App)

App.provide('watermark', readonly(watermarkInstance))

其它页面1.vue

<script>
import { inject } from 'vue'
export default {
  setup() {
    const watermark = inject('watermark')
    return { watermark }
  },
  methods: {
  	updateWatermark(route, index) {
	     this.watermark.update({ text: '水印文字更新' })
	  }
  }
}
</script>

其它页面2.vue

<script>
import { useStore } from 'vuex'
import { inject } from 'vue'
export default {
  setup() {
    const store = useStore()
    const userinfo = store.state.user.loginUserInfo
    
    const watermark = inject('watermark')
    watermark.update({ text: ['用户名', userinfo.userName] })
	
	return { }
  }
}
</script>

vue2中也可以在app.vue中引入和创建实例,其他页面通过this.$root.watermark 获取实例,用以调用相关方法

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值