watermarker-tool
Version:
1. 根据传入的dom元素进行水印的渲染,无需额外配置 2. 可以为不同元素区域分别渲染水印 3. 实现水印防止篡改 4. 清除水印功能
122 lines (103 loc) • 3.3 kB
JavaScript
import html2canvas from 'html2canvas';
async function watermarker(marker, wraper) {
wraper = wraper ? wraper : document.body
const hasMarker = wraper.lastElementChild && wraper.lastElementChild.id === 'watermarkerDomId'
if (hasMarker) {
return Promise.reject('不能重复添加水印')
}
const clearDom = await doMarker(marker, wraper, true)
const isListenRef = { value: true }
onMakerChange(marker, wraper, isListenRef)
function clearWaterMarker() {
isListenRef.value = false
clearDom()
}
return clearWaterMarker
}
function onMakerChange(marker, wraper, isListenRef) {
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver
if (MutationObserver) {
let mo = new MutationObserver(async (val) => {
disconnect(mo)
if (!isListenRef.value) {
return
}
if (val[0].target === wraper) {
await doMarker(marker, wraper, true)
} else {
await doMarker(marker, wraper)
}
connect(wraper, mo)
})
connect(wraper, mo)
}
}
function connect(wraper, mo) {
mo.observe(wraper, {
childList: true,
})
const hasMarker = wraper.lastElementChild && wraper.lastElementChild.id === 'watermarkerDomId'
if (hasMarker) {
mo.observe(wraper.lastElementChild, {
attributes: true,
childList: true,
subtree: true,
})
}
}
function disconnect(mo) {
mo.disconnect()
}
async function doMarker(marker, wraper, isWraper) {
const image = await getPicture(marker)
const watermarkerDom = document.createElement('div')
watermarkerDom.id = 'watermarkerDomId'
watermarkerDom.style.width = '100%'
watermarkerDom.style.height = '100%'
watermarkerDom.style.position = 'absolute'
watermarkerDom.style.top = '0'
watermarkerDom.style.left = '0'
watermarkerDom.style.zIndex = '9999'
watermarkerDom.style.pointerEvents = 'none'
watermarkerDom.style.backgroundImage = `url(${image.src})`
if (isWraper) {
const markers = wraper.children
for (let i = 0; i < markers.length; i++) {
if (markers[i].id === 'watermarkerDomId') {
wraper.removeChild(markers[i])
}
}
} else {
wraper.removeChild(wraper.lastElementChild)
}
wraper.appendChild(watermarkerDom)
if (!['absolute', 'fixed', 'relative'].includes(wraper.style.position)) {
wraper.style.position = 'relative'
}
function clearDom() {
const hasMarker = wraper.lastElementChild && wraper.lastElementChild.id === 'watermarkerDomId'
if (hasMarker) {
wraper.removeChild(wraper.lastElementChild)
}
}
return clearDom
}
async function getPicture(marker) {
const markerWraper = document.createElement('div')
markerWraper.style.height = '0px'
markerWraper.style.overflow = 'hidden'
markerWraper.appendChild(marker)
document.body.appendChild(markerWraper)
const canvas = await html2canvas(marker, {
backgroundColor: null
})
const image = convertCanvasToImage(canvas)
document.body.removeChild(markerWraper)
return image
}
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}
export default watermarker