在员工查看私密页面时,我们为了防止私密页面内容外泄,会在私密页面中打上当前查看人信息的水印,这样即使私密页面内容外泄了,也可以根据水印追究到具体责任人,接下来我们就采用前端的方式进行实现
页面结构
<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}` }
坚持努力,无惧未来!