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>
相关推荐
华科云商xiao徐几秒前
Java并发编程常见“坑”与填坑指南
javascript·数据库·爬虫
奶昔不会射手7 分钟前
css3之grid布局
前端·css·css3
举个栗子dhy11 分钟前
解决在父元素上同时使用 onMouseEnter和 onMouseLeave时导致下拉菜单无法正常展开或者提前收起问题
前端·javascript·react.js
Coding_Doggy17 分钟前
苍穹外卖前端Day1 | vue基础、Axios、路由vue-router、状态管理vuex、TypeScript
前端
前端与小赵17 分钟前
vue3和vue2生命周期的区别
前端·javascript·vue.js
用户4582031531721 分钟前
10个你可能不知道的实用CSS技巧,立竿见影提升开发效率
前端·css
在逃牛马21 分钟前
【Uni-App+SSM+MP 宠物实战】Day4:Uni-App 项目初始化
前端
J_Asia23 分钟前
如何exclude不必要的so文件?
前端
一鹿有你们~24 分钟前
面试题-前端如何解决跨域
前端·javascript·跨域