命中测试SVG形状?

时间:2010-02-01 04:23:01

标签: javascript svg hittest

已经实现了SVG规范(Firefox等)部分的浏览器免费为我们进行了测试 - 如果我在SVG对象上附加了一个mousedown监听器,我会在点击形状时收到通知。这太棒了,特别是对于复杂的多边形形状。

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

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

由于

4 个答案:

答案 0 :(得分:26)

SVG 1.1 DOM有正确的方法(遗憾的是它尚未在mozilla中实现):

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

有关完整的工作示例,请参阅here

答案 1 :(得分:15)

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

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

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

这是一个非标准Mozilla extension,但它也适用于WebKit。不幸的是,虽然它存在于Opera中,但它不会查看<svg>内部,因此在该浏览器中元素将始终为SVGSVGElement。

答案 2 :(得分:1)

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

  1. 使用包含SVG的outerHTML的数据URI创建一个图像(您可能还需要在其中包含样式规则),例如so(此图片不必是在页面中)。如果需要,可以使用onload事件处理程序来确定何时加载它。
  2. 创建一个用于命中测试矩形的画布(此画布不需要在页面中)
  3. 要测试矩形是否与任何形状相交,请执行以下操作:

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

答案 3 :(得分:0)

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