首页 > 解决方案 > 仅通过 svg 掩码中的孔单击:具有相交孔的情况

问题描述

我有确定矩形孔的 svg 掩码。在 svg mask 后面我有一些可点击的元素,我想将事件传递给它们,但只能通过孔。

我已经在这里问过这个问题并得到了答案,这对我来说非常有效,直到我遇到一个带有相交矩形的案例 点击仅通过 svg 掩码中的孔

是否有任何简单的解决方案可以将矩形周围的区域剪掉而不是交叉路口的区域?拥有类似的东西会是完美的globalCompositeOperation='destination-out',我已经开始考虑如何使用画布而不是 svg 来解决我的问题,但是据我所知,我用于 svg 的指针事件尚未设计为与画布正确工作.

button, svg {
  position:absolute;
  width:400px;
  height:400px
}
button {
  background: #0000ff;
  cursor: pointer; 
}
button:hover {
  background: #008800; 
}
svg {
  pointer-events: none;
}
.over {
  fill: #000;
  clip-path: url(#clip);
  pointer-events: painted;
}
<button></button>
<svg xmlns="http://www.w3.org/2000/svg" height="400" width="400">
 <defs>
   <clipPath id="clip" clip-rule="evenodd">
 <path d="M 20 20 h 360 v 360 h -360 z
          M 90 100 v 240 h 140 v -240 z
          M 200 290 v 80 h 80 v -80 z" />
   </clipPath>
 </defs>
 <rect y="0" x="0" height="400" width="400" class="over" />
</svg>

标签: javascriptcsssvghtml5-canvaspointer-events

解决方案


在我看来,这是一个方便的问题。您希望能够使用单独的路径并以相同的方式对待它们,无论它们是否交互。不幸的是,由于系统的一些限制,我认为不可能实现这种便利。但是,您的问题本身很容易回答。

首先,关于您的示例中发生的事情。您clipPath有一个按顺时针方向(右、下、左、上)绘制的大“外部”路径。然后你有两条逆时针绘制的“内部”路径(下、右、上、左)。剪辑根据考虑的内容insideoutside路径工作。问题是考虑了交叉点outside(见链接)。

直接的解决方案是为每个形状使用单个路径,即使它不是简单的矩形:

button, svg {
  position:absolute;
  width:400px;
  height:400px
}
button {
  background: #0000ff;
  cursor: pointer; 
}
button:hover {
  background: #008800; 
}
svg {
  pointer-events: none;
}
.over {
  fill: #000;
  clip-path: url(#clip);
  pointer-events: painted;
}
<button></button>
<svg xmlns="http://www.w3.org/2000/svg" height="400" width="400">
 <defs>
   <clipPath id="clip" clip-rule="evenodd">
 <path d="M 20 20 h 360 v 360 h -360 z
          M 90 100 v 240 h 110 v 30 h 80 v -80 h -50 v -190 z" />
   </clipPath>
 </defs>
 <rect y="0" x="0" height="400" width="400" class="over" />
</svg>


推荐阅读