Обновить путь 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);
}