前端實現添加水印,兩種方式

一、自定義指令的方式

/*需求:給整個頁面添加背景水印。思路:1、使用 canvas 特性生成 base64 格式的圖片文件,設置其字體大小,顏色等。2、將其設置為背景圖片,從而實現頁面或組件水印效果使用:設置水印文案,顏色,字體大小即可<div v-waterMarker="{text:'版權所有',textColor:'rgba(180, 180, 180, 0.4)'}"></div>
*/const addWaterMarker = (str, parentNode, font, textColor) => {// 水印文字,父元素,字體,文字顏色let can = document.createElement("canvas");parentNode.appendChild(can);can.width = 205;can.height = 140;can.style.display = "none";let cans = can.getContext("2d");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";cans.fillText(str, can.width / 10, can.height / 2);parentNode.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")";
};const waterMarker = {mounted(el, binding) {addWaterMarker(binding.value.text, el, binding.value.font, binding.value.textColor);}
};export default waterMarker;

二、組件的方式

<template><WaterMark watermark-text="你好你好你好"><div class="content">我這里是水印</div></WaterMark>
</template>
<script setup lang="ts">
import WaterMark from "./WaterMark.vue";
</script>
<style scoped>
.content {display: flex;justify-content: space-around;width: 100%;
}
</style>

//./WaterMark.vue
<template><div ref="watermarkContainer" class="watermark-container"><!-- 插槽內容,可以放置需要水印的內容 --><slot></slot></div>
</template><script setup lang="ts">
import { onMounted, onUnmounted, ref, Ref, watch } from "vue";
// 定義Props
// defineProps<{ watermarkText: string }>();
const props = defineProps({watermarkText: {type: String,required: true,default: "默認水印",},
});
// const watermarkUrl: Ref<string> = ref("");
const watermarkContainer = ref<HTMLElement | null>(null);
const watermark = ref<HTMLDivElement | null>(null);
const drawWatermark = () => {console.log("drawWatermark----");const watermarkImage = getWatermarkImage();if (watermark.value) {watermark.value.remove();}watermark.value = document.createElement("div");watermark.value.style.position = "absolute";watermark.value.style.backgroundImage = `url(${watermarkImage})`;watermark.value.style.backgroundSize = "200px 200px";watermark.value.style.backgroundRepeat = "repeat";// watermark.value.style.opacity = "0.5";watermark.value.style.zIndex = "99";watermark.value.style.pointerEvents = "none";watermark.value.style.transform = "rotate(-45deg)";watermark.value.style.inset = "0";watermarkContainer.value?.appendChild(watermark.value);
};
const getWatermarkImage = () => {const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");if (!ctx) return;canvas.width = 200;canvas.height = 150;ctx.font = "16px Arial";ctx.fillStyle = "rgba(184, 184, 184, 0.5)";// ctx.textAlign = "center";ctx.fillText(props.watermarkText, 20, 100);return canvas.toDataURL("image/png");
};const observer = new MutationObserver((mutations) => {mutations.forEach((mutation) => {console.log(mutation);if (mutation.type === "attributes" ||mutation.attributeName === "style") {drawWatermark();}});
});onMounted(() => {drawWatermark();if (watermarkContainer.value) {observer.observe(watermarkContainer.value, {childList: true,subtree: true,attributes: true,// attributeFilter: ["style"],});}watch(() => props.watermarkText,() => {drawWatermark();},);
});
onUnmounted(() => {observer.disconnect();
});
</script><style>
.watermark-container {position: relative;width: 100%;height: 100%;
}
</style>

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

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

相關文章

使用LangChain構建法庭預定智能體:結合vLLM部署的Qwen3-32B模型

文章目錄 技術架構概述 核心實現步驟 1. 配置vLLM與Qwen3-32B模型 2. 定義工具(Tools) 3. 構建Agent系統 4. 運行與交互 關鍵技術亮點 1. 工具調用自動化 2. Hermes解析器優勢 3. 對話記憶管理 實際運行效果 性能優化建議 擴展應用場景 總結 在人工智能應用開發中,如何讓大語…

vscode開發微信小程序

下載插件 插件下載位置 1.微信小程序開發工具 2.vscode weapp api 3.vscode wxml 4.vscode-wechat 創建項目 終端運行命令 cd 到要創建項目的目錄執行命令&#xff1a;vue create -p dcloudio/uni-preset-vue test test就是項目名稱 選擇默認模板&#xff0c;回車 出現下圖這…

板凳-------Mysql cookbook學習 (十二--------3_3)

https://cloud.tencent.com/developer/article/1454690 侯哥的Python分享 # 創建節點 class Node(object):def __init__(self,item):self.element itemself.next None# 創建單鏈表類 class SingleLinkList(object):def __init__(self):self.header Noneself.length 0# 1、判…

Flutter開發實戰之CI/CD與發布流程

第12章:CI/CD與發布流程 在前面的章節中,我們學習了Flutter應用開發的各個方面,從基礎UI構建到復雜的狀態管理,從網絡請求到本地存儲。現在,我們將探討一個同樣重要但常被忽視的話題:如何將我們精心開發的應用高效、可靠地發布到各大應用商店。 想象一下,你花費了數月…

ElasticSearch 的3種數據遷移方案

在實際工作中&#xff0c;我們經常會遇到需要將自建的 Elasticsearch 遷移上云&#xff0c;或者遷移到其他 ES 集群的情況。這時&#xff0c;選擇合適的數據遷移方案就顯得尤為重要啦。今天就來給大家介紹三種常用的遷移方案&#xff0c;分別是 COS 快照、logstash 和 elastics…

MySQL 中的“雙路排序”與“單路排序”:原理、判別與實戰調優

一句話導讀 ORDER BY 不能走索引時&#xff0c;MySQL 會在 Server 層做一次 filesort。內部實現分 單路&#xff08;全字段&#xff09; 與 雙路&#xff08;rowid&#xff09; 兩種&#xff1b;了解它們的觸發條件、判別方法與調優思路&#xff0c;是 SQL 性能優化的必修課。一…

OpenLayers 綜合案例-信息窗體-彈窗

看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大家&#xff0c;助你少走彎路&#xff01; OpenLayers…

GaussDB 開發基本規范

1 集中式1.1數據庫價值特性推薦特性分類特性列表說明表類型PARTITION表數據分區存儲引擎行存儲按行順序存儲表&#xff0c;建議點查&#xff0c;增刪改操作較多場景下使用事務事務塊顯式啟動事務單語句事務不顯式啟動事務&#xff0c;單語句即為事務擴容在線擴容擴節點和數據重…

工作中使用git可能遇到的場景

1.main歷史發布版本出問題需要查看&#xff0c;怎么切換歷史發布版本&#xff1f;git reset --hard commitid 更新本地庫和代碼2.A分支的代碼已經做過一些功能&#xff0c;想遷移到B分支當前在A分支git checkout B &#xff08;切換到B分支&#xff09;git cherry-pick A的com…

【Spring AI】本地大型語言模型工具-Ollama

Ollama 是一個專注于在本地運行大型語言模型&#xff08;LLM&#xff09;的工具&#xff0c;支持多種開源模型&#xff08;如 Llama 3、Mistral、Gemma 等&#xff09;&#xff0c;提供簡單的命令行和 API 接口。<dependency><groupId>org.springframework.ai</…

電機S加減速

STM32步進電機S型加減速算法_stm32___build__-2048 AI社區 以上&#xff0c;電機加減速說的非常清楚&#xff0c;收藏點贊&#xff01;

一、初識 Linux 與基本命令

作者&#xff1a;IvanCodes 日期&#xff1a;2025年7月28日 專欄&#xff1a;Linux教程 思維導圖 一、Linux 簡介 1.1 什么是 Linux? Linux 是一種自由、開源的類Unix操作系統內核&#xff0c;由林納斯托瓦茲 (Linus Torvalds) 在1991年首次發布。我們通常所說的 “Linux 系統…

解決angular與jetty websocket 每30s自動斷連的問題

背景&#xff1a;前端&#xff1a;angular 12&#xff0c;websocket接口由lib.dom.d.ts提供后端&#xff1a;java&#xff0c;websocket接口由jetty 12提供問題現象&#xff1a;前端連上server后&#xff0c;每隔30s就會斷開&#xff0c;由于長時間空閑&#xff0c;會導致webso…

【機器學習深度學習】模型私有化部署與微調訓練:賦能特定問題處理能力

目錄 前言 一、私有化部署的背景&#xff1a;通用能力 ≠ 企業實用 暴露問題 二、微調訓練的核心目的 2.1 動作一&#xff1a;私有化部署&#xff08;Private Deployment&#xff09; 2.2 動作二&#xff1a;領域微調&#xff08;Domain Fine-Tuning&#xff09; 2.3 微…

Seq2Seq學習筆記

Seq2Seq模型概述Seq2Seq&#xff08;Sequence-to-Sequence&#xff09;是一種基于深度學習的序列生成模型&#xff0c;主要用于處理輸入和輸出均為序列的任務&#xff0c;如機器翻譯、文本摘要、對話生成等。其核心思想是將可變長度的輸入序列映射為另一個可變長度的輸出序列。…

react useId

useId useId 是 React 18 引入的一個內置 Hook&#xff0c;用于生成唯一且穩定的 ID &#xff0c; 主要用于&#xff0c;解決在客戶端和服務器端渲染&#xff08;SSR&#xff09;時&#xff0c;動態生成 ID 可能導致的沖突問題&#xff1b; 特別適合用于&#xff0c;需要關聯 H…

排水管網實時監測筑牢城市安全防線

排水管網的實時監測工作&#xff0c;強調其對于保障城市安全的重要作用。“排水管網”明確了具體的關注對象&#xff0c;它是城市基礎設施的重要組成部分&#xff0c;承擔著雨水、污水排放等關鍵功能。“實時監測”突出了監測的及時性和持續性&#xff0c;意味著能夠隨時獲取排…

SZU大學物理實驗報告|電位差計

寫在前面&#xff1a;博文里放圖片&#xff0c;主要省去了對文檔的排版時間&#xff0c;實驗還是要自己做的&#xff0c;反正都要去實驗室上課&#xff0c;順帶鍛煉下動手能力。有些結果是實驗手寫的&#xff0c;所以看不到&#xff0c;有結果的可以對下結果差的不太多就行&…

RoPE簡單解析

文章目錄簡介拆解一些tricks簡介 因為RoPE的優異性能&#xff0c;其已成為各種大模型中位置編碼的首選&#xff0c;包括多模態模型&#xff1b;在一些多模態模型或視頻理解模型中&#xff0c;甚至會用到多維度RoPE。雖然RoPE已廣泛應用&#xff0c;之前也看了不少針對其原理解…

windows 獲取 APK 文件的包名和啟動 Activity 名稱

使用 aapt 命令確保環境變量配置正確&#xff1a;首先需要確保你的系統環境變量中包含了 Android SDK 的 build-tools 目錄路徑。這是因為 aapt 工具位于該目錄下。運行命令&#xff1a; 打開命令提示符&#xff08;CMD&#xff09;&#xff0c;然后輸入以下命令來查看 APK 的詳…