canvas的toDataURL()方法是返回一个包含图片展示的 数据URL。
可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。
一、语法
canvas.toDataURL(type, encoderOptions);
二、参数1、type:图片格式,默认为 image/png,可以是其他image/jpeg等
2、encoderOptions:0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值。
三、返回值
返回值是一个数据url,是base64组成的图片的源数据、可以直接赋值给图片的src属性。
注意事项:设置的宽度高度不易过大或者高度或宽度是0,会导致 canvas.toDataURL()返回为data:,,从而不生成图片地址
设置pointer-events:none;样式实现点击穿透,在这个容器内通过js生成小的水印div,每个水印div内展示一个要显示的水印内容,样式repeat重复铺满整个容器
// 定义水印函数
function addWatermark({
container = document.body, // 水印添加到的容器,默认为 body
width = "200px", // 水印 canvas 的宽度
height = "100px", // 水印 canvas 的高度
textAlign = "center", // 水印文字的对齐方式
textBaseline = "middle", // 水印文字的基线
font = "16px Microsoft Yahei", // 水印文字的字体
fillStyle = "rgba(184, 184, 184, 0.6)", // 水印文字的填充样式
content = '名称', // 水印文字的内容
rotate = -30, // 水印文字的旋转角度
zIndex = 10000, // 水印的 z-index 值
}) {
// 生成水印 canvas
const canvas = document.createElement("canvas");
canvas.setAttribute("width", width);
canvas.setAttribute("height", height);
const ctx: any = canvas.getContext("2d");
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
ctx.font = font;
ctx.fillStyle = fillStyle;
ctx.rotate((Math.PI / 180) * rotate);
ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 1);
// 将 canvas 转换为 base64 URL
const base64Url = canvas.toDataURL('image/png');
console.log(base64Url)
const __wm = document.querySelector('.__wm');
const watermarkDiv = __wm || document.createElement("div");
const styleStr = `
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
z-index: ${zIndex};
pointer-events: none;
background: url('${base64Url}') left top repeat;
`;
watermarkDiv.setAttribute("style", styleStr);
watermarkDiv.classList.add("__wm");
//则创建一个 div 并设置样式和类名
if (!__wm) {
container.style.position = 'relative';
container.insertBefore(watermarkDiv, container.firstChild);
}
// 监听容器变化,当容器发生变化时重新调用 addWatermark 函数
const MutationObserver = window.MutationObserver;
if (MutationObserver) {
let mo = new MutationObserver(function () {
const __wm = document.querySelector('.__wm');
// 只在__wm元素变动才重新调用__canvasWM
if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
// 避免一直触发
mo.disconnect();
mo = new MutationObserver(() => { });
console.log('1');
addWatermark({
container: document.getElementById("app") as HTMLElement,
width: '200px',
height: '100px',
textAlign: "center",
textBaseline: "middle",
font: "16px Microsoft Yahei",
fillStyle: "rgba(184, 184, 184, 0.3 )",
content: '名称',
rotate: -30,
zIndex: 10000
});
}
});
mo.observe(container, {
attributes: true,
subtree: true,
childList: true
});
}
}
export default addWatermark
结合项目技术栈vue3.0+ts
需要全局使用,则可以在App.vue文件中引入js文件并使用该函数
<template>
<!-- 路由的渲染出口 -->
<el-config-provider :locale="locale">
<router-view />
</el-config-provider>
</template>
<script lang="ts" setup>
import { onMounted } from 'vue'
import addWatermark from './waterMark/index'
import locale from 'element-plus/lib/locale/lang/zh-cn'
import { useUserStore } from '@/stores/user'
const user = useUserStore() // 此处使用到获取登录账号信息拿到姓名
onMounted(() => {
// 调用 addWatermark 函数添加水印
addWatermark({
container: document.getElementById("app") as HTMLElement,
width: '200px',
height: '100px',
textAlign: "center",
textBaseline: "middle",
font: "16px Microsoft Yahei",
fillStyle: "rgba(184, 184, 184, 0.3 )",
content: user.name,
rotate: -30,
zIndex: 10000,
});
})
</script>