v-watermarker
介绍
v-watermarker
指令用于在元素上添加水印效果,以保护内容的版权或标识。对于图片元素,水印会直接与图片内容合并,防止通过控制台查看原始图片。
基础用法
在图片上应用基本水印:
点击查看代码
vue
<template>
<div class="demo-container">
<div class="watermark-box">
<img
v-watermarker="{
text: '基础水印',
fontSize: 30,
opacity: 0.4,
gap: 200
}"
src="https://images.unsplash.com/photo-1579353977828-2a4eab540b9a?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="风景图片"
class="demo-image"
/>
</div>
<div class="description">
<p>基础水印示例 - 使用默认对角线方向,调整了透明度和间距</p>
</div>
</div>
</template>
<script setup>
import { vWatermarker } from '@cp-vuedir/core'
</script>
<style scoped>
.demo-container {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.watermark-box {
width: 100%;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
position: relative;
margin-bottom: 10px;
height: 400px;
}
.demo-image {
width: 100%;
height: 100%;
}
.description {
font-size: 14px;
color: var(--vp-c-text-2);
margin-top: 10px;
text-align: center;
}
</style>
水印方向
水印支持三种方向:水平、垂直和对角线:
点击查看代码
vue
<template>
<div class="demo-container">
<div class="direction-demos">
<div class="watermark-box">
<img
v-watermarker="{
text: '水平方向',
direction: 'horizontal',
fontSize: 24,
opacity: 0.5,
textColor: '#0066cc',
gap: 70
}"
src="https://images.unsplash.com/photo-1506744038136-46273834b3fb?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="山水风景"
class="demo-image"
/>
<div class="label">水平方向</div>
</div>
<div class="watermark-box">
<img
v-watermarker="{
text: '垂直方向',
direction: 'vertical',
fontSize: 24,
opacity: 0.5,
textColor: '#cc3300',
gap: 70
}"
src="https://images.unsplash.com/photo-1472214103451-9374bd1c798e?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="田野风景"
class="demo-image"
/>
<div class="label">垂直方向</div>
</div>
<div class="watermark-box">
<img
v-watermarker="{
text: '对角线方向',
direction: 'diagonal',
fontSize: 24,
opacity: 0.5,
textColor: '#006633',
gap: 70
}"
src="https://images.unsplash.com/photo-1501785888041-af3ef285b470?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="海岸风景"
class="demo-image"
/>
<div class="label">对角线方向</div>
</div>
</div>
</div>
</template>
<script setup>
import { vWatermarker } from '@cp-vuedir/core'
</script>
<style scoped>
.demo-container {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.watermark-box {
width: 100%;
height: 250px;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
overflow: hidden;
position: relative;
margin-bottom: 10px;
}
.demo-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.label {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.6);
color: white;
padding: 8px;
text-align: center;
font-size: 14px;
font-weight: bold;
}
.direction-demos {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
}
@media (max-width: 640px) {
.direction-demos {
grid-template-columns: 1fr;
}
}
</style>
自定义样式
通过调整下面的控制面板,您可以实时体验不同水印参数的效果:
点击查看代码
vue
<template>
<div class="demo-container">
<div class="watermark-box">
<img
v-watermarker="{
text: 'VueDir',
fontSize: 28,
fontFamily: 'Georgia, serif',
textColor: '#ff3300',
opacity: 0.4,
gap: 100
}"
src="https://images.unsplash.com/photo-1552083375-1447ce886485?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="城市风景"
class="demo-image"
/>
</div>
<div class="description">
<p>自定义样式示例 - 使用更大字体、特殊字体族和醒目的红色</p>
<div class="style-info">
<div class="style-item">
<span class="label">字体大小:</span>
<span class="value">28px</span>
</div>
<div class="style-item">
<span class="label">字体族:</span>
<span class="value">Georgia, serif</span>
</div>
<div class="style-item">
<span class="label">文字颜色:</span>
<span class="value"><span class="color-box"></span>#ff3300 </span>
</div>
<div class="style-item">
<span class="label">透明度:</span>
<span class="value">0.4</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { vWatermarker } from '@cp-vuedir/core'
</script>
<style scoped>
.demo-container {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.watermark-box {
width: 100%;
height: 400px;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
overflow: hidden;
position: relative;
margin-bottom: 15px;
}
.demo-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.description {
font-size: 14px;
color: var(--vp-c-text-2);
margin-top: 10px;
text-align: center;
}
.style-info {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 15px;
margin-top: 10px;
}
.style-item {
display: flex;
align-items: center;
gap: 5px;
}
.label {
font-weight: bold;
color: var(--vp-c-text-1);
}
.value {
color: var(--vp-c-text-2);
}
.color-box {
display: inline-block;
width: 16px;
height: 16px;
background-color: #ff3300;
border-radius: 3px;
vertical-align: middle;
margin-left: 5px;
}
</style>
交互式演示
上面的演示允许您调整以下参数:
- 水印文本:自定义显示的文字内容
- 水印方向:水平、垂直或对角线方向
- 字体大小:调整文字的大小
- 字体族:选择不同的字体样式
- 文字颜色:使用颜色选择器更改颜色
- 透明度:调整水印的透明度
- 间距:调整水印之间的距离
远程图片水印
对远程图片应用水印(需要图片服务器支持跨域):
点击查看代码
vue
<template>
<div class="demo-container">
<div class="watermark-box">
<img
v-watermarker="{
text: '远程图片水印',
fontSize: 24,
opacity: 0.4,
direction: 'diagonal',
textColor: '#0033cc',
gap: 90
}"
src="https://images.unsplash.com/photo-1682687220063-4742bd7fd538?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80"
alt="远程图片"
class="demo-image"
/>
</div>
<div class="description">
<div class="title">远程图片水印示例</div>
<p>此示例展示了对远程图片应用水印。水印会直接与图片内容合并,防止通过控制台查看原始图片。</p>
<p class="note">注意:对于跨域图片,需要确保图片服务器允许跨域访问,否则可能无法正确应用水印。</p>
</div>
</div>
</template>
<script setup>
import { vWatermarker } from '@cp-vuedir/core'
</script>
<style scoped>
.demo-container {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.watermark-box {
width: 100%;
height: 400px;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
overflow: hidden;
position: relative;
margin-bottom: 15px;
}
.demo-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.description {
font-size: 14px;
color: var(--vp-c-text-2);
line-height: 1.5;
padding: 0 10px;
}
.title {
font-weight: bold;
font-size: 16px;
color: var(--vp-c-text-1);
margin-bottom: 8px;
text-align: center;
}
.note {
margin-top: 8px;
font-style: italic;
color: var(--vp-c-warning-1);
padding: 8px;
background-color: var(--vp-c-warning-soft);
border-radius: 4px;
border-left: 3px solid var(--vp-c-warning-1);
}
</style>
容器水印
对非图片元素应用水印:
点击查看代码
vue
<template>
<div class="demo-container">
<div
v-watermarker="{
text: '容器水印',
fontSize: 20,
opacity: 0.25,
textColor: '#333333',
gap: 80
}"
class="watermark-box container-demo"
>
<div class="content">
<h3>容器水印示例</h3>
<p>这是一个应用了水印的容器元素</p>
<p>水印会覆盖在容器内容上方</p>
<p>但不会影响容器内容的交互</p>
</div>
</div>
<div class="description">
<p>对于非图片元素,水印会作为一个覆盖层添加到元素上方,不会影响元素内容的交互。</p>
</div>
</div>
</template>
<script setup>
import { vWatermarker } from '@cp-vuedir/core'
</script>
<style scoped>
.demo-container {
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
}
.watermark-box {
width: 100%;
height: 400px;
border: 1px solid var(--vp-c-divider);
border-radius: 4px;
overflow: hidden;
position: relative;
margin-bottom: 15px;
}
.container-demo {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: var(--vp-c-bg-soft);
padding: 20px;
}
.content {
text-align: center;
z-index: 1;
}
.content h3 {
margin-bottom: 15px;
font-size: 18px;
color: var(--vp-c-text-1);
}
.content p {
margin: 10px 0;
font-size: 16px;
color: var(--vp-c-text-1);
}
.demo-button {
margin-top: 15px;
padding: 8px 16px;
background-color: var(--vp-c-brand);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: background-color 0.3s;
}
.demo-button:hover {
background-color: var(--vp-c-brand-dark);
}
.description {
font-size: 14px;
color: var(--vp-c-text-2);
margin-top: 10px;
text-align: center;
}
</style>
功能特点
- 图片水印保护:当应用于
<img>
标签时,会将图片转换为 Canvas 元素,并将水印直接绘制到图片上,防止用户通过控制台查看原始图片 - 容器水印:当应用于非图片元素时,会在元素上方添加一个带有水印的层
使用示例
图片水印
html
<!-- 直接在图片上应用水印 -->
<img v-watermarker="{ text: '水印文本' }" src="/path/to/image.jpg" alt="图片描述" />
<!-- 自定义水印样式 -->
<img
v-watermarker="{
text: '公司名称',
direction: 'diagonal',
fontSize: 20,
opacity: 0.2
}"
src="/path/to/image.jpg"
alt="图片描述"
/>
容器水印
html
<!-- 在容器元素上应用水印 -->
<div v-watermarker="{ text: '水印文本' }" class="container">
<!-- 容器内容 -->
</div>
SSR 兼容性注意事项
由于水印指令使用了浏览器 API(如 document、Canvas 等),在服务端渲染环境中需要使用 <ClientOnly>
组件包装使用该指令的组件:
html
<ClientOnly>
<div v-watermarker="{ text: '水印文本' }">
<!-- 内容 -->
</div>
</ClientOnly>
或者使用条件导入方式:
js
if (!import.meta.env.SSR) {
// 导入和使用水印指令
}
API
属性名 | 说明 | 类型 | 是否必选 | 默认值 |
---|---|---|---|---|
text | 水印文本内容 | string | 水印文本 | |
direction | 水印方向,可选值:'horizontal'(水平)/'vertical'(垂直)/ 'diagonal'(对角线) | string | diagonal | |
fontSize | 字体大小 | number | 16 | |
fontFamily | 字体族 | string | AaArial | |
textColor | 文字颜色 | string | #000000 | |
opacity | 透明度 | number | 0.1 | |
gap | 水印之间的间距 | number | 100 | |
zIndex | 水印层级(仅对非图片元素有效) | number | 1000 |
注意事项
使用限制
- 对于图片元素,水印会将
<img>
标签替换为<canvas>
元素 - 确保容器元素具有明确的宽高,否则水印可能无法正确显示
- 水印会自动适应容器大小
- 对于非图片元素,水印层的 pointer-events 设置为 none,不会影响容器内容的交互
跨域图片
对于远程图片,如果图片服务器没有设置正确的 CORS 头(Cross-Origin Resource Sharing),可能会导致无法正确应用水印。在这种情况下,Canvas 会被污染(tainted),无法读取或修改图片数据。
安全与性能
- 图片水印通过 Canvas 直接合并图片和水印,防止用户通过控制台查看原始图片
- 使用 Canvas 绘制水印,性能优良
- 水印图案会被缓存,不会重复绘制
- 容器大小变化时会自动重新计算水印位置