Use Canvas to realize page watermark

The toDataURL() method of canvas returns a data URL containing image display .

The type parameter can be used, and the default is PNG format. The resolution of the picture is 96dpi.

1. Grammar

canvas.toDataURL(type, encoderOptions);
2. Parameters

1. type: image format, the default is image/png, it can be other image/jpeg, etc.

2. encoderOptions: The value between 0 and 1 is mainly used to select the quality of the picture. The default value is 0.92, and the default value will also be selected if it exceeds the range.

3. Return value

The return value is a data url, which is the source data of the picture composed of base64, and can be directly assigned to the src attribute of the picture.

Note: the set width and height are not easy to be too large or the height or width is 0 , which will cause  canvas.toDataURL() to return data:, so that the image address will not be generated

Set pointer-events:none ; the style realizes click penetration, in this container, a small watermark div is generated through js, and each watermark div displays a watermark content to be displayed, and the style repeat is repeated to cover the entire container

// 定义水印函数
function addWatermark({
  container = document.body, // 水印添加到的容器,默认为 body
  width = "200px", // 水印 canvas 的宽度
  height = "100px", // 水印 canvas 的高度
  textAlign = "center", // 水印文字的对齐方式
  textBaseline = "middle", // 水印文字的基线
  font = "16px Microsoft Yahei", // 水印文字的字体
  fillStyle = "rgba(184, 184, 184, 0.6)", // 水印文字的填充样式
  content = '名称', // 水印文字的内容
  rotate = -30, // 水印文字的旋转角度
  zIndex = 10000, // 水印的 z-index 值
}) {
  // 生成水印 canvas
  const canvas = document.createElement("canvas");
  canvas.setAttribute("width", width);
  canvas.setAttribute("height", height);
  const ctx: any = 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) / 1);

  // 将 canvas 转换为 base64 URL
  const base64Url = canvas.toDataURL('image/png');
  console.log(base64Url)
  const __wm = document.querySelector('.__wm');
  const watermarkDiv = __wm || 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: url('${base64Url}') left top repeat;
          `;
  watermarkDiv.setAttribute("style", styleStr);
  watermarkDiv.classList.add("__wm");
  //则创建一个 div 并设置样式和类名

  if (!__wm) {
    container.style.position = 'relative';
    container.insertBefore(watermarkDiv, container.firstChild);
  }
  // 监听容器变化,当容器发生变化时重新调用 addWatermark 函数
  const MutationObserver = window.MutationObserver;
  if (MutationObserver) {
    let mo = new MutationObserver(function () {
      const __wm = document.querySelector('.__wm');
      // 只在__wm元素变动才重新调用__canvasWM
      if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
        // 避免一直触发
        mo.disconnect();
        mo = new MutationObserver(() => { });
        console.log('1');
        addWatermark({
          container: document.getElementById("app") as HTMLElement,
          width: '200px',
          height: '100px',
          textAlign: "center",
          textBaseline: "middle",
          font: "16px Microsoft Yahei",
          fillStyle: "rgba(184, 184, 184, 0.3 )",
          content: '名称',
          rotate: -30,
          zIndex: 10000
        });
      }
    });

    mo.observe(container, {
      attributes: true,
      subtree: true,
      childList: true
    });
  }
}
export default addWatermark

Combining project technology stack vue3.0+ts

If you need to use it globally, you can introduce the js file in the App.vue file and use this function

<template>
  <!-- 路由的渲染出口 -->
  <el-config-provider :locale="locale">
    <router-view />
  </el-config-provider>
</template>

<script lang="ts" setup>
import { onMounted } from 'vue'
import addWatermark from './waterMark/index'
import locale from 'element-plus/lib/locale/lang/zh-cn'
import { useUserStore } from '@/stores/user'
const user = useUserStore() // 此处使用到获取登录账号信息拿到姓名
onMounted(() => {
  // 调用 addWatermark 函数添加水印
  addWatermark({
    container: document.getElementById("app") as HTMLElement,
    width: '200px',
    height: '100px',
    textAlign: "center",
    textBaseline: "middle",
    font: "16px Microsoft Yahei",
    fillStyle: "rgba(184, 184, 184, 0.3 )",
    content: user.name,
    rotate: -30,
    zIndex: 10000,
  });
})
</script>

Guess you like

Origin blog.csdn.net/weixin_50543490/article/details/131105942