实现水印的步骤:
- 用canvas 绘制水印(图片或者文字),将绘制好的canvas 转为base64码,作为背景;
- 监听界面的dom操作(
MutationObserver
),如果删除的是水印,则要重新在界面上添加水印;
具体代码如下:
setWaterMark.js
const initProps = {
width: 200,
height: 150,
font: '25px arial,sans-serif',
text: '',
img: {
src: require('@/assets/images/logo-white.png'),
imgWidth: 200,
imgHeight: 50
},
zIndex: 1,
devicePixelRatio: 1,
}
const setMark = (parentDom, waterMarkProp) => {
const props = Object.assign({...initProps}, {...waterMarkProp});
let dataUrlType = '';
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);
const div = document.createElement('div');
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);
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) {
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>