前端水印

in 默认分类 with 0 comment

实现功能

  1. DOM更改ID,className,style,会重新生成一份水印插入到DOM中
  2. 支持Echarts下载时添加水印
saveAsImage : {//设置Echarts下载水印
    show: true,
    backgroundColor:{
        type: 'pattern',
        image: __canvasWM({background:'#fff',render:false}),
        repeat: 'repeat'
    }
}
(function () {
        function __canvasWM({
            container = document.querySelector('#bi-content'),
            width = '200px',
            height = '150px',
            textAlign = 'right',
            textBaseline = 'middle',
            font = "14px microsoft yahei",
            fillStyle = 'rgba(184, 184, 184, 0.2)',
            content = '请勿外传',
            rotate = '-30',
            zIndex = 3,
            background = '',//Echarts 下载时图表背景颜色
            render = true //是否将生成好的水印insert到DOM中 Echarts下载时水印请传false
        } = {}) {
            var args = arguments[0];
            var canvas = document.createElement('canvas');
            content = "<%= user.chinese_name %>";//使用ejs模板来渲染水印内容,防止恶意篡改,也可直接赋值
            canvas.setAttribute('width', width);
            canvas.setAttribute('height', height);
            var ctx = canvas.getContext("2d");

            ctx.textAlign = textAlign;
            ctx.textBaseline = textBaseline;
            ctx.font = font;
            if(background){
                ctx.fillStyle=background;
                ctx.fillRect(0,0,parseFloat(width),parseFloat(height));
            }
            ctx.fillStyle = fillStyle;
            ctx.rotate(Math.PI / 180 * rotate);
            ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 2);
            if(render){
                var base64Url = canvas.toDataURL();
                const watermarkDiv = document.createElement("div");
                watermarkDiv.id='mark'
                let divStyle=`
                position:absolute;
                top:0;
                left:0;
                width:100%;
                height:100%;
                z-index:${zIndex};
                pointer-events:none;
                background-repeat:repeat;
                background-image:url('${base64Url}')`
                watermarkDiv.setAttribute('style', divStyle);
                container.style.position = 'relative';
                container.insertBefore(watermarkDiv, container.firstChild);
                // 监控DOM变动
                const MutationObserver = window.MutationObserver || window.webkitMutationObserver;
                if (MutationObserver) {
                    let mo = new MutationObserver(() => {
                        const watermark = document.querySelector('#mark');
                        if ((watermark && watermark.getAttribute('style') !== divStyle) || !watermark || (watermark && watermark.className!=='')) {
                            if(watermark){
                                let parent = watermark.parentElement;
                                let removed = parent.removeChild(watermark);
                            }
                            // 避免循环触发
                            mo.disconnect();
                            mo = null;
                            this.__canvasWM.apply(this, [].slice.call(arguments))
                        }
                    });
                    // 监听对象
                    const config = {
                        attributes: true,
                        childList: true,
                        subtree: true
                    };
                    mo.observe(container, config)
                }       
            }
            return canvas;
        };
    window.__canvasWM = __canvasWM;
    __canvasWM()
})();

参考链接 https://juejin.im/entry/5b55db355188251b11097366

Responses