【问题标题】:SVG text hit-testSVG 文本命中测试
【发布时间】:2011-08-10 16:21:32
【问题描述】:
我正在尝试使用客户端 JavaScript 实现 SVG 文本元素的碰撞检测。命中测试应检查文本的任何字形是否与另一个文本元素的任何字形重叠。由于getBBox 和getExtentOfChar 不准确,我需要一个自定义解决方案。
我的第一种方法是获取元素的每个坐标/像素的颜色并手动进行命中测试,但这不起作用,因为无法获取坐标的颜色。它需要一个额外的画布来获得像素颜色 -> 糟糕的解决方法。
现在我正在考虑将文本或字形转换为多边形以进行命中测试。是否可以?或者还有其他基于字形的命中测试方法吗?
最好的问候
【问题讨论】:
标签:
javascript
html
svg
collision-detection
hittest
【解决方案1】:
您真的进入了一个充满痛苦和跨浏览器问题的世界。我最终对字体进行了自定义路径渲染,只是为了使 total 文本长度可靠且一致。我什至不想考虑字形命中。
例如,一个问题是 firefox(至少 3.6)和 iirc 某些版本的 opera 在缩放时会出现一些舍入误差,因此当您缩放包含文本的父元素并按该比例的倒数缩放文本时,那么与没有任何比例的情况相比,字母间距会略有不同。 (因为每个字母都必须以偶数或类似的数字开头,所以可以通过将高档和低档都乘以 10000 来解决问题,但那是另一回事了)
不幸的是,与文本相比,使用路径对性能的影响非常明显。如果您的画布进行任何形式的动画平移或缩放,您应该在动画期间切换到纯文本元素,一旦静止,打开路径渲染以确保准确性。
幸运地将 svg 字体转换为路径非常容易,它是纯文本并且使用与路径元素完全相同的格式。 (但要注意字体嵌入许可证!还要记住文件大小,因为您不能使用用户系统中的字体,)
【解决方案2】:
至于基于像素的命中测试——如果你切换到 HTML5 Canvas,那么这将成为可能。几个项目提供了从 SVG 到 Canvas 的轻松转换,例如fabric.js。 See a comparison table here.
至于基于多边形的方法——可能,但很困难。您可以使用某些工具(例如 Inkscape 的 text-to-path)将文本或字形转换为多边形(路径)。然后会有计算。为任何文本制定通用解决方案都需要大量工作。但是,如果文本没有改变,那么使用路径手动绘制文本可能是一种快速而肮脏的解决方案。