【问题标题】:how to create SVG Elements (polylines) faster如何更快地创建 SVG 元素(折线)
【发布时间】:2021-04-25 22:07:32
【问题描述】:

我将图像渲染为 SVG 元素,其中每个像素都是折线六边形。

每个折线元素包含 12 个值(参见下面的坐标示例)

拥有 50.000 - 100.000 个折线元素会使事情变慢。

function appendPixelsToSVG(svgElement, coordinates) {
  const xmlns = 'http://www.w3.org/2000/svg';
  for (let i = 0; i < coordinates.length; ++i) {
    const new_path = document.createElementNS(xmlns, 'polyline');
    new_path.setAttributeNS(null, 'points', coordinates[i]);
    new_path.setAttributeNS(null, 'opacity', 1.0);
    new_path.setAttributeNS(null, 'fill', '#000000');
    svgElement.appendChild(new_path);
  }
}

坐标数据格式示例:

0: " -18.530797027515483, 67.75  -17.37609648913623, 67.75  -16.798746219946604, 68.75  -17.37609648913623, 69.75  -18.530797027515483, 69.75  -19.10814729670511, 68.75 "
1: " -9.870542989671096, 67.75  -8.715842451291843, 67.75  -8.138492182102217, 68.75  -8.715842451291843, 69.75  -9.870542989671096, 69.75  -10.447893258860722, 68.75 "
2: " -1.2102889518267106, 67.75  -0.05558841344745824, 67.75  0.5217618557421679, 68.75  -0.05558841344745824, 69.75  -1.2102889518267106, 69.75  -1.7876392210163368, 68.75 "
3: " 7.449965086017679, 67.75  8.604665624396931, 67.75  9.182015893586557, 68.75  8.604665624396931, 69.75  7.449965086017679, 69.75  6.872614816828053, 68.75 "
4: " 16.110219123862066, 67.75  17.26491966224132, 67.75  17.842269931430945, 68.75  17.26491966224132, 69.75  16.110219123862066, 69.75  15.53286885467244, 68.75 "
5: " 24.770473161706448, 67.75  25.9251737000857, 67.75  26.502523969275327, 68.75  25.9251737000857, 

我的想法是将所有坐标放入同一个折线元素中,但这搞砸了我的形象,因为折线元素显然不知道哪些坐标属于一起,哪些不属于。

如前所述:总是有 12 个元素属于一起

那么有没有什么诀窍可以让它发挥作用?只创建一个折线元素实际上非常快。

【问题讨论】:

  • 也许是 Canvas 的工作?
  • 使用单个&lt;path /&gt;d="M" + coordinates.join("zM") + "z"
  • @Thomas 这正是我想要的。你能把这个写下来作为一个实际的答案,这样我就可以把它标记为已解决?谢谢!
  • 我可以看到两种策略,具体取决于最终目的:如果您需要序列化的 XML,请考虑在不渲染的情况下构建它。如果仅用于渲染,您应该调查在设置属性之前使用Number.toFixed() 对数字进行四舍五入是否可以提高性能。而且您绝对应该忽略opacity="1.0"fill="#000000"(无论如何它们都是默认值),或者至少将它们移动到父元素或样式表以避免重复解析。
  • 精度可能很重要,但我无法想象任何能够表示 16 位有效数字的介质。考虑到抗锯齿,任何小于媒体能够复制的最小点以下最多两位小数的东西都没有任何区别,而从字符串中解析数字仍然需要时间。

标签: javascript performance svg dom


【解决方案1】:

使用路径代替折线有效:

new_path.setAttributeNS(null, 'd', `M${coordinates.join('zM')}z`);

【讨论】:

    猜你喜欢
    • 2019-05-24
    • 2019-02-22
    • 2018-01-29
    • 1970-01-01
    • 2019-04-11
    • 2012-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    相关资源
    最近更新 更多