React 封装水印 hooks

323 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情

基本上的水印框架

创建一个 div,给水印盒子添加类名,设置 div 的样式属性,比如添加水印距离顶部距离、水印页面层级等等。

let DivLayer = document.createElement('div');
DivLayer.innerHTML = StrColumn;
DivLayer.id = 'react-watermark'; // 给水印盒子添加类名
DivLayer.style.position = 'fixed';
DivLayer.style.top = '0px'; // 整体水印距离顶部距离
DivLayer.style.zIndex = '99999'; // 水印页面层级
DivLayer.style.pointerEvents = 'none'; // 元素永远不会成为鼠标事件的 target

document.body.appendChild(DivLayer); // 添加到页面中

插入内容

StrColumn 变量即需要填写入页面中的内容。我们先写一个字符串,看一下效果。

let StrColumn = '版权归属禁止分享';

图片.png

一个肯定不够,那就多来几个

let StrColumn = '';
for (let i = 0; i < 100; i++) {
  StrColumn +=
    '<div style="white-space: nowrap;">版权归属禁止分享</div>';
}

图片.png

加点样式

加点样式进去,比如对于一个水印来说,这个颜色太深了,距离太近了,应该再来点旋转角度。那我们插入的内容就不能单单只是文本了,应该换成 HTML。

let DivLine = document.createElement('div');
DivLine.innerHTML = StrLine;

'<div style="white-space: nowrap;">' + DivLine.innerHTML + '</div>';
let StrLine = '';
for (let i = 0; i < 5; i++) {
  StrLine +=
    '<span style="display: inline-block; line-height:' +
    height +
    'px; width:' +
    width +
    'px; text-align: center; transform:rotate(' +
    rotation +
    'deg); color:' +
    color +
    '; font-size:' +
    size +
    'px; opacity:' +
    opacity +
    ';">' +
    content +
    '</span>';
}

计算显示次数

接下来我们应该计算一行显示几列,因为我们不能确定的是,循环结束的次数。

let Line = parseInt(document.body.clientWidth / width);

同样计算一列显示几行

let Column = parseInt(document.body.clientHeight / height);

为了避免重复生成,需要在最开始判断是否存在该水印。如果存在,那就不需要走下面的逻辑

if (document.getElementById('react-watermark') !== null) {
  return;
}

图片.png

使用方式

useEffect(() => {
  watermark('版权归属禁止分享', '130', '205', '-20', 'black', '14', '.08')
}, [])

完成代码

export default function WaterMark(content, height, width, rotation, color, size, opacity) {
  if (document.getElementById('react-watermark') !== null) {
    return;
  }
  let Line = parseInt(document.body.clientWidth / width);
  let StrLine = '';
  for (let i = 0; i < Line; i++) {
    StrLine +=
      '<span style="display: inline-block; line-height:' +
      height +
      'px; width:' +
      width +
      'px; text-align: center; transform:rotate(' +
      rotation +
      'deg); color:' +
      color +
      '; font-size:' +
      size +
      'px; opacity:' +
      opacity +
      ';">' +
      content +
      '</span>';
  }
  let DivLine = document.createElement('div');
  DivLine.innerHTML = StrLine;

  let Column = parseInt(document.body.clientHeight / height);
  let StrColumn = '';
  for (let i = 0; i < Column; i++) {
    StrColumn +=
      '<div style="white-space: nowrap;">' + DivLine.innerHTML + '</div>';
  }
  let DivLayer = document.createElement('div');
  DivLayer.innerHTML = StrColumn;
  DivLayer.id = 'react-watermark';
  DivLayer.style.position = 'fixed';
  DivLayer.style.top = '0px';
  DivLayer.style.zIndex = '99999';
  DivLayer.style.pointerEvents = 'none';

  document.body.appendChild(DivLayer);
};