vue3 實現前端生成水印效果

vue3 實現前端生成水印效果

首先一點哈,就是單純web前端生成水印只能作為警示使用,如果享徹底防住幾乎是不可能的,有無數種方式去掉web前端生成的水印,所以這種方式只當是一個君子協議吧。

編寫水印組件

首先直接把這部分封裝成一個組件吧,我這邊直接上代碼了。

創建一個 waterMark.vue 文件,用來編寫水印組件:

<template><div class="watermark-container" ref="parentRef"><slot></slot></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import useWaterMarkBg from './waterMarkBg';
const props = defineProps({text: {type: String,default: "版權所有"},fontSize: {type: Number,default: 25,},gap: {type: Number,default: 20,},color: {type: String,default: 'rgba(201, 35, 35, 0.5)'}
})let div;
const bg = useWaterMarkBg(props);
const parentRef = ref();const ob = new MutationObserver((entries) => {for (const entry of entries) {for (const node of entry.removedNodes) {if (node === div) {resetWatermark();return;}}if (entry.target === div) {resetWatermark();}}
})onMounted(() => {resetWatermark();ob.observe(parentRef.value, {childList: true,subtree: true,attributes: true,})
})onUnmounted(() => {ob.disconnect();
})// 重置水印
const resetWatermark = () => {if (!parentRef.value) { return }if (div) {div.remove();}const { base64, size } = bg.value.value;div = document.createElement('div');div.style.position = 'absolute';div.style.backgroundImage = `url(${base64})`;div.style.backgroundSize = `${size.width}px ${size.height}px`;div.style.backgroundRepeat = "repeat";div.style.pointerEvents = 'none';div.style.zIndex = '9999';div.style.inset = 0;parentRef.value.appendChild(div);
}</script>
<style scoped lang="scss">
.watermark-container {position: relative;
}
</style>

可以接受四個參數,如果不夠可以自己加,分別是 text 水印文本內容fontSize 水印文本大小gap 水印文本間隔color 水印文本顏色

然后在水印組件加載完成的時候調用 resetWatermark 重置水印方法實現添加水印。

水印是動態生成的圖片,最后創建了一個動態的div加上頁面的,因為還想盡可能的防止一下水印刪除,所以說在中途檢測了一下dom修改情況,如果修改了,比如刪除了div,或者是修改了div的樣式,那么就重置水印,重新添加一遍。

其中在組件中還是用了 useWaterMarkBg 方法,下面代碼是 waterMarkBg.js 文件的內容,可以根據自己的業務需求適當的修改:

import { ref, computed } from 'vue';/*** 創建水印背景圖片的 composable 函數* @param {Object} options - 水印配置選項* @param {string} options.text - 水印文字內容* @param {number} options.fontSize - 字體大小* @param {number} options.gap - 水印間隔* @param {string} options.color - 文字顏色,默認為半透明灰色* @param {number} options.rotate - 旋轉角度,默認為 -15 度* @param {string} options.fontFamily - 字體,默認為 Arial* @returns {Object} 返回包含 base64 和 size 的響應式對象*/
function useWaterMarkBg(options = {}) {// 默認參數const defaultOptions = {text: '版權所有',fontSize: 25,gap: 20,color: 'rgba(201, 35, 35, 0.5)',rotate: -15,fontFamily: 'Arial, sans-serif'};// 合并用戶參數和默認參數const waterMarkOptions = ref({ ...defaultOptions, ...options });// 計算水印尺寸和 base64 圖片const waterMarkInfo = computed(() => {const { text, fontSize, gap, color, rotate, fontFamily } = waterMarkOptions.value;// 創建 canvas 元素const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');if (!ctx) {throw new Error('無法獲取 canvas 上下文');}// 設置字體ctx.font = `${fontSize}px ${fontFamily}`;// 獲取文字寬度const textWidth = ctx.measureText(text).width;// 計算 canvas 尺寸(包含文字和間隙)const width = textWidth + gap * 2;const height = fontSize * 2 + gap * 2;canvas.width = width;canvas.height = height;// 重置上下文(因為 canvas 尺寸改變了)ctx.font = `${fontSize}px ${fontFamily}`;ctx.fillStyle = color;ctx.textAlign = 'center';ctx.textBaseline = 'middle';// 保存當前狀態ctx.save();// 移動到 canvas 中心并旋轉ctx.translate(width / 2, height / 2);ctx.rotate((Math.PI / 180) * rotate);// 繪制文字ctx.fillText(text, 0, 0);// 恢復之前的狀態ctx.restore();// 轉換為 base64const base64 = canvas.toDataURL('image/png');return {base64,size: {width,height}};});// 如果傳入的 options 發生變化,可以更新水印function updateOptions(newOptions) {waterMarkOptions.value = { ...waterMarkOptions.value, ...newOptions };}return {value: waterMarkInfo,updateOptions};
}export default useWaterMarkBg;

水印組件的使用

使用的時候就很簡單了,引入一下,然后包裹一下需要添加水印的dom就可以了:

    <!-- 默認紅色水印 --><water-mark text="嚴禁傳播"><div class="img-con"><img src="../../assets/imgs/watermark/1.jpg" alt="圖片1"></div></water-mark><!-- 藍色水印 --><water-mark text="禁止復制" :fontSize="25" color="rgba(30, 144, 255, 0.3)"><div class="img-con"><img src="../../assets/imgs/watermark/2.jpg" alt="圖片2"></div></water-mark><!-- 綠色水印 --><water-mark text="測試水印" :fontSize="25" color="rgba(50, 205, 50, 0.4)"><div class="img-con"><img src="../../assets/imgs/watermark/1.jpg" alt="圖片3"></div></water-mark>

效果

在這里插入圖片描述

好了,大體就這個樣子,還是,水印這個很容易刪除,懂得人,刪的很快,最好從源頭解決,只要后端返回前端的是原文件,那么就可以從瀏覽器獲取到沒有水印的內容。

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

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

相關文章

Armonia Mall超級數字生態WEB3商城的引領者

Armonia Mall是一個基于Web3技術的超級數字生態商城&#xff0c;旨在打造全球首家Web3數字普惠商城&#xff0c;幫助千萬行銷人實現數字生態創業&#xff0c;讓全球一億家庭共享數字經濟紅利。 Armonia Mall商城創始人&#xff1a;石玉華Armonia Mall七大超級機制&#xff08;模…

Axios與Java Spring構建RESTful API服務集成指南

1 前后端分離時代的技術選擇 現在的Web開發&#xff0c;前后端分離已經不是什么新鮮事了。前端用什么&#xff1f;很多團隊選擇Axios。后端呢&#xff1f;Java Spring依然是企業級應用的首選。 Axios這個JavaScript庫確實好用&#xff0c;Promise-based的設計讓異步請求變得簡單…

Django ORM多對多關系實戰指南

一、Django 多對多關系的原理 在關系型數據庫中&#xff0c;多對多關系通常需要 第三張中間表 來維護兩張表之間的對應關系。 在 Django 中&#xff0c;你只需要定義 ManyToManyField&#xff0c;Django 會自動幫你創建這張中間表。 特點&#xff1a; 可以雙向查詢&#xff08;…

STM32 單片機開發 - TIM 定時器(PWM)

一、硬件定時器高級控制定時器 Advanced Control Timers (TIM1/TIM8)通用定時器 General Purpose Timers (TIM2/TIM3/TIM4/TIM5)通用定時器 General Purpose Timers (TIM15/TIM16/TIM17)基本定時器 Basic Timers (TIM6/TIM7)表 1 定時器種類二、TIM 中 PWM 概念PWM 的基本原理就…

OpenCV內置分類器實現簡單的人臉識別

引言 人臉檢測是計算機視覺領域的基礎任務之一&#xff0c;廣泛應用于安防監控、人機交互、圖像美化等場景。今天我們將通過一段簡潔的Python代碼&#xff0c;使用OpenCV庫實現實時攝像頭人臉檢測功能。無論你是計算機視覺新手還是有經驗的開發者&#xff0c;這篇文章都能幫你理…

Tomcat 性能優化與高并發調優

Tomcat 性能優化與高并發調優1. 引言 經過前幾篇文章的學習&#xff0c;我們已經掌握了 Tomcat 的核心原理&#xff1a; Connector 連接器容器體系&#xff08;Engine → Host → Context → Wrapper&#xff09;Servlet 執行鏈路線程模型&#xff08;Executor Worker&#xf…

MacOS M1安裝face_recognition

MacOS M1安裝face_recognition一致失敗&#xff0c;嘗試網上各種方法還是失敗&#xff0c;遂分享自己安裝成功的經歷。 conda虛擬環境python版本&#xff1a;3.9.23準備工作確保 Homebrew 已安裝 Homebrew 是 macOS 的包管理器&#xff0c;用于安裝依賴項。如果尚未安裝&#x…

動態庫和靜態庫的鏈接加載

靜態庫的鏈接與加載靜態庫&#xff08;如.a或.lib文件&#xff09;在編譯時直接鏈接到可執行文件中。編譯器會將靜態庫中實際用到的代碼復制到最終的可執行文件&#xff0c;生成獨立的二進制文件。優點是不依賴外部庫文件&#xff0c;但會導致可執行文件體積較大。生成靜態庫的…

如何處理在pytorch環境中已經安裝的matplotlib無法使用的問題

1 問題已經安裝好的matplotlib包無法在pytorch環境中使用。2 方法方法一&#xff1a;用命令安裝matplotlib &#xff1a;方法二&#xff1a;打開cmd&#xff0c;使用conda install matplotlib命令安裝matplotlib庫#輸入以下代碼段&#xff0c;查詢當前執行路徑import osos.sys.…

Linux基礎命令匯總

系統基礎指令 ls:列出目錄內容 ls -a:顯示所有文件(包括隱藏文件) ls -l:顯示詳細文件信息 ls /etc:列出 /etc 目錄內容 示例: cat:查看文件內容 cat /etc/os-release:查看系統版本信息 cat file1:顯示文件內容 cat file1 file2 > merged.txt:合并文件并輸出到新…

一場史詩級的冒險——Docker命令大航海!

各位親愛的開發者、運維勇士、以及所有對現代化軟件部署充滿好奇的小伙伴們&#xff01;今天&#xff0c;我們將開啟一場史詩級的冒險——Docker命令大航海&#xff01;我們將乘坐“Docker號”巨輪&#xff0c;駛向容器化技術的星辰大海。 這不是一篇枯燥的說明書&#xff0c;而…

告別依賴混亂:Spring IoC 容器與 DI 依賴注入入門精講

目錄 什么是 IoC IoC 介紹 傳統開發思路 解決方法 IoC 優勢 DI IoC & DI 使用 IoC 詳解 Bean 的存儲 Controller&#xff08;控制器存儲&#xff09; 獲取 bean 對象的其他方法 bean 命名 面試題之 ApplicationContext pk BeanFactory Service&#xff08;服…

視頻理解學習筆記

目錄 VideoRefer VideoPrism 核心解密&#xff1a;通用視頻編碼器的力量 VideoRefer VideoRefer 是由浙江大學和阿里達摩院聯合推出的視頻對象感知與推理技術&#xff0c;增強視頻大型語言模型&#xff08;Video LLMs&#xff09;的空間-時間理解能力。簡單一點來說就是可以…

P1198題解

題目鏈接 開題第一件事看數據范圍.這里的范圍是二十萬,支持O(nlogn). 這是一個RMQ問題,同時要加點,我們因此考慮ST表或者線段樹.這里用線段樹是核彈打蚊子,沒有意義,我們因此考慮ST表.我們注意到如果加點操作需要改動ST表原來的東西ST表就會炸掉,我們就要考慮更高級的數據結構…

使用yolov8對視頻進行目標檢測

使用 Ultralytics 的 YOLO 模型對視頻進行逐幀目標檢測非常簡單&#xff0c;以下是完整的實現方法&#xff1a; 我們的輸入視頻是這樣的 視頻目標檢測輸入視頻這里是天津市和平區天津大學附近&#xff0c;感興趣的小伙伴來天津玩哈&#xff01;&#xff01; 1. 安裝依賴 確保已…

Edge瀏覽器的自動化點擊系統

Tag_click_openclose_V6 開發與使用注意事項 網頁自動化點擊系統 一個基于Python和CustomTkinter開發的桌面應用程序&#xff0c;通過Selenium實現對Edge瀏覽器的自動化控制。點擊Tag_click_openclose_V6進入Github自取&#xff0c;記得點贊收藏嗷。 功能介紹 連接到已打開…

Python股票數據分析與預測系統 LSTM神經網絡算法 股票價格預測 Tensorflow深度學習 機器學習 Flask框架 東方財富(建議收藏)?

博主介紹&#xff1a;?全網粉絲50W&#xff0c;前互聯網大廠軟件研發、集結碩博英豪成立軟件開發工作室&#xff0c;專注于計算機相關專業項目實戰6年之久&#xff0c;累計開發項目作品上萬套。憑借豐富的經驗與專業實力&#xff0c;已幫助成千上萬的學生順利畢業&#xff0c;…

英萊科技焊縫跟蹤系統亮相德國埃森焊接展,激光視覺點亮世界舞臺

9月15-19日&#xff0c;每4年一屆的德國埃森焊接與切割展覽會&#xff08;SCHWEISSEN & SCHNEIDEN&#xff09;即將盛大開幕。作為焊接行業最具規模及權威性的盛會之一&#xff0c;英萊科技將攜全新PF系列激光視覺焊縫跟蹤系統驚艷亮相&#xff0c;為全球智能化焊接貢獻中國…

嵌入式基本概念:什么是指令集,微架構,IDE,DFP等等是什么意思,有什么關系???

注&#xff1a;下面是指令集和微框架的分類圖&#xff0c;后面我會以ARM的M4舉例子。 一.什么是指令集 大概的可以看這個視頻 https://www.bilibili.com/video/BV1uXzbYBEy2/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&vd_source406ed…

Spring Cloud之服務入口Gateway之自定義過濾器

目錄 過濾器執行順序 自定義過濾器 自定義GatewayFilter 定義GatewayFilter 配置過濾器 啟動服務并訪問 自定義GlobalFilter 定義GlobalFilter 啟動服務并訪問 服務部署 過濾器執行順序 如果?個項?中, 既有GatewayFilter, ?有 GlobalFilter時, 執?的先后順序是什…