canvas 画背景图、logo、字幕,watermark-dom 加水印

<template>
  <div id="water-mark-wrapper" class="water-mark-wrapper" :style="[{width:canvasWidth+'px',height:canvasHeight+'px'}]">
    <!-- 背景图、LOGO、字幕 -->
    <canvas id="live-player-canvas" :width="canvasWidth" :height="canvasHeight"></canvas>
    <!-- 水印 -->
    <div id="watermark-box" class="watermark-box" :style="[{width:canvasWidth+'px',height:canvasHeight+'px'}]"></div>
  </div>
</template>
 
<script>
// 先执行 npm i watermark-dom --save
import watermark from 'watermark-dom';// 或者 var watermark = require("watermark-dom")

export default {
  data() {
    return {
      canvasWidth: 0,
      canvasHeight: 0,
      canvasImg: "",// 背景图路径
      canvasLogo: "",// LOGO路径
      canvasText: "",// 字幕
      canvasElement: null,
      watermarkText: "",// 水印文字,优先级:文字>图片
      watermarkImgUrl: "",// 水印图片
      haveWaterMark: false,// 水印是否已加
      canvasTextFlag: false
    }
  },
  beforeDestroy() {
    // 清空canvas
    if (this.canvasElement) {
      this.canvasElement.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.canvasElement = null;
    }
    // 清空水印
    if (this.haveWaterMark) {
      try {// 避免出现 Cannot read properties of null (reading 'parentNode') 的报错
        watermark.remove()
      } catch (err) {
        console.log(err)
        // 设置水印内容为空字符串
        // watermark.load(
        //   { watermark_id: "wm_div_id", watermark_txt: " " }
        // )
        watermark.load(
          {
            watermark_id: "wm_div_id",// 水印总体的id
            watermark_prefix: "mask_div_id",// 小水印的id前缀
            watermark_txt: "",// 水印文字的内容
            watermark_color: 'transparent',// 水印字体颜色,透明
            watermark_alpha: 0.2,// 水印透明度,要求设置大于等于0.005
            watermark_fontsize: '16px',// 水印字体大小
            watermark_width: 250,// 水印宽度
            watermark_height: 80,// 水印长度
            watermark_parent_node: 'watermark-box'// 水印插件挂载的父元素elementId,不输入则默认挂在body上
          }
        )
      }
      this.haveWaterMark = false;
    }
  },
  mounted() {
    // 计算宽高
    if (document.querySelector(".xxx")) {
      let ele = document.querySelector(".xxx");
      let rect = ele.getBoundingClientRect();
      this.canvasWidth = rect.width;
      this.canvasHeight = rect.width / 16 * 9;
    }
    window.addEventListener('resize', () => {
      if (this.haveWaterMark) {
        // 避免出现 Cannot read properties of null (reading 'parentNode') 的报错
        try {
          watermark.remove()
        } catch (err) {
          console.log(err)
          // 设置水印内容为空字符串
          // watermark.load(
          //   { watermark_id: "wm_div_id", watermark_txt: " " }
          // )
          watermark.load(
            {
              watermark_id: "wm_div_id",// 水印总体的id
              watermark_prefix: "mask_div_id",// 小水印的id前缀
              watermark_txt: "",// 水印文字的内容
              watermark_color: 'transparent',// 水印字体颜色,透明
              watermark_alpha: 0.2,// 水印透明度,要求设置大于等于0.005
              watermark_fontsize: '16px',// 水印字体大小
              watermark_width: 250,// 水印宽度
              watermark_height: 80,// 水印长度
              watermark_parent_node: 'watermark-box'// 水印插件挂载的父元素elementId,不输入则默认挂在body上
            }
          )
        }
        this.haveWaterMark = false;
      }
      if (document.querySelector(".xxx")) {
        // 计算宽高
        let ele = document.querySelector(".xxx");
        let rect = ele.getBoundingClientRect();
        this.canvasWidth = rect.width;
        this.canvasHeight = rect.width / 16 * 9;
        this.initWaterMark();
        this.initCanvas();
      }
    })
  },
  methods: {
    // 加水印
    initWaterMark() {
      this.$nextTick(() => {
        if (document.getElementById("watermark-box") && this.canvasWidth > 0 && this.canvasHeight > 0 && !this.haveWaterMark) {
          this.haveWaterMark = true;
          let that = this;
          try {
            if (that.watermarkText) {
              // 展示文字水印
              watermark.load(
                {
                  watermark_id: "wm_div_id",// 水印总体的id
                  watermark_prefix: "mask_div_id",// 小水印的id前缀
                  watermark_txt: that.watermarkText,// 水印文字的内容
                  watermark_color: 'white',// 水印字体颜色
                  watermark_alpha: 0.2,// 水印透明度,要求设置大于等于0.005
                  watermark_fontsize: '16px',// 水印字体大小
                  watermark_width: 100,// 水印宽度
                  watermark_height: 20,// 水印高度
                  watermark_parent_node: 'watermark-box',// 水印插件挂载的父元素elementId,不输入则默认挂在body上
                  // watermark_x: 20,// 水印起始位置x轴坐标
                  // watermark_y: 20,// 水印起始位置Y轴坐标
                  // watermark_rows: 0,// 水印行数
                  // watermark_cols: 0,// 水印列数
                  // watermark_x_space: 100,// 水印x轴间隔
                  // watermark_y_space: 50,// 水印y轴间隔
                  // watermark_font: '微软雅黑',// 水印字体
                  // watermark_angle: 15,// 水印倾斜度数
                  // watermark_parent_width: 0,// 水印的总体宽度(默认值:body的scrollWidth和clientWidth的较大值)
                  // watermark_parent_height: 0,// 水印的总体高度(默认值:body的scrollHeight和clientHeight的较大值)
                }
              )
            } else {
              // 展示图片水印
              watermark.load(
                {
                  watermark_id: "wm_div_id",// 水印总体的id
                  watermark_prefix: "mask_div_id",// 小水印的id前缀
                  watermark_txt: "",// 水印文字的内容
                  watermark_color: 'transparent',// 水印字体颜色,透明
                  watermark_alpha: 0.2,// 水印透明度,要求设置大于等于0.005
                  watermark_fontsize: '16px',// 水印字体大小
                  watermark_width: 150,// 水印宽度
                  watermark_height: 150,// 水印长度
                  watermark_parent_node: 'watermark-box'// 水印插件挂载的父元素elementId,不输入则默认挂在body上
                }
              )
              // 延迟,确保页面渲染完成
              setTimeout(() => {
                // 小水印内容替换成图片
                let elements = document.querySelector('#wm_div_id').shadowRoot.querySelectorAll('div[id^="mask_div_id"]');
                elements.forEach(function (element) {
                  element.innerHTML = '<img src="' + that.watermarkImgUrl + '" style="max-width:100%;max-height:100%;"/>';
                });
              }, 3000);
            }
            console.log("水印设置成功")
          } catch (err) {
            console.log(err)
          }
        }
      })
    },
    // 加背景图、LOGO、字幕
    initCanvas() {
      // 清空canvas
      if (this.canvasElement) {
        this.canvasElement.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
        this.canvasElement = null;
      }
      if (!this.canvasElement && this.canvasWidth > 0 && this.canvasHeight > 0) {
        this.$nextTick(async () => {
          let canvas = document.getElementById('live-player-canvas');
          let ctx = canvas.getContext('2d');
          this.canvasElement = ctx;
          let that = this;
          // 图片从最底层到最高层依次绘制
          if (this.canvasImg && this.canvasImg != "") {
            // 背景图
            await this.drawCanvas(1, 0, 0, that.canvasWidth, that.canvasHeight).then((res) => {
              if (res == 0) {
                console.log("底图设置成功");
              } else {
                console.log("底图设置失败");
              }
            });
          }
          if (this.canvasLogo && this.canvasLogo != "") {
            // logo
            let x = that.canvasHeight * 0.03;
            let y = that.canvasHeight * 0.03;
            await this.drawCanvas(2, x, y, that.canvasHeight * 0.11, that.canvasHeight * 0.11).then((res) => {
              if (res == 0) {
                console.log("LOGO设置成功");
              } else {
                console.log("LOGO设置失败");
              }
            });
          }

          setTimeout(async () => {
            if (this.canvasText && this.canvasText != "") {
              // 字幕
              let textWidth = ctx.measureText(that.canvasText).width;// 计算字幕长度
              if (!this.canvasTextFlag) {
                this.canvasTextFlag = true;
                await this.drawCanvas(3, (that.canvasWidth * 0.5 - textWidth / 2) > 0 ? (that.canvasWidth * 0.5 - textWidth / 2) : 0, that.canvasHeight * 0.93, Math.floor(that.canvasWidth - that.canvasHeight * 0.02)).then((res) => {
                  if (res == 0) {
                    console.log("字幕设置成功");
                  } else {
                    console.log("字幕设置失败");
                  }
                });
              }
            }
          }, 2000)
        })
      }
    },
    drawCanvas(type, x, y, w, h) {
      // type:1-底图 2-LOGO 3-字幕
      return new Promise((resolve, reject) => {
        let res = resolve;
        let rej = reject;
        let that = this;
        // 1-底图 2-LOGO
        if (type == 1 || type == 2) {
          let img = new Image();
          img.crossOrigin = 'anonymous';
          img.src = type == 1 ? that.canvasImg : that.canvasLogo;
          img.onload = () => {
            that.canvasElement.drawImage(img, x, y, type == 1 ? w : (img.width / img.height * h), h);
            if (type == 1) {
              that.canvasElement.clearRect(0, that.canvasHeight * 0.17, that.canvasWidth, that.canvasHeight * 0.66);
            }
            res(0);
          };
          img.onerror = () => {
            rej("加载失败");
          };
          if (img.complete) {
            res(0);
          }
        } else if (that.canvasTextFlag) {
          // 3-字幕
          that.canvasTextFlag = false;
          that.canvasElement.font = that.canvasHeight * 0.04 + "px Arial";
          that.canvasElement.fillStyle = "red";
          that.canvasElement.fillText(that.canvasText, x, y, w);
          res(0);
        }
      });
    },
  },
};
</script>
 
<style scoped>
.water-mark-wrapper {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1000;
}
#live-player-canvas {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1001;
}
.watermark-box {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 1002;
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值