参数
- value
- visible:水印是否可见
- width:单个水印宽度
- height:单个水印高度
- angle:水印旋转角度
- color:水印的文字颜色
- content:水印内容
vWatermark.js
文件
import { watch } from 'vue'
export const vWatermark = (watermark, binding) => {
const canvas = document.createElement("canvas");
const {
arg,
value: {
visible = true,
width = 240,
height = 120,
angle = -20 * Math.PI / 180,
color = "rgba(0, 0, 0, .1)",
content = "水印"
},
modifiers
} = binding
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.font = '18px serif'
ctx.translate(width / 2, height / 2)
ctx.rotate(angle)
ctx.textAlign = "center"
ctx.textBaseline = "middle"
ctx.fillStyle = color
ctx.fillText(content, 0, 0)
const bgImg = canvas.toDataURL("image/png")
const obs = new MutationObserver(records => {
for(const record of records) {
if(record.target === watermark) {
watermark.style.backgroundImage = watermark.style._visible ? `url(${bgImg})` : "none"
}
for(const item of record.removedNodes) {
if(item === watermark) {
watermark.style.backgroundImage = watermark.style._visible ? `url(${bgImg})` : "none"
}
}
}
})
obs.observe(document.body,{
childList: true,
subtree: true,
attributes: true
})
watch(
() => visible,
() => {
if (visible) {
watermark.style._visible = true
watermark.style.backgroundImage = 'url(' + bgImg + ')'
} else {
watermark.style._visible = false
watermark.style.backgroundImage = "none"
}
},
{immediate: true}
)
}
示例
<script setup>
import {ref} from "vue
import { vWatermark } from "./vWatermark .js"
const visible = ref(false)
</script>
<template>
<button @click="visible = !visible">按钮</button>
<div style="background-color: #fff;width: 500px;height: 500px;">
<div v-watermark="{visible,content: '这是一个水印'}" style="width: 100%;height: 100%;border: 1px solid #666">
</div>
</div>
</template>