网站和小程序的区别,asp建的网站上传文章,wordpress数据可视化,重庆市建设工程信息网打印经常有一些公司和组织出于系统文件或信息安全保密的需要#xff0c;需要在系统网页上增加带有个人标识#xff08;系统账号或个人信息#xff09;的水印#xff0c;可以简单防止截图外传首先我们来看这样一个水印功能的实现思路#xff0c;通常是在我们原有的网页上附上一… 经常有一些公司和组织出于系统文件或信息安全保密的需要需要在系统网页上增加带有个人标识系统账号或个人信息的水印可以简单防止截图外传首先我们来看这样一个水印功能的实现思路通常是在我们原有的网页上附上一个 DIV 层将它设置绝对定位铺满整个窗口然后 z-index 值尽量往大了设保证让水印层处于当前网页所有元素的上面又不影响当前网页的操作。水印上的字体有两种方式添加第一种直接将字体用块元素包裹动态设置绝对定位然后通过 transform 属性旋转第二种通过在 canvas 上绘制出字体设置好样式然后以图片的样式导出最后用图片作为水印层的背景图。出于性能方面考虑第二种方式最优。我们来看具体怎么实现作为一块独立的功能我们在 Vue3 中常用 hooks 来实现通过分析我们概括出实现水印需要的几个功能函数和对外接口对外接口清除水印clear设置水印setWatermark核心功能函数绘制文字背景图createBase64绘制水印层createWatermark页面随窗口大小调整更新updateWatermarkexport function useWatermark(appendEl: RefHTMLElement | null  ref(document.body) as RefHTMLElement
) {// 绘制文字背景图function createBase64() {}// 绘制水印层const createWatermark  ()  {};// 页面随窗口调整更新水印function updateWatermark(){}// 对外提供的设置水印方法function setWatermark() {}// 清除水印const clear  ()  {};return { setWatermark, clear };
}有了代码框架就只需要实现函数和接口的内部实现了另外还要考虑传参来实现代码复用的灵活度和接口参数的可配置。我们从具体的功能函数开始绘制文字背景图这里的参数 str 就是要添加的水印文字attr 为文字样式的属性我们定义了属性的类型为 attr它包含文字的字体和大小以及颜色等值function createBase64(str: string, attr?: attr) {const can  document.createElement(canvas);const width  200;const height  140;Object.assign(can, { width, height });const cans  can.getContext(2d);if (cans) {cans.rotate((-20 * Math.PI) / 120);cans.font  attr?.font ?? 12px Reggae One;cans.fillStyle  attr?.fillStyle ?? rgba(0, 0, 0, 0.12);cans.textAlign  left;cans.textBaseline  middle;cans.fillText(str, width / 20, height);}return can.toDataURL(image/png);}type attr  {font?: string;fillStyle?: string;
};绘制水印层这个函数的主要逻辑是先判断如果已经绘制了水印层直接调用更新水印方法如果还没有先动态创建一个 DIV 层设置绝对定位铺满当前整个浏览器窗口。const id  domSymbol.toString();
const watermarkEl  shallowRefHTMLElement();const createWatermark  (str: string, attr?: attr)  {if (unref(watermarkEl)) {updateWatermark({ str, attr });return id;}const div  document.createElement(div);watermarkEl.value  div;div.id  id;div.style.pointerEvents  none;div.style.top  0px;div.style.left  0px;div.style.position  absolute;div.style.zIndex  100000;const el  unref(appendEl);if (!el) return id;const { clientHeight: height, clientWidth: width }  el;updateWatermark({ str, width, height, attr });el.appendChild(div);return id;};更新水印因为更新水印方法主要是根据当前窗口高度和宽度来的更新水印背景的设置利用一张 Base64 格式的图片平铺即可。function updateWatermark(options: {width?: number;height?: number;str?: string;attr?: attr;}  {}) {const el  unref(watermarkEl);if (!el) return;if (options.width ! undefined) {el.style.width  ${options.width}px;}if (ioptions.height ! undefined) {el.style.height  ${options.height}px;}if (options.str ! undefined) {el.style.background  url(${createBase64(options.str,options.attr)}) left top repeat;}}到此我们实现了主要的三个功能函数下面就是两个对外接口设置水印这里的主要点是考虑设置页面resize监听来及时更新水印的位置。还要考虑 Vue 的生命周期当我们卸载页面的时候要进行清除水印。function setWatermark(str: string, attr?: attr) {createWatermark(str, attr);addResizeListener(document.documentElement, func);const instance  getCurrentInstance();if (instance) {onBeforeUnmount(()  {clear();});}}const func  throttle(function () {const el  unref(appendEl);if (!el) return;const { clientHeight: height, clientWidth: width }  el;updateWatermark({ height, width });});清除水印清除水印的时候顺便移除窗口大小监听函数const clear  ()  {const domId  unref(watermarkEl);watermarkEl.value  undefined;const el  unref(appendEl);if (!el) return;domId  el.removeChild(domId);removeResizeListener(el, func);};水印功能 hooks 的使用import { useWatermark } from //hooks/watermark;
const { setWatermark, clear }  useWatermark();onMounted(()  {nextTick(()  {setWatermark(watermarkText.value);});
});onBeforeUnmount(()  {clear();
});至此Vue3 版的网页水印功能实现全部完成。这里水印的字体大小、颜色和排布参考了企业微信的背景水印使得看起来不那么突兀。- END -