使用JavaScript制作水印北背景

今天分享一个使用JavaScript原生编写的水印背景的效果

实现思路

首先动态创建一个div,通过绝对或相对定位的方式将div放在需要添加水印的元素上。随后动态创建一个canvas,在里面绘制自定义的字体,并倾斜45度,然后通过canvas.toDataURL()方法导出base64码图。最后将此图片放在元素遮罩层上做背景即可。

具体实现

基本工作,准备好相关html代码

<style>
    #container{
        width: 700px;
        height: 700px;
        display: flex;
        margin: auto;
        align-items: center;
        border: 1px solid #ccc;
        position: relative;
    }
    #container button{
        margin: auto;
    }
</style>
<div id="container">
   <button>大家好,我是水印底下的按钮,你们点不到我,嘻嘻</button>
</div>

1、首先编写动态创建canvas的方法,并将canvas的相关内容返回

/**
 * 创建canvas并绘制相关字体
 * @params {*} text 自定义的字体
 * @returns {*} canvas宽 - canvas的base64
 */
function MakeWaterMark(text){
    const canvas = document.createElement("canvas");
    // devicePixelRatio:查看浏览器设备的缩放比例
    const Pixel = window.devicePixelRatio || 1;
    const fontsize = 18 * Pixel;
    const ctx = canvas.getContext("2d");
    // 通过字体的多少动态计算宽高
    const { width } = ctx.measureText(text);
    // 取最大值
    const canvasWidth = Math.max(100,width) * Pixel;
    canvas.width = canvasWidth;
    canvas.height = canvasWidth;
    ctx.translate(canvasWidth / 2 , canvasWidth / 2);
    // 旋转45度
    ctx.rotate(45);
    ctx.font = `${fontsize}px 宋体`;
    ctx.fillStyle = "rgba(0,0,0,0.3)";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(text,0,0)
    return{
        base64:canvas.toDataURL(),
        size:canvasWidth
    }
}

2、然后创建遮罩层div元素,并将此div放在需要添加水印的元素上

/**
 * 创建加载水印
 * @params {*} parentNode:需要添加水印的元素
 */ 
function loadMark(parentNode){
    let {base64,size} = MakeWaterMark("峰少1618");
    const div = document.createElement("div");
    div.style.backgroundImage = `url(${base64})`;
    div.style.backgroundSize = `${size}px,${size}px`;
    div.style.backgroundRepeat = "repeat";
    div.style.position = "absolute"
    div.style.zIndex = '9999';
    div.style.inset = 0;
    div.id = "watermark";
    parentNode.appendChild(div);
}

此时,水印已经创建成功了,但是有时候,我们遇到同行时难免会有打开控制台删除元素的操作,因此,可以使用MutationObserver监听器来将水印元素实时监听起来,查看他的元素在每个时刻发生的变化。

在刚才的loadMark方法中添加如下代码:

// 声明一个监听器
let ob = null;
ob = new MutationObserver((recodrs)=>{
    if(recodrs[0].type == "attributes"){
        alert("当前元素属性发生变化")
    }
    if(recodrs[0].type == "childList"){
        for (const key of recodrs[0].removedNodes) {
            if(key.id == 'watermark'){
                alert("水印被删除")
                //解除监听绑定,此处必须解除绑定,不然会陷入死循环
                ob.disconnect()   
                ob = null;
                loadMark(parentNode)
            }
        }
    }
})
// parentNode要添加水印的父节点,就是loadMark()方法传来的参数
ob.observe(parentNode,{
    childList : true,   //监听元素的内容是否有变化
    attributes : true,  //监听元素的属性有没有变化
    subtree : true      //监听元素的字树有没有变化
})

此时水印才算真正安全了,当有人从控制台删除水印时,MutationObserver监听器监听的元素属性发生的变化时,就会迅速做出反应。

实现效果

 好了,水印这块就分享这些了

如果看到的小伙伴有新的需求,还没什么思路,但是和这里的效果有关系,可以私信我,咱们一起想办法总比一个人想要好很多吧

当然大家有更好的实现水印逻辑,可以提出来,大家一起进步喽!!!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值