Иногда бывает нужно вычислить трансформацию над svg путем (сдвиг, масштаб и т.п.). Или слегка ужать его размер — заменить все команды на «относительные», урезать дробную часть координат и выкинуть лишние пробелы. Как ни странно, готовых библиотек для таких простых операций не было.
Самое ближайшее по смыслу можно найти в рафаэле и SVGO. Но в первом все переводится в безье третьего порядка (нормально для отображения, но плохо для сохранения результата), а второй работает на более высоком уровне, и будет для простых вещей неудобным и медленным.
В итоге, после выделения наработок в отдельный пакет, получился svgpath с простым и понятным интерфейсом:
var svgpath = require('svggpath'); var result = svgpath(path) .scale(1, -1) .translate(50, 100) .abs().round(0).rel() .toString();
Обратите внимание на конструкцию .abs().round(0).rel()
— округлять можно только абсолютные значения, иначе погрешность станет копиться и полезут артефакты. Поэтому относительные команды сначала переводятся в абсолютные, а после огругления все конвертируется обратно, для уменьшения размера.
В общем, получилось компактно и довольно быстро. Для тех, кому понадобятся другие преобразования — есть итератор на подобии forEach, который передает в итерирующую функцию команды сегментов и координаты их начальных точек.
Код работает под нодой, но в то же время легко браузерифицируется (на fontello все крутится в браузере, проверено). Пока реализованы те преобразования, которые были востребованы. В перспективе наверное имеет смысл добавить парсинг и наложение команд transform, а также вычисление bounding box. Сейчас библиотека активно используется в конверторе шрифтов svg2ttf и при обработке картинок на fontello.
Исходный код, лицензия MIT.
Автор: Vitaly