轻松实现一个水印组件


实现思路

利用canvas绘制水印文本,将它作为背景图片依附在父元素上。在最后的实现过程中,我发现如果在一个文件,同时引用水印组件的时候,只会有一个水印生效,分析得出,因为水印组件样式是使用的是属性选择器,所以只会生效一个,那么这里做获取组件的操作必须要用ref了。

关键参数与注意事项:

  1. 水印内容
  2. 水印颜色
  3. 水印角度
  4. 自定义水印宽高
  5. 需要考虑事件穿透

最终效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Watermark.vue

<template>
<div class="watermark" ref="watermarkRef"></div>
</template>

<script setup>
import { onMounted, defineProps, ref } from "vue";

const watermarkRef = ref(null);

const props = defineProps({
text: {
type: String,
required: true,
},
width: {
type: Number,
default: 150,
},
height: {
type: Number,
default: 100,
},
angle: {
type: Number,
default: -30,
},
color: {
type: String,
default: "rgba(0, 0, 0, 0.1)",
}
})

onMounted(() => {
const canvasDOM = document.createElement("canvas");
canvasDOM.width = props.width;
canvasDOM.height = props.height;
const ctx = canvasDOM.getContext("2d");
ctx.translate(props.width / 2, props.height / 2); // 移动到 canvas 中心点
ctx.rotate(props.angle * Math.PI / 180); // 将角度转换为弧度:角度 * (π/180)
ctx.font = "16px Arial";
ctx.fillStyle = props.color;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(props.text, 0, 0); // 在原点(0,0)绘制文字,因为已经移动到了中心点

// 使用 ref 直接获取当前组件的元素
const watermark = watermarkRef.value;
watermark.style.backgroundImage = `url(${canvasDOM.toDataURL('image/png')})`;
watermark.style.backgroundRepeat = "repeat";
watermark.style.backgroundSize = `${props.width}px ${props.height}px`;
watermark.style.pointerEvents = "none";
watermark.style.zIndex = "1000";
})
</script>

<style scoped>
.watermark {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 父组件
<div style="display: flex;">
<div style="width:500px;height:500px;background:#eee;position:relative;">
<Watermark
text="梨的前端小屋"
:angle="-45"
color="#808080"
/>
</div>

<div style="margin-left:10px;width:316px;height:370px;position:relative;background:#eee;">
<img src="./assets/1.png" alt="">
<Watermark
text="梨的前端小屋"
:angle="-45"
color="#808080"
/>
</div>
</div>

ok,这样就实现了我们的水印组件。

我的微信公众号: 梨的前端小屋


文章作者: 梨啊梨
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 梨啊梨 !
  目录