JS+CSS实现反向遮罩

1 篇文章 0 订阅
1 篇文章 0 订阅

一. 需求

公司项目需要在界面上做多种不规则纹理的镂空效果,cssmask可以实现正向遮罩,直接使用的话只会显示不规则纹理区域内的内容。目前我想要的的效果与之相反——不规则图形区域内不显示,其他区域显示。

二. 思路

于是我就想到了利用canvas,先利用canvas获取不规则纹理的像素数据,再把需要遮罩的dom元素和不规则纹理绘制到同一个canvas,根据事先获取的像数数据对不规则纹理内的不透明像素的变成透明,最后把canvas转换成base64的url,设置mask属性,大功告成。

三.准备

由于要把dom转换为canvas,使用了html2canvas,
网址:html2canvas官网

四.实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        text-align: center;
        background: black;
        border: 2px solid #143182;
        border-radius: 10px;
        width: 250px;
        height: 150px;
        margin: 2px;
      }
    </style>
  </head>
  <body>
    有遮罩的
    <div></div>
    没遮罩的
    <div></div>
    遮罩纹理<br />
    <img src="sheep.png" alt="" />
    <script src="http://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
    <script>
      const img = document.querySelector("img");
      img.onload = function(e) {
        const div = document.querySelector("div");
        addMask(div, img, 20, 0);
      };

      // 添加mask
      function addMask(dom, mask, x = 0, y = 0) {
        html2canvas(dom).then(canvas => {
          const ctx = canvas.getContext("2d");
          // 先用一个新的canvas获取图片的像素数据
          const maskcvs = document.createElement("canvas"),
            maskctx = maskcvs.getContext("2d");
          maskcvs.width = mask.width;
          maskcvs.height = mask.height;
          maskctx.drawImage(mask, 0, 0);
          const maskdata = maskctx.getImageData(0, 0, mask.width, mask.height);

          // 再从画布上获取对应像素区域
          const maskdataOnCVS = ctx.getImageData(x, y, mask.width, mask.height);
          // 根据图片的像素数据把图片的不透明像素转换成透明像素
          for (let i = 0, len = maskdataOnCVS.data.length; i < len; i += 4) {
            if (maskdata.data[i + 3] > 0) {
              maskdataOnCVS.data[i + 3] = 0;
            }
          }
          // 把图片放回画布上
          ctx.putImageData(maskdataOnCVS, x, y);
          dom.style["mask"] = dom.style[
            "-webkit-mask"
          ] = `url(${canvas.toDataURL("image/png")})`;
        });
      }
    </script>
  </body>
</html>

五.效果图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值