Snap.svg предоставляет мощный и гибкий API для работы с векторной графикой в браузере, включая возможность расширения функциональности через плагины. Плагины позволяют добавлять новые методы к объектам Snap или расширять глобальные возможности библиотеки.
Плагин в Snap.svg реализуется как функция, принимающая объект
Snap в качестве аргумента:
(function(Snap, Element, Paper, glob) {
// Здесь определяется функциональность плагина
})(Snap, Snap.Element, Snap.Paper, this);
circle, rect, path и др.).Paper,
внутри которого размещаются элементы SVG.window), используется для объявления глобальных функций,
если это необходимо.Такой подход обеспечивает изоляцию пространства имён и предотвращает конфликты с другими скриптами.
Чтобы добавить новый метод к элементу SVG, используется объект
Element:
Snap.plugin(function(Snap, Element, Paper, glob) {
Element.prototype.changeColor = function(color) {
this.attr({ fill: color });
return this; // поддержка цепочек вызовов
};
});
Применение нового метода:
var paper = Snap(400, 400);
var circle = paper.circle(100, 100, 50);
circle.changeColor("#f06");
Ключевой момент: метод добавляется к Element.prototype,
что делает его доступным для всех SVG-элементов.
Подобным образом можно добавлять методы к объекту Paper
для удобного управления группой элементов:
Snap.plugin(function(Snap, Element, Paper, glob) {
Paper.prototype.createRectGrid = function(rows, cols, cellWidth, cellHeight) {
var group = this.group();
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var rect = this.rect(j * cellWidth, i * cellHeight, cellWidth, cellHeight);
group.add(rect);
}
}
return group;
};
});
Использование:
var paper = Snap(500, 500);
var grid = paper.createRectGrid(5, 5, 50, 50);
grid.selectAll("rect").forEach(function(r) { r.attr({ fill: "#ccc" }); });
Если функциональность плагина не связана напрямую с элементами, её
можно объявить в глобальной области видимости через объект
glob:
Snap.plugin(function(Snap, Element, Paper, glob) {
glob.randomColor = function() {
return "#" + Math.floor(Math.random()*16777215).toString(16);
};
});
Теперь можно использовать randomColor в любом месте
кода:
var paper = Snap(300, 300);
var circle = paper.circle(150, 150, 75);
circle.attr({ fill: randomColor() });
this – при расширении
Element или Paper рекомендуется возвращать
объект, чтобы сохранить возможность цепочек вызовов.IIFE), чтобы не загрязнять глобальную
область видимости.Snap.plugin – всегда
регистрировать плагины через встроенный метод, а не напрямую к
прототипу, чтобы Snap.svg мог корректно обрабатывать зависимости.if (this.type === "circle") { ... }.Snap.plugin(function(Snap, Element, Paper, glob) {
// Метод для плавного изменения цвета элемента
Element.prototype.fadeToColor = function(color, duration) {
var el = this;
Snap.animate(0, 1, function(val) {
var startColor = Snap.color(el.attr("fill"));
var endColor = Snap.color(color);
var r = startColor.r + val * (endColor.r - startColor.r);
var g = startColor.g + val * (endColor.g - startColor.g);
var b = startColor.b + val * (endColor.b - startColor.b);
el.attr({ fill: Snap.rgb(r, g, b) });
}, duration || 1000);
return this;
};
// Глобальная утилита для генерации случайного SVG элемента
glob.createRandomShape = function(paper) {
var shapes = ["circle", "rect", "ellipse"];
var shapeType = shapes[Math.floor(Math.random() * shapes.length)];
var x = Math.random() * paper.node.clientWidth;
var y = Math.random() * paper.node.clientHeight;
var size = 20 + Math.random() * 80;
switch(shapeType) {
case "circle": return paper.circle(x, y, size);
case "rect": return paper.rect(x, y, size, size);
case "ellipse": return paper.ellipse(x, y, size, size / 2);
}
};
});
Применение:
var paper = Snap(600, 400);
var shape = createRandomShape(paper);
shape.fadeToColor("#ff0000", 2000);
Такой подход позволяет создавать сложные, переиспользуемые расширения Snap.svg, которые можно интегрировать в проекты любой сложности, сохраняя читаемость и модульность кода.