最近接了个需求,要求在页面上添加水印,水印内容是变化的(每个用户的信息是不一样的),要均匀规则的分布在页面上,并且不能影响页面其他功能的正常使用。在参考了百度各位大佬的实现方式之后,终于做出一个自认为比较简单好用的水印组件。
核心是两点
1、使用canvas绘制文字,并且将toDataURL()方法输出的数据设置为dom的背景图片。设置背景图片的好处是,图片平铺之后,会很规则
2、给要平铺的dom元素设置pointer-events: none;样式。这个样式是元素穿透,意味着这个dom上面所有的事件全部失效。把该元素覆盖在整个页面上,加上了水印,也不影响页面其他功能的使用。完美!!!
这里是template
<template>
<div class="wrterMarkWrap" ref="wrterMarkWrap"></div>
</template>
这里是方法,也就是canvas绘图的实现
<script>
const canWidth = 400 // 定义图片的宽
const canHeight = 250 // 定义图片的高
export default {
props: {
textColor: { // 水印文字颜色
type: String,
default: 'rgba( 80, 119, 146, .7)'
},
rotateDeg: { // 文字旋转角度
type: Number,
default: -25,
},
markTxt: { // 水印内容
type: String,
default: ''
},
},
data () {
return {
can: null, // 画布
textSize: 14, // 文字大小
showMark: true, // 是否使用水印
}
},
watch: {
markTxt: { // 监视绘制文字
immediate: true,
handler ( newVal, oldVal ) {
if ( newVal && newVal != oldVal && this.showMark ) { // 此处可加定时器,防止dom未生成,获取不到组件实例
this.initCanvas()
}
}
},
},
methods: {
initCanvas () {
this.createMark()
this.drawWarterMark()
},
// 使用canvas绘制文字,并保存
createMark () {
let writetxt = '自制水印-' + this.markTxt // 设置水印文字
this.can = document.createElement('canvas') // 创建canvas
this.can.width = canWidth // 定义canvas的width
this.can.height = canHeight // 定义canvas的height
let ctx = this.can.getContext('2d')
let txtWidth = ctx.measureText(writetxt).width // 绘制文字所占宽度
ctx.translate( (canWidth - txtWidth) / 2, canHeight / 2); // 移动canvas的绘制起始点
ctx.rotate(this.rotateDeg * Math.PI / 180) // 旋转canvas
ctx.font = `${this.textSize}px 微软雅黑` // 设置字体信息
ctx.fillStyle = this.textColor // 字体颜色
ctx.textBaseline = 'hanging' // 设置文字基准线
ctx.fillText(writetxt, 0, 0) // 绘制文字
},
drawWarterMark () { // 把canvas的输出文字设置为元素的背景图
this.$refs.wrterMarkWrap.style.background = 'url(' + this.can.toDataURL('image/png') + ') left top repeat'
},
}
}</script>
这里是样式,不要忘记了给元素设置事件穿透
<style lang="scss" scoped>
.wrterMarkWrap {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
z-index: 20;
pointer-events: none; // 事件穿透,该元素所有的事件全部失效,最重要的
}
</style>
以上就是全部代码,代码是按照自己习惯写的,有什么不对之处,请指出。本人是canvas菜鸟,只会做点简单的东西,刚好就是应用自己会的折腾出了水印组件。