<template>
  <div class="image-watermark">
    <img v-if="dataUrl" :src="dataUrl" />
  </div>
</template>

<script>
export default {
  name: "image-watermark",
  props: {
    url: String,
    content: String,
  },
  data() {
    return {
      loading: false,
      errorMsg: "",
      dataUrl: "",
    };
  },
  mounted() {
    this.initData();
  },
  methods: {
    async initData() {
      if (!this.url) return;

      this.loading = true;

      const image = await this.loadingImg(this.url).catch(() => {});
      if (!image) {
        this.loading = false;
        this.errorMsg = "图片载入失败！";
        return;
      }

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

      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      ctx.drawImage(image, 0, 0);

      this.drawWatermark(ctx, { width: canvas.width, height: canvas.height });

      canvas.toBlob((val) => {
        this.loading = false;
        if (!val) return;
        this.dataUrl = URL.createObjectURL(val);
      });
    },
    loadingImg(url) {
      return new Promise((reslove, reject) => {
        const img = new Image();
        img.crossOrigin = "";
        img.src = url;
        img.onload = () => {
          reslove(img);
        };
        img.onerror = (e) => {
          reject(e);
        };
      });
    },
    drawWatermark(ctx, { width, height }) {
      const angle = (315 * Math.PI) / 180;
      const fontSize = 50;
      ctx.font = `${fontSize}px serif`;
      ctx.fillStyle = "rgba(212,212,212,0.5)";
      ctx.textAlign = "center";
      ctx.textBaseline = "middle";
      // 获取内容的宽度
      const cInfo = ctx.measureText(this.content);

      const spacing = [Math.max(300, width / 8), Math.max(300, height / 8)];
      const spaceWH = [cInfo.width + spacing[0], fontSize + spacing[1]];
      const spaceSize = Math.max(width, height);
      const wCount = Math.ceil(spaceSize / spaceWH[0]);
      const hCount = Math.ceil(spaceSize / spaceWH[1]);

      ctx.translate(width / 2, height / 2);
      ctx.rotate(angle);

      for (let i = 0; i < wCount; i++) {
        for (let j = 0; j < hCount; j++) {
          const x = -spaceSize / 2 + i * spaceWH[0];
          const y = -spaceSize / 2 + j * spaceWH[1];
          ctx.fillText(this.content, x, y);
        }
      }
    },
  },
};
</script>

<style>
.image-watermark img {
  display: block;
  width: 100%;
  height: auto;
}
</style>
