Vue+canvas實(shí)現(xiàn)水印功能
概述
實(shí)際項(xiàng)目中偶爾會遇到給項(xiàng)目頁面背景加水印的需求,最近正好遇到,借機(jī)自己動手實(shí)現(xiàn)了這個功能,這里記錄下實(shí)現(xiàn)思路和過程,支持文字和圖片作為背景水印。
最終效果
1.默認(rèn)樣式

2.自定義顏色、字體大小等

實(shí)現(xiàn)思路
- 首先不難想到的是,最終的水印文字重復(fù)平鋪到頁面背景上面,我們可以想到盒模型background屬性,然后設(shè)置其背景圖片為我們的文字即可.
- 其次如何讓給定的文本變成圖片呢?我們可以考慮使用canvas繪圖功能,根據(jù)給定的文字,生成canvas圖片,然后轉(zhuǎn)成base64格式,賦值給image標(biāo)簽不就可以了嘛,并且還能給文字設(shè)置不同的樣式,例如:加粗、顏色、背景、漸變、傾斜等等.
- 最后我們要做的就是將生成的背景圖片平鋪到頁面即可,切記不能影響頁面的布局,這里我們就可以考慮定位來實(shí)現(xiàn).
實(shí)現(xiàn)過程
這里我們采用vue+ts的方式,將水印封裝成組件
App.vue
<template>
<div :class="['vite-app']">
<watermark
content="大家辛苦一下"
:line-height="40"
:rotate="-15"
:fullscreen="true"
>
this is default text
<ul>
<li v-for="item in 5" :key="item">this is test content</li>
</ul>
</watermark>
<div class="main-content">
<ul>
<li v-for="item in 60" :key="item">this is test content</li>
</ul>
</div>
</div>
</template>
<script setup lang="ts">
import Watermark from "./components/Watermark.vue";
</script>
<style lang="less">
* {
margin: 0;
padding: 0;
}
.vite-app {
font-weight: bold;
font-size: 20px;
}
</style>./component/Watermark.vue
<template>
<div
:class="['water-mark', props.fullscreen ? 'water-mark-full-screen' : '']"
ref="waterMarkContainer"
>
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
const waterMarkContainer = ref<HTMLElement>();
//poprs屬性
export interface WarkMark {
fullscreen?: boolean;
fontSize?: number;
lineHeight?: number;
fontFamily?: string;
color?: string;
width?: number;
height?: number;
xOffset?: number;
yOffset?: number;
rotate?: number;
imgSrc?: string;
content: string;
}
//默認(rèn)值
const props = withDefaults(defineProps<WarkMark>(), {
fontSize: 16,
fontFamily: "宋體",
color: "rgba(128, 128, 128, .5)",
width: 250,
height: 258,
// height: 100,
lineHeight: 16,
xOffset: 10,
yOffset: 28,
rotate: 30,
});
function createWaterMark() {
const canvas = document.createElement("canvas");
canvas.height = props.height;
canvas.width = props.width;
const ctx = canvas.getContext("2d");
let imageUrl = "";
ctx!.rotate(props.rotate * (Math.PI / 180));
ctx!.fillStyle = props.color;
ctx!.font = `${props.fontSize}px ${props.fontFamily}`;
const wrap = document.createElement("div");
wrap.classList.add("mak-wrap");
wrap.style.zIndex = "-1";
if (props.imgSrc) {
//圖片作為背景
createImageWaterMark();
} else {
//文字作為背景
createTextWaterMark();
}
function createDom() {
wrap.style.backgroundImage =
"url(" + imageUrl + ")," + "url(" + imageUrl + ")";
wrap.style.backgroundPosition = `${props.width / 2}px ${
props.height / 2
}px, 0 0`;
wrap.style.backgroundSize = props.width + "px";
waterMarkContainer.value!.appendChild(wrap);
}
function createImageWaterMark() {
const image = new Image();
image.src = props.imgSrc!;
image.width = props.width * 0.2;
image.crossOrigin = "anonymous"; //允許圖片跨域訪問
image.onload = () => {
ctx!.drawImage(
image,
props.xOffset,
props.xOffset + props.lineHeight + 10
);
imageUrl = canvas.toDataURL();
canvas.style.opacity = ".5";
createDom();
};
}
function createTextWaterMark() {
ctx!.fillText(
props.content,
props.xOffset,
props.xOffset + props.lineHeight + 10
);
imageUrl = canvas.toDataURL();
createDom();
}
}
onMounted(() => {
createWaterMark();
});
</script>
<style lang="less">
.water-mark {
position: relative;
pointer-events: none;
.mak-wrap {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
.water-mark.water-mark-full-screen {
.mak-wrap {
position: fixed;
}
}
</style>總結(jié)
實(shí)現(xiàn)思路明白后,上面的樣式方面,可以根據(jù)自己需求進(jìn)行自定義修改。
到此這篇關(guān)于Vue+canvas實(shí)現(xiàn)水印功能的文章就介紹到這了,更多相關(guān)Vue canvas水印內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用vue自定義指令開發(fā)表單驗(yàn)證插件validate.js
今天就來介紹一下如何利用vue的自定義指令directive來開發(fā)一個表單驗(yàn)證插件的過程,需要的朋友可以參考下2019-05-05
vue element-ui v-for循環(huán)el-upload上傳圖片 動態(tài)添加、刪除方式
這篇文章主要介紹了vue element-ui v-for循環(huán)el-upload上傳圖片 動態(tài)添加、刪除方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10
vue template當(dāng)中style背景設(shè)置不編譯問題
這篇文章主要介紹了vue template當(dāng)中style背景設(shè)置不編譯問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04
Vue組件傳值過程中丟失數(shù)據(jù)的分析與解決方案
這篇文章主要給大家介紹了關(guān)于Vue組件傳值過程中丟失數(shù)據(jù)的分析與解決方案,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
淺談mvvm-simple雙向綁定簡單實(shí)現(xiàn)
本篇文章主要介紹了淺談mvvm-simple雙向綁定簡單實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼
這篇文章主要介紹了VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
使用Vue3實(shí)現(xiàn)一個簡單的思維導(dǎo)圖組件
思維導(dǎo)圖是一種用于表示信息、想法和概念的圖形化工具,本文將基于 Vue3和VueDraggable實(shí)現(xiàn)一個簡單的思維導(dǎo)圖組件,支持節(jié)點(diǎn)拖拽,編輯及節(jié)點(diǎn)之間的關(guān)系連接,希望對大家有所幫助2025-04-04

