watermark.vue 2.44 KB
<template>
  <div ref="layer" class="watermark-layer"></div>
</template>

<script>
export default {
  name: 'WatermarkLayer',
  props: {
    width: Number,
    height: Number,
    text: String,
  },
  mounted() {
    if (this.width && this.height && this.text) {
      this.init();
    }
  },
  methods: {
    init() {
      const layerEl = this.$refs.layer;
      console.log('layerEl', layerEl);
      if (layerEl) {
        const canvas = this.createCanvas();
        layerEl.style.width = this.width + 'px';
        layerEl.style.height = this.height + 'px';
        layerEl.appendChild(canvas);
      }
    },
    /**
     * image 图片对象,用于截图加水印
     * 外部可直接调用,传入image对象,给图片加水印
     */
    createCanvas(image) {
      const canvas = document.createElement('canvas');
      canvas.width = 400;
      canvas.height = 300;
      // canvas.height = this.height - 40; // 40为底部工具条
      canvas.className = 'watermark';
      console.log('createCanvas', canvas);

      // 获取 Canvas 上下文
      const ctx = canvas.getContext('2d');

      // 在 Canvas 上绘制原始图片
      if (image) {
        ctx.drawImage(image, 0, 0);
      }

      // 绘制水印文本
      ctx.font = '24px Arial';
      ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';

      // 定义水印内容
      const watermarkText = this.text;

      // 定义水印间隔和边距
      // TODO: 未兼容移动端
      const watermarkIntervalX = 80; // 水印之间的水平间隔
      const watermarkIntervalY = 80; // 水印之间的垂直间隔
      const watermarkMarginX = 30; // 水印距离左边的边距
      const watermarkMarginY = 0; // 水印距离顶部的边距

      // 循环绘制水印
      for (let x = watermarkMarginX; x < canvas.width; x += watermarkIntervalX) {
        for (let y = watermarkMarginY; y < canvas.height; y += watermarkIntervalY) {
          // 保存当前绘图状态以便恢复
          ctx.save();

          // 将坐标原点移动到水印位置
          ctx.translate(x, y);

          // 旋转文本
          ctx.rotate(-Math.PI / 4); // 旋转-45度(以弧度表示)

          // 绘制水印文本
          ctx.fillText(watermarkText, 0, 0);

          // 恢复绘图状态
          ctx.restore();
        }
      }

      return canvas;
    },
  },
}
</script>

<style lang="scss" scoped>
.watermark-layer {
  ::v-deep(canvas) {
    width: 100%;
    height: 100%;
  }
}
</style>