watermark.js
import Cookies from "js-cookie"
let domain = '.xxx.com'
if (window.location.host.indexOf("localhost") !== -1) {
domain = "localhost"
} else {
domain = isProd ? '.xxx.net' : '.xxxx.com'
}
function createImgBase(options) {
const canvas = document.createElement('canvas')
const text = options.content
// 因为要实现文字交错效果,所以这里生成两倍宽度的图片
canvas.width = options.width * 2
canvas.height = options.height
const ctx = canvas.getContext('2d')
if (ctx) {
// X轴阴影距离,负值表示往上,正值表示往下
// ctx.shadowOffsetX = 2;
// // Y轴阴影距离,负值表示往左,正值表示往右
// ctx.shadowOffsetY = 2;
// // 阴影的模糊程度
// ctx.shadowBlur = 2
ctx.font = options.font
ctx.fillStyle = options.color
ctx.rotate(options.rotateDegree)
ctx.textAlign = 'left'
ctx.fillText(text, options.x, options.y)
}
return canvas.toDataURL('image/png')
}
const watermark = {
set: function ({
width = 340,
height = 240,
content = '水印',
font = '14px PingFang SC, sans-serif',
color = '#E8E9EB',
rotate = -16
}) {
const option = {
width,
height,
content,
font,
color,
rotateDegree: (rotate * Math.PI) / 180,
}
const dataUri1 = createImgBase({
...option,
x: 100,
y: 140,
})
const dataUri2 = createImgBase({
...option,
x: 400,
y: 340,
})
/* 新建一个用于填充canvas水印的标签,之所以没有直接在body上添加,是因为z-index对个别内容影响,才考虑的不用body */
// pointer-events:none 限制鼠标事件及对覆盖元素层进行穿透
var watermark = document.createElement('div')
const styleStr = `
position:fixed;
top:80px;
left:220px;
width:100vw;
height:100vh;
z-index:99;
pointer-events:none;
background-repeat:repeat;
mix-blend-mode: multiply;
background-image: url(${dataUri1}), url(${dataUri2});
background-size: ${option.width * 2}px ${option.height}px;`
watermark.setAttribute('style', styleStr)
watermark.classList.add('watermark')
document.body.appendChild(watermark)
//此方法是防止用户通过控制台修改样式去除水印效果
/* MutationObserver 是一个可以监听DOM结构变化的接口。 */
const observer = new MutationObserver(() => {
const wmInstance = document.querySelector('.watermark')
if ((wmInstance && wmInstance.getAttribute('style') !== styleStr) || !wmInstance) {
//如果标签在,只修改了属性,重新赋值属性
if (wmInstance) {
// 避免一直触发
// observer.disconnect();
// console.log('水印属性修改了');
wmInstance.setAttribute('style', styleStr)
} else {
/* 此处根据用户登录状态,判断是否终止监听,避免用户退出后登录页面仍然有水印 */
if (Cookies.get('token', { path: "", domain: domain })) {
//标签被移除,重新添加标签
// console.log('水印标签被移除了');
document.body.appendChild(watermark)
} else {
observer.disconnect()
}
}
}
})
observer.observe(document.body, {
attributes: true,
subtree: true,
childList: true
})
},
close: function () {
/* 关闭页面的水印,即要移除水印标签 */
let watermark = document.querySelector('.watermark')
if (watermark) {
document.body.removeChild(watermark)
}
}
}
export default watermark
main.js
// 引入水印文件地址
import watermark from '@/utils/watermark.js'
Vue.prototype.$watermark = watermark
layout/index.vue
mounted() {
let text = 'xxx ' + this.userName
this.$watermark.set({
content: text, //水印内容
font: 'lighter 14px PingFang SC, sans-serif', //字体
color: '#E8E9EB', // 色值
rotate: -16 //倾斜角度
})
},
beforeDestroy() {
this.$watermark.close()
}