项目需求,在新窗口打开一张图片,图片上加上水印,我选择使用canvas生成水印蒙层
- 遇到的问题:因为我图片是auto自适应的浏览器窗口,所以会导致水印div获取不到图片的宽度,所以我在图片上绑定load方法@load="imageLoad",等图片加载完成能获取到宽度了再生成水印。
- 参考网站:# 使用canvas生成水印watermarkhttps://blog.csdn.net/weixin_44370837/article/details/123666313
- 代码记录:
<template>
<div class="preview-container">
<div class="water-mark-con">
<img :src="imgSrc" alt="" @load="imageLoad" />
</div>
</div>
</template>
<script>
export default {
data() {
return {
imgSrc: ''
}
},
created() {
this.imgSrc = this.$route.query.path
},
mounted() {
window.addEventListener('resize', this.handleResize)
},
beforeDestroy() {
window.removeEventListener('resize', this.handleResize)
},
methods: {
handleResize() {
// 窗口大小改变
this.addWaterMark()
},
imageLoad() {
// 图片100%会导致获取不到width等图片加载完成
this.addWaterMark()
},
addWaterMark() {
// const watermark = {}
// 如果水印元素已经存在先移除,再重新生成
const id = '3.14159261111'
if (document.getElementById(id) !== null) {
document
.getElementsByClassName('water-mark-con')[0]
.removeChild(document.getElementById(id))
}
// 水印内容为:姓名+id
const userInfo = JSON.parse(localStorage.getItem('userInfo'))
const waterStr = userInfo.nickname + '(' + userInfo.id + ')'
const canvasEle = document.createElement('canvas')
// 动态设置单个水印元素的宽高,这决定了页面水印的密度(水印元素图片大小,要结合rotate)
canvasEle.width = waterStr.length < 6 ? 6 * 28 : waterStr.length * 28
canvasEle.height = waterStr.length < 6 ? 6 * 10 : waterStr.length * 10
const ctx = canvasEle.getContext('2d') // 绘制2d图形
ctx.rotate((-20 * Math.PI) / 180) // 设置水印元素的倾斜度, 这一行代码要写在设置水印文字之前,涉及样式的都写在设置水印文字之前
ctx.font = '22px serif' // 设置水印文字的大小和字体
ctx.fillStyle = 'rgba(200, 200, 200, 0.8)' // 设置水印文字的颜色
ctx.textAlign = 'left' // 文本左对齐
ctx.fillText(waterStr, canvasEle.width / 18, canvasEle.height / 1.1) // 设置水印文字及坐标
// 把canvas转化为一张图片,作为背景图,添加到div
const divEle = document.createElement('div')
const waterMarkCon = document.getElementsByClassName('water-mark-con')[0] // 获取img图片的父级div
const waterMarkOffsetTop = waterMarkCon.offsetTop + 'px'
const waterMarkOffsetLeft = waterMarkCon.offsetLeft + 'px'
divEle.id = id
divEle.style.width = waterMarkCon.clientWidth + 'px' // 设置div元素的宽高
divEle.style.height = waterMarkCon.clientHeight - 4 + 'px'
divEle.style.pointerEvents = 'none'
divEle.style.position = 'fixed'
divEle.style.top = waterMarkOffsetTop
divEle.style.left = waterMarkOffsetLeft
divEle.style.background = 'url(' + canvasEle.toDataURL() + ') left top repeat'
divEle.style.zIndex = 999999
// div添加到body元素,水印生成
waterMarkCon.appendChild(divEle)
}
}
}
</script>
<style lang="scss" scoped>
.preview-container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: rgb(14, 14, 14);
}
img {
// max-width: 100%;
// max-height: 100%;
// width: auto;
// height: auto;
max-height: 100vh;
}
</style>