Raphaël.js создавался в эпоху, когда основной задачей было обеспечить единый API для работы с векторной графикой в разных браузерах, включая устаревшие версии Internet Explorer. В основе библиотеки лежит абстракция, которая скрывает различия между SVG и VML.
Snap.svg изначально разрабатывался как инструмент исключительно для работы с SVG. Это принципиальное отличие определяет всю архитектуру библиотеки:
Snap.svg не пытается быть универсальным слоем совместимости — он опирается на стандарт SVG как на единственную платформу.
В Raphaël элементы являются обёртками над внутренней реализацией. Разработчик взаимодействует с абстрактными объектами, не всегда напрямую связанными с DOM.
В Snap.svg:
Пример различия:
Raphaël:
var paper = Raphael(10, 50, 320, 200);
var circle = paper.circle(50, 40, 10);
Snap.svg:
var s = Snap(320, 200);
var circle = s.circle(50, 40, 10);
На первый взгляд синтаксис похож, но в Snap.svg
circle.node — это реальный <circle> в
DOM, а не абстракция.
Snap.svg предоставляет встроенные инструменты для загрузки и манипуляции внешними SVG-файлами:
Snap.load("image.svg", function(fragment) {
s.append(fragment);
});
В Raphaël подобной функциональности нет. Работа с внешними SVG требует дополнительных инструментов или ручного парсинга.
Ключевые особенности Snap.svg:
<defs>, <symbol>,
<use>Raphaël использует собственную систему анимации, реализованную поверх JavaScript. Она не связана напрямую с возможностями SVG.
Snap.svg опирается на:
Пример:
Raphaël:
circle.animate({ cx: 200 }, 1000);
Snap.svg:
circle.animate({ cx: 200 }, 1000, mina.easeinout);
Snap.svg использует модуль mina для управления кривыми
анимации, что делает поведение более предсказуемым и расширяемым.
Обе библиотеки поддерживают SVG-пути, но Snap.svg предоставляет более мощные инструменты:
var length = Snap.path.getTotalLength(path);
var point = Snap.path.getPointAtLength(path, 50);
В Raphaël такие возможности либо отсутствуют, либо реализованы ограниченно.
Snap.svg более естественно работает с группами
(<g>), так как напрямую взаимодействует с SVG:
var group = s.group(circle, rect);
group.attr({ transform: "translate(50,50)" });
В Raphaël группы реализованы через абстракции (set),
которые:
Snap.svg использует стандартные SVG-трансформации:
translaterotatescalematrixcircle.transform("translate(100,0) rotate(45)");
Raphaël применяет трансформации через собственный синтаксис, что иногда приводит к несоответствиям со стандартом SVG.
Snap.svg полностью поддерживает:
<mask><clipPath>Пример:
var mask = s.circle(50, 50, 40);
rect.attr({ mask: mask });
В Raphaël:
Snap.svg позволяет использовать SVG-фильтры напрямую:
var filter = Snap.filter.blur(5, 5);
circle.attr({ filter: filter });
Raphaël не поддерживает фильтры SVG, так как ориентирован на более старые технологии.
Обе библиотеки поддерживают обработку событий, но подход отличается.
Snap.svg:
circle.click(function() {
console.log("clicked");
});
Raphaël использует собственную систему событий, которая может отличаться от нативного поведения браузера.
Snap.svg предоставляет удобный механизм расширения:
Snap.plugin(function(Snap, Element, Paper, global) {
Element.prototype.highlight = function() {
this.attr({ stroke: "red" });
};
});
Raphaël также поддерживает плагины, но архитектура менее гибкая из-за слоя абстракции.
Snap.svg выигрывает за счёт:
Raphaël:
Snap.svg следует спецификациям SVG:
Raphaël:
Raphaël создавался с учётом:
Snap.svg ориентирован на:
Это делает Snap.svg менее универсальным, но более мощным инструментом в актуальной среде.
Raphaël.js:
Snap.svg:
Разница между библиотеками отражает эволюцию веб-разработки: от борьбы за совместимость к использованию нативных возможностей платформы.