You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用CSS将canvas设为遮罩在叠加div上实现镂空打孔效果

问题原因

  • 你的CSS给canvas单独设置了position: absolute、z-index:5,优先级远高于其他层,直接导致canvas本身显示在最上层遮挡内容:而且绝对定位元素脱离父级文档流,父级.hidden的overflow: hidden对它完全无效,所以你藏不住它。
  • CSS mask: url(#xxx)的语法是用来引用SVG内部的mask元素ID,不能直接绑定canvas元素作为遮罩源,你的用法不符合规范。

修复方案

  1. 调整CSS规则,移除canvas的绝对定位、高层级配置,直接隐藏canvas(它只用来生成遮罩源,不需要显示)
  2. 在canvas绘制完成后,将其导出为图片地址,动态赋值给.aside的mask属性即可。

修改后的完整代码

CSS

.aside, .content{
  left:0;
  top:0;
  position:absolute;
  height: 100vh;
  width: 100vw;
  display: block;
}
.content{
  z-index:2;
  font-weight:bold;
  color:red;
  background:yellow;
}
.aside{
  color:green;
  z-index:3;
  /* 兼容webkit内核浏览器 */
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
/* 直接隐藏canvas,不需要多余的hidden父容器也可以 */
#splash-canvas{
  display: none;
}

JS

var punchHole = function(x, y, r, ctx){
    ctx.save()
    ctx.arc(x, y, r, 0, Math.PI * 2, false)
    ctx.clip()
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
    ctx.restore();
}

function draw() {
    var ctx = document.getElementById('splash-canvas').getContext('2d');
    var circles = [{x: 50, y: 50, r: 50}, {x: 75, y: 75, r: 50}];
    ctx.fillStyle = 'black';
    ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    for (var i=0; i<circles.length; i++){
        punchHole(circles[i].x, circles[i].y, circles[i].r, ctx)
    }
    // 新增:将canvas转为图片地址,设置为aside的遮罩
    const canvas = document.getElementById('splash-canvas');
    const aside = document.querySelector('.aside');
    const maskUrl = `url(${canvas.toDataURL()})`;
    aside.style.webkitMaskImage = maskUrl;
    aside.style.maskImage = maskUrl;
}
window.onload = draw;

HTML

<canvas id="splash-canvas" width="150" height="150"></canvas>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div class="aside">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>

效果说明

修改后canvas不会再显示,.aside层会以canvas绘制的图形作为遮罩:不透明的黑色区域显示.aside的绿色文字,透明的孔洞区域透出下层.content的红色文字,完全符合预期效果。

内容的提问来源于stack exchange,提问作者brett

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 18:54:03