为了账号安全,请及时绑定邮箱和手机立即绑定

仅通过 svg 蒙版中的孔单击

仅通过 svg 蒙版中的孔单击

慕哥6287543 2022-11-27 16:14:59
我有 svg 掩码,它确定矩形中的孔。在 svg mask 后面我有一些可点击的元素,我想将事件传递给它们,但只能通过孔。我已经尝试过pointer-events值,但我只能制作整个面具来传递事件或制作整个面具来捕获它们。对于一个孔,可以简单地使用 clip-path 来完成,只需确定孔的外部,但是多个孔会使事情变得更加困难。有没有可能避免使用剪辑路径?我也试过pointer-events: visiblePainted和pointer-events: painted,但没有成功。
查看完整描述

2 回答

?
湖上湖

TA贡献2003条经验 获得超2个赞

这个问题有几个方面。首先,你是对的,掩码和剪辑路径的行为与命中测试不同

裁剪路径是一个几何边界,给定的点显然在该边界之内或之外;因此,指针事件必须在裁剪元素的渲染区域上正常捕获,但不能在裁剪区域上捕获...相比之下,掩码不是二进制转换,而是像素操作,并且完全不同的行为透明和几乎但不完全透明可能是令人困惑的任意;因此,对于应用了遮罩的元素,即使在遮罩不透明度变为零的区域,也必须捕获指针事件。

其次,剪辑路径是一种几何形状,但就像所有路径一样,它可能包含孔洞。<rect>您可以使用一个具有三个子路径而不是三个<path>,只要clip-rule确保内部的子路径从周围的形状中切出即可。

第三,如果该pointer-events属性应用于<svg>HTML 上下文中的元素,其行为会变得……奇怪。pointer-events: none元素上的任何其他值<svg>都会导致整个边界框接收事件 -为 HTML 元素提出的一种行为,但目前不属于任何规范的一部分。

这里的解决方案是pointer-events: none<svg>元素上设置,然后pointer-events: painted在子<rect>元素上反转它。

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 40 40 v 40 h 40 v -40 z

          M 200 290 v 40 h 40 v -40 z" />

   </clipPath>

 </defs>

 <rect y="0" x="0" height="400" width="400" class="over" />

</svg>


查看完整回答
反对 回复 2022-11-27
?
慕尼黑8549860

TA贡献1818条经验 获得超11个赞

剪贴蒙版对于从复杂的对象中裁剪出部分很有用,但如果您只是使用纯色块,那么创建已经有孔的形状可能同样容易。


我在下面添加了一个示例。这有帮助吗?


<svg width="400" heoght="200" viewBox="0 0 400 200">

  <text x="100" y="100" text-anchor="middle"

    alignment-baseline="middle" onclick="alert('Hello!')"

    style="cursor:pointer">Click me</text>

  <text x="300" y="100" text-anchor="middle"

    alignment-baseline="middle" onclick="alert('Hello?')"

    style="cursor:pointer">Not me</text>

  <path d="M20 20 180 20 180 180 20 180ZM60 60 60 140 140

    140 140 60Z" fill="#3a6" fill-opacity="0.7"

     fill-rule="nonzero"/>

  <path d="M220 20 380 20 380 180 220 180Z" fill="#f20"

    fill-opacity="0.7"/>

</svg>


查看完整回答
反对 回复 2022-11-27
  • 2 回答
  • 0 关注
  • 184 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号