持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
在员工查看私密页面时,我们为了防止私密页面内容外泄,会在私密页面中打上当前查看人信息的水印,这样即使私密页面内容外泄了,也可以根据水印追究到具体责任人,接下来我们就采用前端的方式进行实现
页面结构
<div id="app">hello world</div>
样式
* {
margin: 0;
padding: 0;
}
#app {
width: 100vw;
height: 100vh;
}
结构和样式都比较简单,有个
#app内容盒子,里面放的是我们的私密内容,我们让私密内容盒子铺满整个屏幕
逻辑实现
我们这里实现采用canvas进行实现,声明一个水印函数,水印函数接收一个
config入参变量的配置对象(不传也有默认值),通过它配置我们canvas的水印效果,绘制出来后在将绘制的canvas导出成图片,新创建一个div元素在将canvas导出的图片以背景图的方式放到新创建的div元素中,给新创建div样式,使它能够完全贴合需要显示水印的元素,最后放到需要添加水印的容器中
// 执行水印函数
watermark()
/**
* @function 水印函数
* @param config {*} 水印配置文件
* **/
function watermark(config = {}) {
// 开启水印盒子,默认是body元素
let container = document.body;
// 水印宽度
let width = '150';
// 水印高度
let height = width / 3;
// 水印字体水平居中样式(默认水平居中)
let textAlign = "center";
// 文字垂直对齐方式(默认中线对齐)
let textVertical = "middle";
// 字体大小(默认16px)
let font = "16px serif";
// 默认文字颜色
let fillStyle = "rgba(204, 204, 204,0.5)";
// 默认内容
let content = "若水";
// 默认旋转角度
let rotate = "30";
// 由于我们使用的是定位的方式,所以需要设置一下定位层级
let posIndex = '10';
// 是否显示时间(默认显示)
let isTime = true;
// 将默认配置和用户传递进来的配置进行合并
let canvasConfig = Object.assign({ container, width, height, textAlign, textVertical, font, fillStyle, content, rotate, posIndex, isTime }, config);
// 创建canvas元素
const CANVAS = document.createElement('canvas');
// 设置canvas的宽高
CANVAS.style.cssText = `width:${canvasConfig.width}px;height = ${canvasConfig.height}px`;
// 给canvas插入不支持提示内容
CANVAS.innerText = '该浏览器不支持canvas元素,请更换其他浏览器重试!';
// 判断浏览器是否支持canvas元素,不支持则不进入
if (CANVAS.getContext) {
// 获取绘制上下文
const CANVASCONTENT = CANVAS.getContext('2d');
// 设置文字水平位置
CANVASCONTENT.textAlign = canvasConfig.textAlign;
// 设置文字垂直位置
CANVASCONTENT.textBaseline = canvasConfig.textVertical;
// 设置文字样式
CANVASCONTENT.font = canvasConfig.font;
// 设置文字颜色
CANVASCONTENT.fillStyle = canvasConfig.fillStyle;
// 文字显示位置
let textPosX = Math.trunc(canvasConfig.width) / 5;
let textPosY = Math.trunc(canvasConfig.height) / 2;
// 设置canvas平移位置
CANVASCONTENT.translate(textPosX, textPosY);
console.log(' 设置canvas平移位置', textPosX, textPosY);
// 设置旋转角度
CANVASCONTENT.rotate((-Math.trunc(canvasConfig.rotate) / 180) * Math.PI);
// 进行绘制文本内容
CANVASCONTENT.fillText(canvasConfig.content, textPosX, textPosY);
// 判断是否需要添加事件水印
if (isTime) {
// 获取当前时间
let currentTime = getCurrentTime();
// 添加时间内容
CANVASCONTENT.fillText(currentTime, textPosX, textPosY + 20);
}
// 将canvas导出成图片
const Base64URL = CANVAS.toDataURL();
// 创建一个div元素,用于存放水印图片
const watermarkDOM = document.createElement('div');
// 给创建的div元素设置样式
/** position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
这样可以让元素水平垂直居中
**/
// pointer-events: none;属性是让用户看的到但是鼠标点击不到,会直接穿透过去的效果
const watermarkDOMStyle = `
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
width: 100%;
height: 100%;
z-index: ${canvasConfig.posIndex};
pointer-events: none;
background: url('${Base64URL}');`;
// 将样式添加给水印盒子
watermarkDOM.style.cssText = watermarkDOMStyle;
// 水印容器样式
const containerStyle = `
position: relative;
width: 100%;
min-width: 100%;
`;
container.style.cssText = containerStyle;
// 插入父节点
container.appendChild(watermarkDOM);
}
}
/**
* @function 获取当前时间
* **/
function getCurrentTime() {
// 当前时间
let time = new Date();
// 拼接的年月份格式
let str = "年月日:";
// 处理补零
const getTime = str => {
return str.toString().padStart(2, 0)
}
// 获取当前时间或者是传入的时间
const T = time ? new Date(time) : new Date();
// 获取年
const Y = T.getFullYear()
// 获取月
const M = getTime(T.getMonth() + 1)
// 获取日
const D = getTime(T.getDate())
// 获取时
const H = getTime(T.getHours())
// 获取分
const B = getTime(T.getMinutes())
// 将处理后的时间进行返回
return `${Y}${str[0]}${M}${str[1]}${D}${str[2] && str[2] + ' '}${H}${str[3]}${B}`
}
坚持努力,无惧未来!