使用Canvas实现页面水印

文章介绍了一个用于在网页上添加水印的JavaScript函数,利用HTML5的canvas元素和toDataURL方法生成基于内容的数据URL,然后将其作为背景图像应用到页面的固定位置。水印可以自定义大小、字体、颜色、角度等属性,并且能响应容器的变化动态更新。示例代码展示了如何在Vue3应用中集成这个水印函数,根据用户信息动态显示用户名作为水印内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

canvastoDataURL()方法是返回一个包含图片展示的 数据URL

可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。

一、语法

canvas.toDataURL(type, encoderOptions);
二、参数

1、type:图片格式,默认为 image/png,可以是其他image/jpeg等

2、encoderOptions:0到1之间的取值,主要用来选定图片的质量,默认值是0.92,超出范围也会选择默认值。

三、返回值

返回值是一个数据url,是base64组成的图片的源数据、可以直接赋值给图片的src属性。

注意事项:设置的宽度高度不易过大或者高度或宽度是0,会导致 canvas.toDataURL()返回为data:,,从而不生成图片地址

设置pointer-events:none;样式实现点击穿透,在这个容器内通过js生成小的水印div,每个水印div内展示一个要显示的水印内容,样式repeat重复铺满整个容器

// 定义水印函数
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

结合项目技术栈vue3.0+ts

需要全局使用,则可以在App.vue文件中引入js文件并使用该函数

<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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值