From ce295cc521128457d45ef452e9806189f3ca9024 Mon Sep 17 00:00:00 2001 From: kun <1422840143@qq.com> Date: Thu, 21 Sep 2023 18:54:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B0=B4=E5=8D=B0=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/directives/modules/waterMarker copy.ts | 93 +++++++++++++++++++ src/directives/modules/waterMarker.ts | 67 ++++++++++++- .../acceptancePlan/index.scss | 13 +++ .../acceptancePlan/index.vue | 2 +- 4 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 src/directives/modules/waterMarker copy.ts diff --git a/src/directives/modules/waterMarker copy.ts b/src/directives/modules/waterMarker copy.ts new file mode 100644 index 0000000..7f1494c --- /dev/null +++ b/src/directives/modules/waterMarker copy.ts @@ -0,0 +1,93 @@ +/* + 需求:给整个页面添加背景水印。 + + 思路: + 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; +`; +let str: string = ""; +let font: any = null; +let textColor: string = ""; +import type { Directive, DirectiveBinding } from "vue"; +const addWaterMarker: Directive = (str: string, parentNode: any, font: any, textColor: string) => { + str = str || ""; + font = font || "16px Microsoft JhengHei"; + textColor = textColor || "rgba(180, 180, 180, 0.3)"; + // 水印文字,父元素,字体,文字颜色 + 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 = font || "16px Microsoft JhengHei"; + cans.fillStyle = textColor || "rgba(180, 180, 180, 0.3)"; + cans.textAlign = "left"; + cans.textBaseline = "Middle" as CanvasTextBaseline; + cans.fillText(str, 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: DirectiveBinding, binding: DirectiveBinding) { + // addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); + el.onload = init.bind(null, 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 = {}) => { + // 设置水印 + addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); + // 启动监控 + createObserver(el, binding.value); +}; +export default waterMarker; diff --git a/src/directives/modules/waterMarker.ts b/src/directives/modules/waterMarker.ts index c3e4f74..11362a7 100644 --- a/src/directives/modules/waterMarker.ts +++ b/src/directives/modules/waterMarker.ts @@ -8,9 +8,26 @@ 使用:设置水印文案,颜色,字体大小即可
*/ - +// watermark 样式 +let style = ` + display: block; + overflow: hidden; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-repeat: repeat; + pointer-events: none; +`; +let str: string = ""; +let font: any = null; +let textColor: string = ""; import type { Directive, DirectiveBinding } from "vue"; -const addWaterMarker: Directive = (str: string, parentNode: any, font: any, textColor: string) => { +const addWaterMarker = (parentNode: any, binding: { str: string; font: any; textColor: string }) => { + str = str || ""; + font = font || "16px Microsoft JhengHei"; + textColor = textColor || "rgba(180, 180, 180, 0.3)"; // 水印文字,父元素,字体,文字颜色 let can: HTMLCanvasElement = document.createElement("canvas"); parentNode.appendChild(can); @@ -24,13 +41,53 @@ const addWaterMarker: Directive = (str: string, parentNode: any, font: any, text cans.textAlign = "left"; cans.textBaseline = "Middle" as CanvasTextBaseline; cans.fillText(str, can.width / 10, can.height / 2); - parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")"; + + // 创建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: DirectiveBinding, binding: DirectiveBinding) { - addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); + mounted(el: HTMLElement, binding: any) { + // addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor); + el.onload = init.bind(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 = {}) => { + // 设置水印 + addWaterMarker(el, binding.value); + // 启动监控 + createObserver(el, binding.value); +}; export default waterMarker; diff --git a/src/views/goverment/engineeringAcceptance/acceptancePlan/index.scss b/src/views/goverment/engineeringAcceptance/acceptancePlan/index.scss index ffb8729..1b12d1c 100644 --- a/src/views/goverment/engineeringAcceptance/acceptancePlan/index.scss +++ b/src/views/goverment/engineeringAcceptance/acceptancePlan/index.scss @@ -3,6 +3,7 @@ display: flex; width: 100%; height: 100%; + position: relative; .leftMenu { width: 300px; border-radius: 8px; @@ -92,3 +93,15 @@ width: 300px; } } +.water-mark { + display: inline-block; + overflow: hidden; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + pointer-events: none; + background-repeat: repeat; + z-index: 10; +} diff --git a/src/views/goverment/engineeringAcceptance/acceptancePlan/index.vue b/src/views/goverment/engineeringAcceptance/acceptancePlan/index.vue index d4fe305..d43d591 100644 --- a/src/views/goverment/engineeringAcceptance/acceptancePlan/index.vue +++ b/src/views/goverment/engineeringAcceptance/acceptancePlan/index.vue @@ -1,5 +1,5 @@