现象

某条超长层位线(20000+ 道)在雷达图上只显示了一部分,甚至整段空白;而短一点的层位线正常。

原因

原来的渲染是把整段层位线一次性画到一个 Canvas 上,Canvas 的宽度等于段的道数。一条 20000 道的层位线,Canvas 宽度就是 20000 像素起步(缩放后更高)。

而 GPU 纹理有尺寸上限,通常 16384 ~ 32768 像素(因显卡而异)。Canvas 宽度一旦超过这个上限,渲染直接失败——而且是静默失败,表现为空白或只画了一截,没有任何报错,排查起来很费劲。

方案:视口裁剪

思路是只画当前能看见的那部分,而不是整段都画。Canvas 宽度始终约等于视口宽度(屏幕上可见的范围),内容随滚动 / 缩放重绘:

  • 根据当前滚动位置和缩放,算出视口覆盖的道号区间 [from, to]
  • 只把这个区间内的层位线点画到 Canvas 上。
  • Canvas 宽度固定为视口宽度,永远不会超过 GPU 纹理上限。
  • 用户滚动或缩放时,重新计算区间并重绘。

附带的优化

视口裁剪还顺带解决了性能问题:以前不管看哪都在画 20000 个点,现在只画视口里的几百个点。再加一个缓存——已解析的深度数组缓存起来,避免每次重绘都重新 split 字符串,滚动时的开销又降一截。

小结

超大尺寸内容渲染,“按视口裁剪”几乎是唯一正解:既绕开 GPU 纹理上限,又天然限制了单帧绘制量。这也是各种地图、图表、编辑器处理“无限画布”的通用思路。