主要用到 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 获取实例,用以调用相关方法