【问题标题】:How to punch holes through overlaying div by applying canvas as a mask with CSS如何通过使用 CSS 将画布作为蒙版在覆盖 div 上打孔
【发布时间】:2021-12-12 00:30:48
【问题描述】:

我画了一个画布,内容如下:

如何正确地将画布设置为 CSS 中整个 div 的剪贴蒙版?

这是我的代码:

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)
    }
}
window.onload = draw;
.aside, .content, canvas{
  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;
  height: 100vh;
  width: 100vw;
  display: block;
  mask: url(#splash-canvas);
}
canvas{
  z-index:5;
}
.hidden{
  overflow:hidden;
  width:0;
}
<div class="hidden"><canvas id="splash-canvas"  width="150" height="150"></canvas></div>
<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>

可以看出,画布被应用为蒙版,但它也显示自己并将内容隐藏在它蒙版的图层中。不知道我做错了什么。我期望发生的是黑色区域应该替换为.aside 层(绿色文本)的内容,并且.content 层(红色文本)的内容应该通过孔可见(这个已经发生了)。我尝试将画布存储在隐藏的 div 中(溢出:隐藏),但没有骰子。我还尝试将画布隐藏在屏幕上其他所有内容的后面,但它仍然显示在顶部。

【问题讨论】:

  • 可以看出画布被应用为蒙版 --> 它没有被应用为蒙版。您在哪里读到可以将画布用作蒙版?这是不可行的
  • 我以前从未使用过画布,但是,在我的示例中有 3 层:1. 红色文本,2. 绿色文本,3. 画布(蒙版)。面具上有一个洞。我可以通过它清楚地看到第 1 层,但是我看不到中间层,因此我断定蒙版已应用于第 2 层。否则我应该看到绿色文本重叠在红色文本上。 CSS 掩码使用 alpha 信息来决定什么是可见的,什么是不可见的,并且在这种情况下,画布显然具有 alpha 信息。
  • 去掉 mask 属性,你会看到同样的结果(mask 在这里什么都不做)。溢出:隐藏什么都不做,因为画布是位置:绝对。删除 position:absolute 或添加 position:relative 到其父元素
  • 关于溢出隐藏问题你是对的。然而,这是一个禁用与启用掩码的屏幕截图:imgur.com/a/OZqh0J0 肯定发生了一些事情,但不是我所期望的。
  • 我测试过,你是对的。我认为你所有的 cmets 都可以编译成这个问题的一个很好的答案。如果您愿意这样做,我会将其标记为解决方案。知道没有解决方案就像知道正确的现有解决方案一样好。

标签: javascript css canvas


【解决方案1】:

您实际上并不需要那么多代码或画布。使用渐变的背景着色可以实现您想要的效果。

.content{
  font-weight:bold;
  font-size:30px;
  color:#0000;
  background:                                   /* position */
   radial-gradient(farthest-side,red 98%,#0000) 20px  20px,
   radial-gradient(farthest-side,red 98%,#0000) 160px 100px,
   green;
  background-size:200px 200px; /* size of the circles */
  background-repeat:no-repeat;
  -webkit-background-clip:text;
          background-clip:text;
}
&lt;div class="content"&gt;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.&lt;/div&gt;

【讨论】:

  • 对不起,我的 sn-p 只是为了证明这个概念。我想要实现的是溶解上层,以便可以看到后面的层。这就是我想要重现的内容:imgur.com/swm6ifG,所以基本上我想使用画布来为面具制作动画。我不能接受这个答案,因为它没有回答问题。
猜你喜欢
  • 2015-01-03
  • 1970-01-01
  • 2020-03-01
  • 2018-08-20
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多