vue 水印組件

Watermark.vue

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue';interface Props {text?: string;fontSize?: number;color?: string;rotate?: number;zIndex?: number;gap?: number;
}const props = withDefaults(defineProps<Props>(), {text: 'Watermark',fontSize: 16,color: 'rgba(0, 0, 0, 0.1)',rotate: -45,zIndex: 1000,gap: 100
});const watermarkRef = ref<HTMLDivElement>();
const containerRef = ref<HTMLDivElement>();
let observer: MutationObserver | null = null;
let styleObserver: MutationObserver | null = null;
let securityInterval: number | null = null;const createWatermark = () => {const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');if (!ctx) return '';ctx.font = `${props.fontSize}px Arial`;const textWidth = ctx.measureText(props.text).width;const width = textWidth + props.gap;const height = props.fontSize + props.gap;canvas.width = width;canvas.height = height;ctx.translate(width / 2, height / 2);ctx.rotate((props.rotate * Math.PI) / 180);ctx.font = `${props.fontSize}px Arial`;ctx.fillStyle = props.color;ctx.textAlign = 'center';ctx.textBaseline = 'middle';ctx.fillText(props.text, 0, 0);return canvas.toDataURL();
};const applyWatermark = () => {if (!watermarkRef.value) return;const url = createWatermark();const originalStyles = {position: 'absolute',top: '0',left: '0',width: '100%',height: '100%',pointerEvents: 'none',backgroundImage: `url(${url})`,backgroundRepeat: 'repeat',userSelect: 'none',webkitUserSelect: 'none',zIndex: props.zIndex.toString(),opacity: '1',display: 'block',visibility: 'visible'};Object.assign(watermarkRef.value.style, originalStyles);
};const observeContainer = () => {if (!containerRef.value || !watermarkRef.value) return;observer = new MutationObserver((mutations) => {mutations.forEach((mutation) => {if (mutation.type === 'childList') {const removedNodes = Array.from(mutation.removedNodes);if (removedNodes.includes(watermarkRef.value!)) {containerRef.value?.appendChild(watermarkRef.value!);applyWatermark();}}});});observer.observe(containerRef.value, {childList: true,subtree: true,attributes: true});
};const observeWatermark = () => {if (!watermarkRef.value) return;styleObserver = new MutationObserver(() => {applyWatermark();});styleObserver.observe(watermarkRef.value, {attributes: true,attributeFilter: ['style', 'class']});
};const startSecurityCheck = () => {securityInterval = window.setInterval(() => {if (!watermarkRef.value?.isConnected) {containerRef.value?.appendChild(watermarkRef.value!);}applyWatermark();}, 100) as unknown as number;
};watch(() => [props.text, props.fontSize, props.color, props.rotate, props.gap], () => {applyWatermark();
});onMounted(() => {applyWatermark();observeContainer();observeWatermark();startSecurityCheck();
});onUnmounted(() => {observer?.disconnect();styleObserver?.disconnect();if (securityInterval) {clearInterval(securityInterval);}
});
</script><template><div ref="containerRef" class="watermark-container"><div ref="watermarkRef" class="watermark"></div><div class="content"><slot></slot></div></div>
</template><style scoped>
.watermark-container {position: relative;width: 100%;height: 100%;
}.watermark {position: absolute;top: 0;left: 0;width: 100%;height: 100%;pointer-events: none;background-repeat: repeat;user-select: none;-webkit-user-select: none;
}.content {position: relative;width: 100%;height: 100%;
}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82293.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82293.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82293.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hbuilder中h5轉為小程序提交發布審核

【注意】 [HBuilder] 11:59:15.179 此應用 DCloud appid 為 __UNI__9F9CC77 &#xff0c;您不是這個應用的項目成員。1、聯系這個應用的所有者&#xff0c;請求加入項目成員&#xff08;https://dev.dcloud.net.cn "成員管理"-"添加項目成員"&#xff09;…

QT之INI、JSON、XML處理

文章目錄 INI文件處理寫配置文件讀配置文件 JSON 文件處理寫入JSON讀取JSON XML文件處理寫XML文件讀XML文件 INI文件處理 首先得引入QSettings QSettings 是用來存儲和讀取應用程序設置的一個類 #include "wrinifile.h"#include <QSettings> #include <QtD…

道德經總結

道德經 《道德經》是中國古代偉大哲學家老子所著&#xff0c;全書約五千字&#xff0c;共81章&#xff0c;分為“道經”&#xff08;1–37章&#xff09;和“德經”&#xff08;38–81章&#xff09;兩部分。 《道德經》是一部融合哲學、政治、人生智慧于一體的經典著作。它提…

行為型:迭代器模式

目錄 1、核心思想 2、實現方式 2.1 模式結構 2.2 實現案例 3、優缺點分析 4、適用場景 1、核心思想 目的&#xff1a;將遍歷邏輯與數據存儲結構解耦 概念&#xff1a;提供一種機制來按順序訪問集合中的各元素&#xff0c;而不需要知道集合內部的構造 舉例&#xff1a;…

人臉識別技術合規備案最新政策詳解

《人臉識別技術應用安全管理辦法》將于2025年6月1日正式實施&#xff0c;該辦法從技術應用、個人信息保護、技術替代、監管體系四方面構建了人臉識別技術的治理框架&#xff0c;旨在平衡技術發展與安全風險。 一、明確技術應用的邊界 公共場所使用限制&#xff1a;僅在“維護公…

如何把vue項目部署在nginx上

1&#xff1a;在vscode中把vue項目打包會出現dist文件夾 按照圖示內容即可把vue項目部署在nginx上

奇好 PDF安全加密 + 自由拆分合并批量處理 OCR 識別

各位辦公小能手們&#xff0c;你們好呀&#xff01;今天我要給大家介紹一款超厲害的軟件——奇好PDF。它就像是一個PDF文檔處理的超級大管家&#xff0c;啥功能都有&#xff0c;格式轉換、編輯、提取、安全保護這些統統不在話下&#xff0c;不管是辦公、學習&#xff0c;還是設…

Docker-Harbor 私有鏡像倉庫使用指南

1.用戶管理 為項目創建專用用戶&#xff0c;并配置權限&#xff0c;確保該用戶能夠順利推送鏡像到 Harbor 倉庫&#xff0c;確保鏡像推送操作的安全性和便捷性。 創建完成后可以根據需要選擇是否設置為管理員 角色 權限描述 適用場景 系統管理員 擁有系統的完全控制權限 運維…

HomeAssistant開源的智能家居docker快速部署實踐筆記(CentOS7)

1. SGCC_Electricity 應用介紹 SGCC_Electricity 是一個用于將國家電網&#xff08;State Grid Corporation of China&#xff0c;簡稱 SGCC&#xff09;的電費和用電量數據接入 Home Assistant 的自定義集成組件。通過該應用&#xff0c;用戶可以實時追蹤家庭用電量情況&…

maven 3.0多線程編譯提高編譯速度

mvn package 默認只使用 單線程 來執行構建生命周期&#xff08;即順序地構建每一個模塊&#xff09;。 如果你使用的是多模塊項目&#xff0c;Maven 從 3.0 開始提供了**并行構建&#xff08;parallel build&#xff09;**的能力&#xff0c;但它不是默認開啟的。 如何啟用多…

python模塊管理環境變量

概要 在 Python 應用中&#xff0c;為了將配置信息與代碼分離、增強安全性并支持多環境&#xff08;開發、測試、生產&#xff09;運行&#xff0c;使用專門的模塊來管理環境變量是最佳實踐。常見工具包括&#xff1a; 標準庫 os.environ&#xff1a;直接讀取操作系統環境變量…

K8s 集群運行時:從 Docker 升級到 Containerd

一、背景&#xff1a;Kubernetes容器運行時演進史 自2020年Kubernetes 1.20版本宣布棄用Docker作為默認容器運行時以來&#xff0c;容器技術生態經歷了重大變革。作為CNCF畢業項目&#xff0c;Containerd憑借其輕量化架構、原生CRI支持和卓越性能表現&#xff0c;逐漸成為云原生…

30-消息隊列

一、消息隊列概述 隊列又稱消息隊列&#xff0c;是一種常用于任務間通信的數據結構&#xff0c;隊列可以在任務與任務間、 中斷和任務間傳遞信息&#xff0c;實現了任務接收來自其他任務或中斷的不固定長度的消息&#xff0c;任務能夠從隊列里面讀取消息&#xff0c;當隊列中的…

AI Agent開發第74課-解構AI偽需求的魔幻現實主義

開篇 ??在之前的系列中我們狂炫了AI Agent的各種高端操作(向量數據庫聯動、多模態感知、動態工作流等…),仿佛每個程序員都能用LLM魔法點石成金?。 但今天咱們要潑一盆透心涼的冷水——當企業把AI當成萬能膠水強行粘合所有需求時,連電風扇都能被玩出量子糾纏的魔幻現實…

低代碼AI開發新趨勢:Dify平臺化開發實戰

在人工智能快速發展的今天&#xff0c;AI應用的開發方式也在不斷演變。從傳統的手寫代碼到如今的低代碼甚至零代碼開發&#xff0c;技術的進步讓更多的非專業開發者也能輕松上手。本文將帶你走進Dify平臺化開發的世界&#xff0c;探索如何通過這一強大的低代碼AI開發平臺&#…

開發積累總結

export default 和export const 均用于從模塊導出函數、對象或原始值&#xff0c;區別在于&#xff1a; export default&#xff1a;一個文件中只能有一個&#xff0c;為默認導出&#xff0c;在引用時指定名字。 export const&#xff1a;一個文件中有多個&#xff0c;為命名…

【TCP/IP協議族詳解】

目錄 第1層 鏈路/網絡接口層—幀&#xff08;Frame&#xff09; 1. 鏈路層功能 2. 常見協議 2.1. ARP&#xff08;地址解析協議&#xff09; 3. 常見設備 第2層 網絡層—數據包&#xff08;Packet&#xff09; 1. 網絡層功能 2. 常見協議 2.1. ICMP&#xff08;互聯網…

vocabulary in program

編號意思&#xff08;英譯中&#xff09;音標單詞1n. 稀薄&#xff1b;稀罕&#xff1b;珍奇/?re?r?sn/rareness2n.登記表&#xff0c;注冊簿&#xff1b;注冊員&#xff1b;&#xff08;人或樂器的&#xff09;聲區&#xff0c;音區&#xff1b;&#xff08;適合特定場合使…

整平機技術進階:從原理到實戰的深度解析

一、整平機的力學原理與數學模型 整平機的核心在于通過材料塑性變形消除內應力&#xff0c;其力學過程可簡化為以下模型&#xff1a; 彈塑性變形理論 當材料通過輥輪時&#xff0c;表層受拉應力&#xff0c;芯部受壓應力&#xff0c;超過屈服強度后產生永久變形。 關鍵公式&a…

【b站計算機拓荒者】【2025】微信小程序開發教程 - chapter1 初識小程序 - 3項目目錄結構4快速上手

3 項目目錄結構 3.1 項目目錄結構 3.1.1 目錄介紹 # 1 項目主配置文件&#xff0c;在項目根路徑下&#xff0c;控制整個項目的-app.js # 小程序入口文件&#xff0c;小程序啟動&#xff0c;會執行此js-app.json # 小程序全局配置文件&#xff0c;配置小程序導航欄顏色等信息…