水印工具
本文档介绍水印工具的使用方法。
WatermarkUtils
水印工具类,支持添加文字水印、图片水印,防删除。
添加文字水印
typescript
import { WatermarkUtils } from '@vben/utils';
// 基础水印
WatermarkUtils.add({
text: '内部资料'
});
// 自定义样式
WatermarkUtils.add({
text: '内部资料',
fontSize: 16,
color: 'rgba(0, 0, 0, 0.15)',
rotate: -20,
zIndex: 9999
});
// 多行文字
WatermarkUtils.add({
text: ['内部资料', '请勿外传']
});添加图片水印
typescript
import { WatermarkUtils } from '@vben/utils';
WatermarkUtils.add({
image: '/logo.png',
width: 120,
height: 40
});移除水印
typescript
import { WatermarkUtils } from '@vben/utils';
WatermarkUtils.remove();防删除水印
typescript
import { WatermarkUtils } from '@vben/utils';
// 启用防删除(监听 DOM 变化)
WatermarkUtils.add({
text: '内部资料',
preventDelete: true
});完整示例
vue
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { WatermarkUtils } from '@vben/utils';
const watermarkText = ref('内部资料');
const fontSize = ref(16);
const color = ref('rgba(0, 0, 0, 0.15)');
const rotate = ref(-20);
function addWatermark() {
WatermarkUtils.add({
text: watermarkText.value,
fontSize: fontSize.value,
color: color.value,
rotate: rotate.value,
preventDelete: true
});
}
function removeWatermark() {
WatermarkUtils.remove();
}
onMounted(() => {
addWatermark();
});
onUnmounted(() => {
removeWatermark();
});
</script>
<template>
<div class="watermark-demo">
<a-space direction="vertical" style="width: 100%">
<a-input
v-model:value="watermarkText"
placeholder="水印文字"
/>
<div>
<span>字体大小:</span>
<a-slider
v-model:value="fontSize"
:min="12"
:max="30"
style="width: 200px; display: inline-block; margin-left: 10px"
/>
<span style="margin-left: 10px">{{ fontSize }}px</span>
</div>
<div>
<span>旋转角度:</span>
<a-slider
v-model:value="rotate"
:min="-90"
:max="90"
style="width: 200px; display: inline-block; margin-left: 10px"
/>
<span style="margin-left: 10px">{{ rotate }}°</span>
</div>
<a-space>
<a-button type="primary" @click="addWatermark">
添加水印
</a-button>
<a-button @click="removeWatermark">
移除水印
</a-button>
</a-space>
</a-space>
</div>
</template>自定义水印实现
typescript
// 创建水印
function createWatermark(options: {
text: string;
fontSize?: number;
color?: string;
rotate?: number;
}) {
const {
text,
fontSize = 16,
color = 'rgba(0, 0, 0, 0.15)',
rotate = -20
} = options;
// 创建 canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d')!;
canvas.width = 200;
canvas.height = 150;
ctx.font = `${fontSize}px Arial`;
ctx.fillStyle = color;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// 旋转
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate((rotate * Math.PI) / 180);
ctx.fillText(text, 0, 0);
// 转换为 Data URL
return canvas.toDataURL();
}
// 添加水印
function addWatermark(text: string) {
const watermarkUrl = createWatermark({ text });
const div = document.createElement('div');
div.id = 'watermark';
div.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 9999;
background-image: url(${watermarkUrl});
background-repeat: repeat;
`;
document.body.appendChild(div);
}
// 移除水印
function removeWatermark() {
const watermark = document.getElementById('watermark');
if (watermark) {
watermark.remove();
}
}防删除实现
typescript
// 监听 DOM 变化,防止水印被删除
function observeWatermark() {
const watermark = document.getElementById('watermark');
if (!watermark) return;
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
const removed = Array.from(mutation.removedNodes).some(
node => node === watermark
);
if (removed) {
// 水印被删除,重新添加
addWatermark('内部资料');
}
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
return observer;
}API 参考
add
添加水印。
typescript
WatermarkUtils.add(options: {
text?: string | string[];
image?: string;
fontSize?: number;
color?: string;
rotate?: number;
width?: number;
height?: number;
zIndex?: number;
preventDelete?: boolean;
}): voidremove
移除水印。
typescript
WatermarkUtils.remove(): void使用场景
- 文档保护
- 图片版权保护
- 内部资料标识
- 防止截图泄密