2021-12-09-水印

##

export const drawWaterMark = function (content = '水印') {
  const container = document.body;
  const width = '300';
  const height = '200';
  const textAlign = 'center';
  const textBaseline = 'middle';
  const font = '16px Microsoft Yahei';
  const fillStyle = 'rgba(184, 184, 184, 0.2)';
  const rotate = '30';
  const zIndex = 10000;

  const canvas = document.createElement('canvas');

  canvas.setAttribute('width', `${width}px`);
  canvas.setAttribute('height', `${height}px`);
  const ctx = canvas.getContext('2d');

  ctx.textAlign = textAlign;
  ctx.textBaseline = textBaseline;
  ctx.font = font;
  ctx.fillStyle = fillStyle;
  ctx.rotate((Math.PI / 180) * rotate);
  ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 4);

  const base64Url = canvas.toDataURL();
  const watermarkDiv = document.createElement('div');
  const styleStr = `
  position:fixed;
  top:0;
  left:0;
  bottom:0;
  right:0;
  width:100%;
  height:100%;
  z-index:${zIndex};
  pointer-events:none;
  background-repeat:repeat;
  background-image:url('${base64Url}')`;
  watermarkDiv.setAttribute('style', styleStr);
  watermarkDiv.classList.add('watermark');

  container.insertBefore(watermarkDiv, container.firstChild);

  // 防止用户通过控制台修改样式去除水印效果
  /* MutationObserver 监听DOM结构变化的接口。 */
  const observer = new MutationObserver(() => {
    const wmInstance = document.querySelector('.watermark');
    console.log('MutationObserver');
    if ((wmInstance && wmInstance.getAttribute('style') !== styleStr) || !wmInstance) {
      // 如果标签在,只修改了属性,重新赋值属性
      if (wmInstance) {
        // console.log('水印属性修改了');
        wmInstance.setAttribute('style', styleStr);
      } else {
        // console.log('水印被删除了');
        container.insertBefore(watermarkDiv, container.firstChild);
      }
    }
  });

  // 防删除
  observer.observe(container, {
    attributes: false, // node 的特性(attribute)
    subtree: false, // node 的所有后代的更改
    childList: true, // node 的直接子节点的更改
  });
  // 防编辑样式
  observer.observe(document.querySelector('.watermark'), {
    attributes: true, // node 的特性(attribute)
    subtree: true, // node 的所有后代的更改
    childList: true, // node 的直接子节点的更改
  });
};