这里我们采用为目标元素添加背景图的方案,代码原理解析:
- 根据用户提供的参数生成一个单位水印的元素,插入到 Dom 中。
- 利用 canvas.toDataURL 的 api 生成单位水印的 base64 位编码。
- 在 head 中插入 <style> 标签,里面填入背景样式。
源码如下:
waterMarked.js
/**
* 页面水印函数
* created by Max.Law on 2023/3/17
*/
export const createImgBase = options => {
const canvas = document.createElement('canvas')
const text = options.content
canvas.width = options.width
canvas.height = options.height
const ctx = canvas.getContext('2d')
if (ctx) {
ctx.shadowOffsetX = 2
ctx.shadowOffsetY = 2
ctx.shadowBlur = 2
ctx.font = options.font
ctx.fillStyle = options.color
ctx.translate(options.width / 2, options.height / 2)
ctx.rotate(options.rotateDegree)
ctx.textAlign = 'center'
ctx.fillText(text, options.x, options.y)
}
return canvas.toDataURL('image/png') //base64位编码
}
/**
* 生成水印
* @param {String} className 水印类名
* @param {String} content 内容
* @param {String} font 字体
* @param {String} color 自定义样式: 如字体颜色(使用RGBA)
* @param {Number} rotate 翻转角度
* @param {String} position 水印定位方式
* @param {Number} top 距离顶部位置
* @param {Number} left 距离左部位置
* @param {Number} zIndex 水印层级
* @param {Number} spacing 水印间距
* @param {Boolean} print 是否只在打印时使用
*/
export const genWaterMark = ({
className = 'watermarked',
content = 'Max.Law',
font = '14px PingFang SC, sans-serif',
color = 'rgba(156, 162, 169, 0.3)',
rotate = -45,
position = 'absolute',
top = 0,
left = 0,
zIndex = 1000,
spacing = 70,
print = false,
}) => {
const contentDom = document.createElement('span')
contentDom.innerHTML = content
contentDom.style.font = font
contentDom.style.opacity = 0
contentDom.style.position = 'absolute'
const body = document.querySelector('body')
body.appendChild(contentDom)
const textWidth = contentDom.offsetWidth
body.removeChild(contentDom)
const option = {
width: textWidth + spacing,
height: textWidth + spacing,
content,
font,
color,
rotateDegree: (rotate * Math.PI) / 180,
x: 0,
y: 0,
}
const imgBase64 = createImgBase({ ...option })
const defaultHeight = document.getElementsByClassName(className)[0].scrollHeight
let defaultStyle = document.createElement('style')
if (print) {
defaultStyle.media = 'print'
}
defaultStyle.innerHTML = `.${className}:after {
content: '';
display: block;
width: 100%;
height: ${defaultHeight}px;
${top || top === 0 ? `top: ${top}px;` : ''}
${left || left === 0 ? `left: ${left}px;` : ''}
background-repeat: repeat;
pointer-events: none;
${position ? `position: ${position}` : ''};
${zIndex ? `z-index:${zIndex}` : ''};
background-image: url(${imgBase64});
background-size: ${option.width}px ${option.height}px;
}`
document.head.appendChild(defaultStyle)
}
使用
import { genWaterMark } from '@/plugins/watermarked.js' //你自己的路径
genWaterMark({
className: 'printArea',
content: '水印文案',
})
补充
- 水印添加对象必须得用 class 标记;
- 水印对象需设置
position: relative;
样式,不然则对 boby 定位; - 也可以使用参数
position = fixed
直接对页面定位; - 水印默认宽度为 100%,高度则为元素的 scrollHeight;
- 可以使用参数 print 决定是否只在打印时添加水印;