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>
相关推荐
weifont24 分钟前
聊一聊Electron中Chromium多进程架构
javascript·架构·electron
大得36928 分钟前
electron结合vue,直接访问静态文件如何跳转访问路径
javascript·vue.js·electron
水银嘻嘻2 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
it_remember2 小时前
新建一个reactnative 0.72.0的项目
javascript·react native·react.js
小嘟嚷ovo3 小时前
h5,原生html,echarts关系网实现
前端·html·echarts
十一吖i3 小时前
Vue3项目使用ElDrawer后select方法不生效
前端
只可远观3 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰3 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
敲代码的小吉米4 小时前
前端上传el-upload、原生input本地文件pdf格式(纯前端预览本地文件不走后端接口)
前端·javascript·pdf·状态模式
是千千千熠啊4 小时前
vue使用Fabric和pdfjs完成合同签章及批注
前端·vue.js