一、前言
-
之前看到element的水印功能比较有意思,特意学习了一下水印的方法,在生成基本水印的基础上又进行了二次封装,可适用多场景,vue项目也可以搭配路由、用户信息等等进行使用。
-
核心是通过创建一个canvas元素,并在其上绘制水印文本,然后将canvas转换为图片格式,再将该图片设置为一个div元素的背景,参数可以指定将水印添加到哪个DOM元素上,不同标识符可添加不同dom。
二、代码注释详解
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box">
<div class="box1">box1</div>
<div class="box2">box2</div>
<div class="box3">box3</div>
</div>
</body>
<script>
// 参数
// str---水印文本 用来展示的文字
// id---唯一ID 当前水印区域的唯一标识,用于区分多个区域水印
// dom---DOM元素类名 传入类名则为区域水印,否则全屏水印
const setWatermark = (str, id, dom) => {
// 如果页面上已经存在该ID的水印元素,则先移除
if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id));
// 创建一个canvas元素,用于绘制水印
const can = document.createElement('canvas');
// 设置canvas的宽度和高度
can.width = 200;
can.height = 130;
// 获取canvas的2d绘图上下文
const cans = can.getContext('2d');
// 旋转绘图上下文,设置水印的倾斜角度
cans.rotate((-20 * Math.PI) / 180);
// 设置水印文本的字体样式和大小
cans.font = '14px Vedana';
// 设置水印文本的颜色和透明度
cans.fillStyle = 'rgba(200, 200, 200, 0.30)';
// 设置水印文本的基线对齐方式
cans.textBaseline = 'middle';
// 在canvas上绘制水印文本
cans.fillText(str, can.width / 10, can.height / 2);
// 创建一个变量用于接收DOM
let div;
// 如果传入了dom参数,则获取该类名的DOM元素,将水印添加到该元素上
if (dom) {
div = document.querySelector('.' + dom)
} else {
// 如果没有传入dom参数,则创建一个新的div元素,并设置其宽高为页面宽高
div = document.createElement('div');
div.style.width = `${document.documentElement.clientWidth}px`;
div.style.height = `${document.documentElement.clientHeight}px`;
// 设置div元素的位置为页面左上角
div.style.top = '0px';
div.style.left = '0px';
// 设置div元素的定位方式为固定定位,使其不随页面滚动而移动
div.style.position = 'fixed';
// 将新创建的div元素添加到body元素中
document.body.appendChild(div);
}
// 设置div元素的ID,用于后续识别和移除水印
div.id = id;
// 设置div元素不参与鼠标事件,避免影响页面其他元素的交互
div.style.pointerEvents = 'none';
// 设置div元素的z-index层级非常高,确保其显示在页面其他元素之上
div.style.zIndex = '10000000';
// 设置div元素的背景为水印图片,并设置为重复显示,从而铺满整个页面
div.style.background = `url(${can.toDataURL('image/png')}) left top repeat`;
// 返回水印元素的ID,可用于后续移除水印
return id;
};
// 调用传参 vue项目中此处可以在路由监听中与携带参数交互或者根据登陆者信息等交互,其他场景可以自行开发
// 第一种 全屏水印
setWatermark('全屏水印', '1');
// 第二种 指定dom水印
// setWatermark('指定dom水印', 11, 'box1');
// 第二种 多个dom水印
// setWatermark('多个dom水印', 111, 'box1');
// setWatermark('多个dom水印', 222, 'box2');
// setWatermark('多个dom水印', 333, 'box3');
</script>
<style>
.box {
display: flex;
}
.box1,
.box2,
.box3 {
width: 500px;
height: 500px;
line-height: 500px;
text-align: center;
margin-right: 10px;
border: 1px solid red;
}
</style>
</html>