/* 需求:给整个页面添加背景水印。 思路: 1、使用 canvas 特性生成 base64 格式的图片文件,设置其字体大小,颜色等。 2、将其设置为背景图片,从而实现页面或组件水印效果 使用:设置水印文案,颜色,字体大小即可
*/ // watermark 样式 let style = ` display: block; overflow: hidden; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-repeat: repeat; pointer-events: none; `; import type { Directive, DirectiveBinding } from "vue"; const addWaterMarker = (parentNode: any, binding: any = {}) => { console.log(binding); // 水印文字,父元素,字体,文字颜色 let can: HTMLCanvasElement = document.createElement("canvas"); parentNode.appendChild(can); can.width = 205; can.height = 140; can.style.display = "none"; let cans = can.getContext("2d") as CanvasRenderingContext2D; cans.rotate((-20 * Math.PI) / 180); cans.font = binding.font || "16px Microsoft JhengHei"; cans.fillStyle = binding.textColor || "rgba(180, 180, 180, 0.3)"; cans.textAlign = "left"; cans.textBaseline = "Middle" as CanvasTextBaseline; cans.fillText(binding.text, can.width / 10, can.height / 2); // 创建waterMark父元素 const waterMark = document.createElement("div"); waterMark.className = `water-mark`; // 方便自定义展示结果 style = `${style}background-image: url(${can.toDataURL("image/png")})`; waterMark.setAttribute("style", style); // 将对应图片的父容器作为定位元素 parentNode.setAttribute("style", "position:relative;"); // 将图片元素移动到waterMark中 parentNode.appendChild(waterMark); // parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")"; }; const waterMarker = { mounted(el: HTMLElement, binding: any) { console.log(666); // addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); el.onload = init(el, binding); } }; // 监听DOM变化 const createObserver = (el: HTMLElement, binding: any) => { const waterMarkEl = el.parentElement?.querySelector(".water-mark"); const observer = new MutationObserver(mutationsList => { if (mutationsList.length) { const { removedNodes, type, target } = mutationsList[0]; const currStyle = waterMarkEl?.getAttribute("style"); // 证明被删除了 if (removedNodes[0] === waterMarkEl) { observer.disconnect(); init(el, binding); } else if (type === "attributes" && target === waterMarkEl && currStyle !== style) { waterMarkEl.setAttribute("style", style); } } }); observer.observe(el.parentElement, { childList: true, attributes: true, subtree: true }); }; const init = (el: HTMLElement, binding: any = {}) => { console.log(666); // 设置水印 addWaterMarker(el, binding.value); // 启动监控 createObserver(el, binding.value); }; export default waterMarker;