Обновить путь SVG из типизированных массивов

Каков наилучший способ построения SVG-путей из типизированных массивов?

Такие массивы кажутся лучшим способом передачи данных из кода, скомпилированного для asm.js, в другие фрагменты JavaScript.

На ум приходят различные возможные подходы. Одним из вариантов будет построение d текст атрибута в исходном коде для приложения asm.js. Но эта строка будет включать в себя много чисел, и реализация emscripten sprintf является слишком общим, чтобы дать хорошую производительность здесь. Поэтому я сомневаюсь, что у этого подхода есть шансы конкурировать.

Таким образом, данные должны передаваться из сгенерированного кода asm.js в рукописный JavaScript не в виде текста, а в виде чисел. Одна возможность заключается в использовании двух типизированных массивов (которые на самом деле являются разными ArrayBuffer). Один содержит типы сегментов, а другой - связанные координаты. Эти данные могут затем использоваться в рукописном коде для вычисления строки для d атрибут или создать список сегментов, используя SVGPathSegList из SVG DOM API.

Я экспериментировал с обеими этими альтернативами здесь: http://jsperf.com/svg-path-from-typed-arrays.

Ни один из подходов не кажется особенно быстрым. (Правка: кажется, что я принял разделитель thoussand за десятичный разделитель. Если это правильно, и у меня было почти десять тысяч операций в секунду вместо только десяти, то это вполне приемлемо)

Так что все же мне интересно, есть ли какая-то альтернатива, которую я пропустил? Есть ли способ сделать эту операцию еще быстрее? Не стесняйтесь редактировать мой jsperf, если вы хотите попробовать новые альтернативы.

1 ответ

Вот мое текущее лучшее решение. Я не буду возражать, если кто-то придумает более умный. Номер кода, связанный с каждым типом линии, совпадает с номером из SVGPathSeg.pathSegType, Так что "близко" 1 "Абсолютный ход" 2 и так далее.

var letters = [" ? ", " Z ", " M ", " m ", " L ", " l ",
               " C ", " c ", " Q ", " q ", " A ", " a ",
               " H ", " h ", " V ", " v ", " S ", " s ", " T ", " t "];
var numbers = [  0  ,   0  ,   2  ,   2  ,   2  ,   2  ,
                 6  ,   6  ,   4  ,   4  ,   7  ,   7  ,
                 1  ,   1  ,   1  ,   1  ,   4  ,   4  ,   2  ,   2  ]; 

function buildPathString(elt, types, coordinates) {
  var i, t, c, nc, d = "", ci = 0;
  for (i = 0; i != types.length; ++i) {
    t = types[i];
    nc = numbers[t];
    c = coordinates.subarray(ci, ci + nc);
    d += letters[t] + Array.prototype.join.call(c, " ");
    ci += nc;
  }
  elt.setAttribute("d", d);
}
Другие вопросы по тегам