JS+canvas封装全屏水印、局部水印、多个dom水印

一、前言

  • 之前看到element的水印功能比较有意思,特意学习了一下水印的方法,在生成基本水印的基础上又进行了二次封装,可适用多场景,vue项目也可以搭配路由、用户信息等等进行使用。

  • 核心是通过创建一个canvas元素,并在其上绘制水印文本,然后将canvas转换为图片格式,再将该图片设置为一个div元素的背景,参数可以指定将水印添加到哪个DOM元素上,不同标识符可添加不同dom。

二、代码注释详解

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div class="box">
        <div class="box1">box1</div>
        <div class="box2">box2</div>
        <div class="box3">box3</div>
    </div>
</body>
<script>
    // 参数  
    // str---水印文本  用来展示的文字
    // id---唯一ID     当前水印区域的唯一标识,用于区分多个区域水印
    // dom---DOM元素类名 传入类名则为区域水印,否则全屏水印
    const setWatermark = (str, id, dom) => {
        // 如果页面上已经存在该ID的水印元素,则先移除  
        if (document.getElementById(id) !== null) document.body.removeChild(document.getElementById(id));
        // 创建一个canvas元素,用于绘制水印  
        const can = document.createElement('canvas');
        // 设置canvas的宽度和高度  
        can.width = 200;
        can.height = 130;
        // 获取canvas的2d绘图上下文  
        const cans = can.getContext('2d');
        // 旋转绘图上下文,设置水印的倾斜角度  
        cans.rotate((-20 * Math.PI) / 180);
        // 设置水印文本的字体样式和大小  
        cans.font = '14px Vedana';
        // 设置水印文本的颜色和透明度  
        cans.fillStyle = 'rgba(200, 200, 200, 0.30)';
        // 设置水印文本的基线对齐方式  
        cans.textBaseline = 'middle';
        // 在canvas上绘制水印文本  
        cans.fillText(str, can.width / 10, can.height / 2);
        // 创建一个变量用于接收DOM
        let div;
        // 如果传入了dom参数,则获取该类名的DOM元素,将水印添加到该元素上  
        if (dom) {
            div = document.querySelector('.' + dom)
        } else {
            // 如果没有传入dom参数,则创建一个新的div元素,并设置其宽高为页面宽高  
            div = document.createElement('div');
            div.style.width = `${document.documentElement.clientWidth}px`;
            div.style.height = `${document.documentElement.clientHeight}px`;
            // 设置div元素的位置为页面左上角  
            div.style.top = '0px';
            div.style.left = '0px';
            // 设置div元素的定位方式为固定定位,使其不随页面滚动而移动  
            div.style.position = 'fixed';
            // 将新创建的div元素添加到body元素中  
            document.body.appendChild(div);
        }
        // 设置div元素的ID,用于后续识别和移除水印  
        div.id = id;
        // 设置div元素不参与鼠标事件,避免影响页面其他元素的交互  
        div.style.pointerEvents = 'none';
        // 设置div元素的z-index层级非常高,确保其显示在页面其他元素之上  
        div.style.zIndex = '10000000';
        // 设置div元素的背景为水印图片,并设置为重复显示,从而铺满整个页面  
        div.style.background = `url(${can.toDataURL('image/png')}) left top repeat`;
        // 返回水印元素的ID,可用于后续移除水印  
        return id;
    };
    // 调用传参 vue项目中此处可以在路由监听中与携带参数交互或者根据登陆者信息等交互,其他场景可以自行开发
    // 第一种 全屏水印
    setWatermark('全屏水印', '1');
    // 第二种 指定dom水印
    // setWatermark('指定dom水印', 11, 'box1');
    // 第二种 多个dom水印
    // setWatermark('多个dom水印', 111, 'box1');
    // setWatermark('多个dom水印', 222, 'box2');
    // setWatermark('多个dom水印', 333, 'box3');
</script>
<style>
    .box {
        display: flex;
    }
    .box1,
    .box2,
    .box3 {
        width: 500px;
        height: 500px;
        line-height: 500px;
        text-align: center;
        margin-right: 10px;
        border: 1px solid red;

    }
</style>
</html>
相关推荐
一枚前端小能手几秒前
🔥 SSR服务端渲染实战技巧 - 从零到一构建高性能全栈应用
前端·javascript
Komorebi_9999几秒前
Vue3 provide/inject 详细组件关系说明
前端·javascript·vue.js
用户14125016652715 分钟前
一文彻底掌握 ECharts:从配置解读到实战应用
前端
LRH17 分钟前
React 架构设计:从 stack reconciler 到 fiber reconciler 的演进
前端
VIjolie18 分钟前
文档/会议类应用的协同同步机制(OT/CRDT简要理解)
前端
不一样的少年_19 分钟前
【前端效率工具】:告别右键另存,不到 50 行代码一键批量下载网页图片
前端·javascript·浏览器
golang学习记20 分钟前
从0死磕全栈之Next.js 企业级 next.config.js 配置详解:打造高性能、安全、可维护的中大型项目
前端
1024小神22 分钟前
next项目使用状态管理zustand说明
前端
Asort23 分钟前
JavaScript设计模式(八):组合模式(Composite)——构建灵活可扩展的树形对象结构
前端·javascript·设计模式
刘永胜是我24 分钟前
【iTerm2 实用技巧】解决两大顽疾:历史记录看不全 & 鼠标滚轮失灵
前端·iterm