26

已实现部分 SVG 规范(Firefox 等)的浏览器免费为我们进行命中测试 - 如果我在 SVG 对象上附加 mousedown 侦听器,只要单击该形状,我就会收到通知。这太棒了,尤其是对于复杂的多边形形状。

我想知道是否有一种方法可以利用此功能进行更多的命中测试。我想知道给定的矩形是否与我的任何 SVG 形状相交。

例如,我将 3 个复杂的多边形添加到我的元素中。现在我想知道矩形 (40, 40, 100, 100) 是否与它们中的任何一个相交。有没有人知道我如何能够使用已经很好的命中测试支持,而不是自己添加所有这些代码?

谢谢

4

4 回答 4

29

SVG 1.1 DOM 有正确的方法(不幸的是它还没有在 mozilla 中实现):

var nodelist = svgroot.getIntersectionList(hitrect, null);

有关完整的工作示例,请参见此处

于 2010-02-01T17:27:18.143 回答
18

我不知道与整个矩形相交的任何方式。但是你可以与一个点相交,所以你可以建立一个更复杂的检查:

var el= document.elementFromPoint(x, y);

将在特定页面相对坐标处为您提供最高堆叠的元素。<svg>如果 SVG 内没有任何形状被击中,您将获得该元素。

这是一个非标准的Mozilla 扩展,但它也适用于 WebKit。不幸的是,虽然它存在于 Opera 中,但它不会往里面看<svg>,所以在那个浏览器上,该元素将始终是 SVGSVGElement。

于 2010-02-01T15:14:14.457 回答
2

Chrome 版本的 checkIntersection(和 getIntersectionList)测试元素边界框,而不是元素本身。我能够编写自己的 checkIntersection ,它通过使用带有这种相当复杂的方法的画布在 chrome 上工作,这似乎适用于小矩形并且对于大矩形来说会很慢,所以它很适合命中测试。该技术将作为 Chrome 中 checkIntersection 的 polyfill,适用于小矩形和其他可能破坏了 checkIntersection 实现的浏览器。

  1. 创建一个使用包含 SVG 的 outerHTML 的数据 URI 的图像(您可能还需要在其中包含样式规则),就像这样(此图像不必在页面中)。如果需要,您可以使用 onload 事件处理程序来确定何时加载。
  2. 创建一个画布以用于您的命中测试矩形(此画布不需要在页面中)

要测试矩形是否与您的任何形状相交,请执行以下操作:

  1. 确保画布与矩形大小相同(设置其宽度和高度)
  2. 使用画布上下文clearRect()方法清除画布
  3. 在 -x, -y 的画布上绘制 SVG,以便与画布重叠的图像部分对应于您要使用drawImage()测试的区域
  4. 使用上下文的getImageData()获取画布的 ImageData 。数据数组的每个第 4 个元素都是 alpha 字节,非零值意味着 SVG 的一部分与矩形重叠。如果所有第 4 个字节都是 0,那么您的 SVG 没有与矩形相交。
于 2017-05-03T17:44:25.657 回答
0

getIntersectionList 在 Opera 中运行良好。我的问题是 SVG 1.1 Full 规范中关于此的功能要求必须渲染元素(以及指针事件的可能目标)才能被检测为命中。不幸的是,这使得这些函数对于当前只有部分世界可见的游戏世界中的命中测试毫无用处。

于 2011-10-27T19:39:26.727 回答