Skip to content

水印工具

本文档介绍水印工具的使用方法。

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;
}): void

remove

移除水印。

typescript
WatermarkUtils.remove(): void

使用场景

  • 文档保护
  • 图片版权保护
  • 内部资料标识
  • 防止截图泄密

参考资源

MIT License