在 Vue 中实现水印可以是图片或文字的方式,通常可以通过以下几种方式实现:

方法 1:使用 Canvas 实现图片或文字水印

你可以通过 HTML5 Canvas 动态生成水印,既可以是图片也可以是文字。这种方法可以将水印绘制到画布上,并且可以选择在页面加载时根据需求生成图片或文字水印。

示例代码:

<template>
  <div>
    <canvas ref="watermarkCanvas"></canvas>
    <img ref="targetImage" src="example.jpg" alt="Example Image" @load="addWatermark" />
  </div>
</template>

<script>
export default {
  methods: {
    addWatermark() {
      const canvas = this.$refs.watermarkCanvas;
      const img = this.$refs.targetImage;
      const ctx = canvas.getContext('2d');

      // 设置 canvas 大小与图片相同
      canvas.width = img.width;
      canvas.height = img.height;

      // 绘制图片
      ctx.drawImage(img, 0, 0);

      // 根据需要添加图片或文字水印
      this.addTextWatermark(ctx, canvas);  // 添加文字水印
      // this.addImageWatermark(ctx, canvas);  // 添加图片水印
    },

    addTextWatermark(ctx, canvas) {
      // 设置文字水印样式
      ctx.font = "30px Arial";
      ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      ctx.rotate(-0.1);  // 旋转角度
      ctx.fillText("Watermark Text", canvas.width / 2, canvas.height / 2);
    },

    addImageWatermark(ctx, canvas) {
      const watermarkImage = new Image();
      watermarkImage.src = 'path/to/watermark.png';  // 替换为你的水印图片路径
      watermarkImage.onload = () => {
        const scaleFactor = 0.3;  // 调整水印图片大小
        const watermarkWidth = watermarkImage.width * scaleFactor;
        const watermarkHeight = watermarkImage.height * scaleFactor;

        // 绘制图片水印
        ctx.drawImage(watermarkImage, canvas.width - watermarkWidth - 10, canvas.height - watermarkHeight - 10, watermarkWidth, watermarkHeight);
      };
    }
  }
};
</script>

<style scoped>
canvas {
  border: 1px solid #ccc;
}
</style>

特点:

  • 可以动态选择是添加文字水印还是图片水印。
  • 使用 Canvas 绘制,水印叠加到图片上,图片和水印绑定在一起,不易被移除。
  • 支持复杂的水印样式定制,比如旋转、透明度、大小等。

方法 2:使用 CSSVue 的插槽 (Slots) 实现

如果你只需要一个覆盖层式的水印,可以通过 CSS 结合 Vue 插槽来实现,这样可以在同一组件中轻松切换文字或图片水印。

示例代码:

<template>
  <div class="watermark-container">
    <img src="example.jpg" alt="Example Image" />
    <div class="watermark-content">
      <slot name="watermark-text"></slot>
      <slot name="watermark-image"></slot>
    </div>
  </div>
</template>

<style scoped>
.watermark-container {
  position: relative;
}

.watermark-content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;  /* 防止水印干扰点击 */
}

.watermark-content img {
  opacity: 0.2;
}

.watermark-content span {
  font-size: 40px;
  color: rgba(255, 255, 255, 0.5);
  transform: rotate(-30deg);
}
</style>

使用组件:

<template>
  <Watermark>
    <template v-slot:watermark-text>
      <span>Watermark Text</span>
    </template>
    <template v-slot:watermark-image>
      <img src="path/to/watermark.png" alt="Watermark Image" />
    </template>
  </Watermark>
</template>

特点:

  • 通过 Vue 插槽,灵活控制水印内容,可以根据需要选择文字或图片水印。
  • 利用 CSS 控制水印的透明度、位置等样式,简单而直观。
  • 适用于页面静态水印,适合对页面不影响性能的场景。

方法 3:自定义指令动态添加水印

使用 Vue 自定义指令,可以根据需要动态在任意元素上添加图片或文字水印。

示例代码:

<template>
  <div v-watermark="{ text: 'Custom Watermark', imgSrc: 'path/to/watermark.png' }" class="watermark-container">
    <img src="example.jpg" alt="Example Image" />
  </div>
</template>

<script>
export default {
  directives: {
    watermark: {
      bind(el, binding) {
        const { text, imgSrc } = binding.value;

        // 创建水印容器
        const watermarkDiv = document.createElement('div');
        watermarkDiv.style.position = 'absolute';
        watermarkDiv.style.top = '0';
        watermarkDiv.style.left = '0';
        watermarkDiv.style.width = '100%';
        watermarkDiv.style.height = '100%';
        watermarkDiv.style.pointerEvents = 'none';
        watermarkDiv.style.zIndex = '9999';
        watermarkDiv.style.display = 'flex';
        watermarkDiv.style.alignItems = 'center';
        watermarkDiv.style.justifyContent = 'center';

        if (text) {
          // 添加文字水印
          const textWatermark = document.createElement('span');
          textWatermark.innerText = text;
          textWatermark.style.color = 'rgba(255, 255, 255, 0.5)';
          textWatermark.style.fontSize = '40px';
          textWatermark.style.transform = 'rotate(-30deg)';
          watermarkDiv.appendChild(textWatermark);
        }

        if (imgSrc) {
          // 添加图片水印
          const imgWatermark = document.createElement('img');
          imgWatermark.src = imgSrc;
          imgWatermark.style.opacity = '0.2';
          imgWatermark.style.maxWidth = '100px';
          watermarkDiv.appendChild(imgWatermark);
        }

        el.style.position = 'relative';
        el.appendChild(watermarkDiv);
      }
    }
  }
};
</script>

<style scoped>
.watermark-container {
  position: relative;
}
</style>

特点:

  • 通过指令动态添加水印,灵活性高,可以在任何元素中使用。
  • 支持同时添加图片和文字水印,适合需要动态配置水印内容的场景。
  • 水印不会影响页面操作,通过 pointer-events: none 避免影响点击等操作。

总结:

  • 如果需要动态灵活地生成文字或图片水印,推荐使用 Canvas 实现方法,可以高度定制水印效果。
  • 如果需要简单的静态水印,可以使用 CSS + 插槽 或者 自定义指令,实现便捷而简洁。
  • 对于复杂的水印需求,如多种水印类型结合,可以利用 Vue 插槽或自定义指令进行扩展。

你可以根据项目的具体需求选择合适的实现方式。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐