【发布时间】:2018-11-06 08:45:03
【问题描述】:
我有一个用例,我需要在画布元素上呈现大量(约 50,000 个字形)清晰、可扩展的文本字符串。到目前为止,我尝试过的 最佳 解决方案包括对画布元素上绘制的文本进行三角测量(使用 fillText 方法绘制文本),通过 WebGL 将矩阵制服和表示该字符串的三角形 Float32Array 上传到 GPU。使用这种方法,我能够以大约 30fps 的速度渲染 100,000 个字形。字形在非常高的缩放级别下会变得块状,但这对我的用例来说很好。
但是,这种方法每个字符串的开销约为 250 毫秒,因为我首先将字符串绘制到内存中的画布元素,读取像素数据,将位图图像转换为矢量,然后对矢量数据进行三角测量。在网上搜索解决方案时,我发现了两个有趣的开源项目:
- OpenType.js:https://opentype.js.org/
- 耳切:https://github.com/mapbox/earcut
所以现在我想重写我最初的概念证明以使用 OpenType 和 Earcut。 OpenType 用于将曲线数据输入 Earcut,而 Earcut 用于对数据进行三角剖分并返回一个表示每个三角形点的数组。
我的问题是,我不知道如何获取 OpenType 提供的数据并将其转换为 Earcut 接受的格式。任何人都可以为此提供帮助吗?
更多信息:
这个 StackOverflow 问题有一些很好的信息,但缺少一些实现细节:Better Quality Text in WebGL。我想我想要完成的是第一个答案中描述的“作为几何图形的字体”方法。
【问题讨论】:
-
这听起来像XY problem;为什么需要在一个画布上同时渲染这么多字形?
-
感谢您的评论。我的用例是一个项目管理 Web 应用程序,其中每个任务可以在最大缩放级别上有五个不同的字符串,并且用户可以围绕时间表进行平移/缩放。已经存在剔除,因此屏幕外的字形不会像细节级别系统那样呈现,因此在放大时会呈现更多细节。但是,文本以相对较低的缩放级别显示,其中一行任务描述可见。一次可见 1,000 多个任务是很常见的。
-
我认为问题是——你真的需要 WebGL 吗?常规 2d 画布使用相同的硬件加速,并具有更复杂的算法来填充轮廓,而无需将曲线分解为段并进行三角剖分。
-
所以我的第一次尝试是使用两个画布元素。一个带有 WebGL 上下文,一个带有 CanvasRenderingContext2D。所有文本都绘制在 CanvasRenderingContext2D 上,然后覆盖在主 GL 上下文画布上。这在 Chrome 和 iOS Safari 上效果很好,但是在 Firefox 和 Edge 上绘制文本的速度要慢得多,字符串数量很多(使用 5,000 个作为测试用例),这对我们来说最终是不行的。
标签: javascript html5-canvas webgl triangulation opentype