<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>
canvas 画背景图、logo、字幕,watermark-dom 加水印
于 2025-03-21 17:45:55 首次发布
478

被折叠的 条评论
为什么被折叠?



