SVG 文本命中测试

发布于 2024-11-29 07:12:42 字数 315 浏览 2 评论 0原文

我正在尝试使用客户端 JavaScript 实现 SVG 文本元素的碰撞检测。命中测试应检查文本的任何字形是否与另一个文本元素的任何字形重叠。由于 getBBoxgetExtentOfChar 并不准确,因此我需要一个自定义解决方案。

我的第一种方法是获取元素的每个坐标/像素的颜色并手动进行命中测试,但这不起作用,因为不可能获取坐标的颜色。需要额外的画布来获取像素颜色 ->糟糕的解决方法。

现在我正在考虑将文本或字形转换为多边形以进行命中测试。是否可以?或者还有其他基于字形的命中测试的方法吗?

此致

I'm trying to implement collision detection for SVG text elements using client side JavaScript. The hit-test should check if any glyph of a text overlaps any glyph of another text element. Since getBBox and getExtentOfChar are anything than accurate I need a custom solution.

My first approach was to get the colour of each coordinate/pixel of an element and do the hit-testing manually, but this does not work because it isn't possible to get the colour of a coordinate. It would require an additional canvas to get pixel colours -> awful workaround.

Now I'm thinking about converting the text or the glyphs to polygons for hit testing. Is it possible? Or has anyone another approach for glyph based hit testing?

Best Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

她如夕阳 2024-12-06 07:12:42

您确实进入了一个充满痛苦和跨浏览器问题的世界。我最终对字体进行了自定义路径渲染,只是为了使文本长度可靠且一致。我什至不想考虑字形命中。

例如,一个问题是 firefox(至少 3.6)和 iirc 以及某些版本的 opera 在缩放时存在一些舍入误差,因此当您缩放包含文本的父元素并按该比例的倒数缩放文本时,字母- 与没有任何比例相比,间距会略有不同。 (因为每个字母必须以偶数或类似的数字开头,所以可以通过将高档和低档乘以 10000 来解决问题,但这是另一个故事)

不幸的是,与文本相比,使用路径对性能的影响非常明显。如果您的画布进行任何形式的动画平移或缩放,您应该在动画期间切换到纯文本元素,并在静态后打开路径渲染以确保准确性。

幸运的是,将 svg-fonts 转换为路径非常容易,它是纯文本,并且使用与路径元素完全相同的格式。 (但要注意字体嵌入许可证!还要记住文件大小,因为您无法使用用户系统中的字体,)

You are really entering a world of pain and cross browser problems. I ended up doing custom path-rendering of fonts only to get the total text length reliable and consistent. I don't even want to think about glyph-hitting.

One problem for example is that firefox (at least 3.6) and iirc also some version of opera has some rounding error when scaling so when you scale the parent-element holding the text and scale the text by the inverse of that scale, then the letter-spacing will be slightly different compared to without any scale. (Because each letter must begin on an even number or something like that, problem can be solved by multiplying both the upscale and downscale with like 10000 but that's another story)

The performance impact by using path compared to text is unfortunately quite noticeable. If your canvas does any form of animated panning or zooming you should switch to pure text-elements during the animation and once static, turn on path rendering for accuracy.

Fortunally converting svg-fonts to paths is very easy, it is plaintext and using the exact same format as the path-element. (beware of font-embedding-licenses though! Also keep file size in mind as you cannot use the fonts from the users system, )

你怎么这么可爱啊 2024-12-06 07:12:42

至于基于像素的命中测试 - 如果您切换到 HTML5 Canvas,那么这将成为可能。有几个项目提供了从 SVG 到 Canvas 的轻松转换,例如 fabric.js在此处查看比较表

至于基于多边形的方法——可能,但很困难。您可以使用某些工具(例如 Inkscape 的文本到路径)将文本或字形转换为多边形(路径)。然后就会有计算。为任何文本制定通用解决方案都需要大量工作。但是,如果文本没有改变,那么使用路径手动绘制文本可能是一个快速但肮脏的解决方案。

As for the pixel-based hit-testing – if you switch to HTML5 Canvas, then this will become possible. Several projects provide easy transition from SVG to Canvas, e.g. fabric.js. See a comparison table here.

As for the polygon-based approach – possible, but difficult. You can convert text or glyphs to polygons (paths) using some tool (Inkscape's text-to-path for instance). And then there'll be calculations. Making a general solution for any text will require a lot of work. However, if the text doesn't change, then drawing your text manually using paths can be a quick and dirty solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文