javascript - 仅通过 svg 蒙版中的孔单击
问题描述
我有确定矩形孔的 svg 掩码。在 svg mask 后面我有一些可点击的元素,我想将事件传递给它们,但只能通过孔。我已经尝试过pointer-events
值,但我只能制作整个掩码来传递事件或整个掩码来捕获它们。对于一个孔,可以使用剪辑路径简单地完成,只需确定孔的外部部分,但是几个孔会使事情变得更加困难。有没有可能避免使用剪辑路径?我也试过pointer-events: visiblePainted
and pointer-events: painted
,但没有成功。
.background {
width: 400px;
height: 400px;
background: red;
cursor: pointer;
}
.svg {
position: absolute;
top: 0;
left: 0;
pointer-events: none;
}
<button class="background">
</button>
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg" class="svg">
<defs>
<mask id="mask">
<rect
x="0"
y="0"
width="400"
height="400"
fill="white"
/>
<rect
x="20"
y="20"
width="40"
height="40"
fill="black"
/>
<rect
x="290"
y="290"
width="40"
height="40"
fill="black"
/>
</mask>
</defs>
<rect
x="0"
y="0"
width="400"
height="400"
fill="black"
opacity="0.5"
mask="url(#mask)"
pointer-events="auto"
/>
</svg>
解决方案
这个问题有几个方面。首先,您是对的,蒙版和剪辑路径的行为与命中测试不同。
剪辑路径是一个几何边界,给定点显然在该边界之内或之外;因此,指针事件必须在裁剪元素的渲染区域上正常捕获,但不能在裁剪区域上捕获......相比之下,掩码不是二进制转换,而是像素操作,并且完全不同的行为透明和几乎但不完全透明可能会令人困惑地任意;因此,对于应用了掩码的元素,即使在掩码变为零不透明度的区域中,仍必须捕获指针事件。
其次,剪辑路径是一种几何形状,但就像所有路径一样,它可能包含孔。<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>
推荐阅读
- python - 在python中组合嵌套列表而不影响键值方向
- javascript - SecurityError: Blocked a frame with origin from access a cross-origin frame IN FIRST ACCESS
- amazon-web-services - 在 MacOS 上安装 aws2 cli 后出现 AWS2 SSO 配置错误
- python - 为什么我的列表理解函数比字符串连接的列表附加函数慢?
- python - 如何将多个 csv 文件合并为一个文件,其中包含 pandas、python 上的特定列?
- c++ - 带有 zip_source_buffer 的 libzip 会导致数据损坏和/或段错误
- c# - 有没有办法可以从脚本中更改另一个对象的材质?
- html - 当元素也悬停时不显示顺风活动样式
- python - 返回经度/纬度坐标集之间的最小距离
- go - 验证 POST JSON 正文匹配结构