vue3水印组件

水印组件

技术:Vue3 + Typescript

最近自己做项目时想到了,有些内容如人像,指纹,签名,或其他有版权的场景下需要做水印;

准备用el-plus的watermark,但是缺依赖文件啥的没用上,而且自己只用实现一个简单的就行,于是这个组件就诞生了;

在这里插入图片描述

<template>
  <div ref="watermarkContainer" class="watermark-container">
    <slot></slot>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";

const props = defineProps({
  text: {
    type: String,
    default: "liuxing",
  },
  imageUrl: {
    type: String,
    default: "",
  },
  color: {
    type: String,
    default: "red",
  },
  fontSize: {
    type: Number,
    default: 16,
  },
  opacity: {
    type: Number,
    default: 0.5,
  },
  angle: {
    type: Number,
    default: -20,
  },
});

const watermarkContainer = ref<HTMLElement | null>(null);

const createWatermark = () => {
  if (!watermarkContainer.value) return;

  const container = watermarkContainer.value;
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  if (!ctx) return;

  const width = 100;
  const height = 100;
  canvas.width = width;
  canvas.height = height;

  ctx.clearRect(0, 0, width, height);
  ctx.globalAlpha = props.opacity;
  ctx.font = `${props.fontSize}px Arial`;
  ctx.fillStyle = props.color;
  ctx.translate(width / 2, height / 2);
  ctx.rotate((props.angle * Math.PI) / 180);
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";

  if (props.imageUrl) {
    const img = new Image();
    img.src = props.imageUrl;
    img.onload = () => {
      ctx.drawImage(img, -img.width / 2, -img.height / 2);
      drawWatermark();
    };
  } else if (props.text) {
    ctx.fillText(props.text, 0, 0);
    drawWatermark();
  }

  function drawWatermark() {
    const pattern = ctx!.createPattern(canvas, "repeat");
    if (pattern) {
      const watermarkLayer = document.createElement("div");
      watermarkLayer.style.position = "absolute";
      watermarkLayer.style.top = "0";
      watermarkLayer.style.left = "0";
      watermarkLayer.style.width = "100%";
      watermarkLayer.style.height = "100%";
      watermarkLayer.style.background = `url(${canvas.toDataURL()})`;
      container.appendChild(watermarkLayer);
    }
  }
};

onMounted(() => {
  createWatermark();
});

watch(
  [
    () => props.text,
    () => props.imageUrl,
    () => props.color,
    () => props.fontSize,
    () => props.opacity,
    () => props.angle,
  ],
  () => {
    if (watermarkContainer.value) {
      watermarkContainer.value.innerHTML = "";
      createWatermark();
    }
  },
);
</script>

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值