javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JS实现水印

关于JS前端实现水印的代码操作

作者:十串

这篇文章主要介绍了关于JS前端实现水印的代码操作,文中给出了详细的实现思路和代码示例供大家参考,对大家的学习或工作有一定的帮助,需要的朋友可以参考下

网页水印

实现思路

代码操作

function createImgBase(options) {
  const { content, width, height } = options;
  const canvasDom = document.createElement("canvas");
  let ctx = canvasDom.getContext("2d");
  canvasDom.width = width;
  canvasDom.height = height;
  if (ctx) {
    // 设置画笔的方向
    ctx.rotate((-14 * Math.PI) / 180);
    // 设置水印样式
    ctx.fillStyle = "rgba(100,100,100,0.4)";
    ctx.font = "italic 20px Arial";
    // 渲染水印
    content.forEach((text, index) => {
      ctx.fillText(text, 10, 30 * (index + 1)); // 纵向拉开30的间距
    });
  }
  // document.body.appendChild(canvasDom);
  // 将canvas转为图片
  return canvasDom.toDataURL("image/png");
}

// createImgBase({
//   content: ["介四嘛呀", "介四sui印", "内部机密材料", "严禁外泄!"],
//   width: 200,
//   height: 200,
// });
function getWaterMark({
  content,
  className,
  canvasHeight = 140,
  canvasWidth = 150,
}) {
  // 生成图片
  const data_url = createImgBase({
    content,
    width: canvasWidth,
    height: canvasHeight,
  });
  // 通过设置伪元素样式,添加水印图片为背景图
  const defaultStyle = `
  .${className} {
    position: relative;
  }
  .${className}::after {
    content: "";
    background-image: url(${data_url});
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    pointer-events: none;
  }`;

  const styleDom = document.createElement("style");
  styleDom.innerHTML = defaultStyle;
  document.head.appendChild(styleDom);
}
// getWaterMark({
//   content: ["介四嘛呀", "介四sui印", "内部机密材料", "严禁外泄!"],
//   className: "content",
// });
function listenerDOMChange(className) {
  // 获取要监听的节点
  const targetNode = document.querySelector(`.${className}`);
  // 创建监听器
  const observer = new MutationObserver(mutationList => {
    // 遍历变化记录
    for (let mutationRecord of mutationList) {
      // 如果目标节点的class属性发生变化,判断是不是类名被删了,是的话把类名加回去
      if (mutationRecord.attributeName === "class") {
        if(!Array.from(targetNode.classList).includes(className)) {
          targetNode.classList.add(className)
        }
      }
    }
  });
  // 启动监听
  observer.observe(targetNode, {
    attributes: true,
  });
}

function getWaterMark({
      content,
      className,
      canvasHeight = 140,
      canvasWidth = 150,
}) {
  // 监听
  listenerDOMChange(className);
  const data_url = createImgBase({
    content,
    width: canvasWidth,
    height: canvasHeight,
  });
  // ...
  const styleDom = document.createElement("style");
  styleDom.innerHTML = defaultStyle;
  document.head.appendChild(styleDom);
}

关于MutationObserver

MutationObserver 用来监听DOM的变化,DOM的增删、DOM属性的变化,子结点和文本内容的变化,都可以被监听。

MutationObserver 的监听和事件不同,事件是同步的,DOM的变化会立即触发对应的事件,而 MutationObserver 是异步的,会在下一个微任务执行时触发监听回调。

const observer = new MutationObserver((mutationsList, observer) => {
    // mutationsList mutationRecord数组 记录了DOM的变化
    // observer MutationObserver的实例

    // 监听回调
    console.log(mutationsList, observer);
})

mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});
// node 监听的节点
// config 监听配置(要监听哪些内容)
// observer.observe(node, config);
mutationObserver.observe(document.documentElement, {
  attributes: true,  // 属性变化
  attributeOldValue: true,  // 观察attributes变动时,是否需要记录变动前的属性值
  attributeFilter: [‘class',‘src']  // 需要观察的特定属性

  characterData: true,  // 节点内容、文本的变化
  characterDataOldValue: true,  // 观察characterData变动时,是否需要记录变动前的属性值

  childList: true,  // 子结点变化
  subtree: true,    // 所有后代节点
});

// 停止监听
mutationObserver.disconnect()

// 清除变动记录
mutationObserver.takeRecords()

图片水印

实现思路

方案一:通过oss添加水印 方案二:通过canvas生成带有水印的图片

oss实现

oss方式不做过多描述了 简单来说就是通过在获取图片时,在图片链接上增加参数,让oss生成一张带水印的图片。 注意点:

canvas实现

async function imgToCanvas(cav, imgSrc) {
  const img = new Image();
  img.src = imgSrc;
  // 防止因跨域导致的图片加载失败(该方法有局限性)
  img.setAttribute("crossOrigin", "anonymous");
  // 等待图片加载
  await new Promise(resolve => (img.onload = resolve));
  cav.width = img.width;
  cav.height = img.height;
  const ctx = cav.getContext("2d");
  if (ctx) {
    ctx.drawImage(img, 0, 0);
  }
  return cav;
}
function addWaterMask(cav, content) {
  const ctx = cav.getContext("2d");
  ctx.fillStyle = "rgba(100,100,100,0.2)";
  ctx.font = `24px serif`;
  ctx.translate(0, 0);
  ctx.rotate((5 * Math.PI) / 180);
  // 生成水印
  let x = 0, y = 0;
  while (x < cav.width) {
    y = 0;
    while (y < cav.height) {
      ctx.fillText(content, x, y);
      y += 100;
    }
    x += 150;
  }
}
(async function () {
  const canvas = document.createElement("canvas");
  await imgToCanvas(
    canvas,
    "https://pp.myapp.com/ma_pic2/0/shot_54360764_1_1716462139/0"
  );
  addWaterMask(canvas, "介四sui印");
  // document.body.appendChild(canvas);
  return canvas.toDataUrl("image/png")
})();

到此这篇关于关于JS前端实现水印的代码操作的文章就介绍到这了,更多相关JS实现水印内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文