JavaScript 方法封装:前端添加水印简单方案

210 阅读1分钟

预览

通过 dom 大小计算水印,生成图片,替换背景,支持自定义样式。

动画12.gif

代码

/**
 * 给对应 dom 生成水印
 * @example
 * watermark(document.body, 'My Watermark', { fontSize: 20, opacity: 0.5, angle: -30, color: 'red', fontFamily: 'Arial', repeat: true, backgroundOpacity: 0.05 });
 * watermark(document.body, 'My Watermark'); /// 在 body 中生成水印
 * watermark(document.body, 'My Watermark', { fontSize: 120, color: 'red', repeat: false, angle: 0 }); /// 在 body 中生成水印
 * watermark(document.body, 'My Watermark', { fontSize: 20, color: 'red', repeat: true, angle: 90 }); /// 在 body 中生成水印
 * @param dom 需要生成水印的 dom
 * @param text 水印内容
 * @param options 样式配置
 * @returns
 */
export function watermark(dom: any, text: string, options: any = {}) {
  const {
    fontSize = 16,
    opacity = 0.3,
    angle = -45,
    color = '#000',
    fontFamily = 'Arial',
    repeat = true,
    backgroundOpacity = 0.05,
  } = options;

  const canvas = document.createElement('canvas');
  const ctx: any = canvas.getContext('2d');
  ctx.font = `${fontSize}px ${fontFamily}`;
  const textWidth = ctx.measureText(text).width;
  const textHeight = fontSize;
  const canvasWidth =
    angle % 180 == 0
      ? textWidth * 2
      : angle % 90 == 0
      ? textHeight * 2
      : (Math.abs(textWidth * Math.cos((angle * Math.PI) / 180)) +
          Math.abs(textHeight * Math.sin((angle * Math.PI) / 180))) *
        2;
  const canvasHeight =
    angle % 180 == 0
      ? textHeight * 2
      : angle % 90 == 0
      ? textWidth * 2
      : (Math.abs(textHeight * Math.cos((angle * Math.PI) / 180)) +
          Math.abs(textWidth * Math.sin((angle * Math.PI) / 180))) *
        2;

  canvas.width = canvasWidth;
  canvas.height = canvasHeight;

  ctx.font = `${fontSize}px ${fontFamily}`;
  ctx.fillStyle = color;
  ctx.globalAlpha = opacity;
  ctx.textAlign = 'center';
  ctx.textBaseline = 'middle';

  const centerX = canvasWidth / 2;
  const centerY = canvasHeight / 2;
  ctx.translate(centerX, centerY);
  ctx.rotate((angle * Math.PI) / 180);
  ctx.fillText(text, 0, 0);
  ctx.rotate((-angle * Math.PI) / 180);
  ctx.translate(-centerX, -centerY);

  const backgroundImage = `url(${canvas.toDataURL('image/png')})`;
  dom.style.backgroundImage = backgroundImage;
  dom.style.backgroundRepeat = repeat ? 'repeat' : 'no-repeat';
  dom.style.backgroundSize = `${
    dom.clientWidth === canvasWidth ? canvasWidth : dom.clientWidth / Math.ceil(dom.clientWidth / canvasWidth)
  }px ${
    dom.clientHeight === canvasHeight ? canvasHeight : dom.clientHeight / Math.ceil(dom.clientHeight / canvasHeight)
  }px`;
  dom.style.backgroundColor = `rgba(0, 0, 0, ${backgroundOpacity})`;
  dom.style.backgroundPosition = 'center';
}

也可直接安装 js-xxx 工具库直接使用

// npm i js-xxx
import { watermark } from 'js-xxx';

watermark(document.body, 'My Watermark', { fontSize: 20, opacity: 0.5, angle: -30, color: 'red', fontFamily: 'Arial', repeat: true, backgroundOpacity: 0.05 });
watermark(document.body, 'My Watermark'); /// 在 body 中生成水印
watermark(document.body, 'My Watermark', { fontSize: 120, color: 'red', repeat: false, angle: 0 }); /// 在 body 中生成水印
watermark(document.body, 'My Watermark', { fontSize: 20, color: 'red', repeat: true, angle: 90 }); /// 在 body 中生成水印