SVG.js предоставляет мощный API для работы с векторной графикой, но его возможности можно значительно расширить за счёт создания собственных плагинов. Расширения позволяют добавлять новые методы к объектам SVG.js, работать с кастомными атрибутами и интегрировать специализированные функции для сложной графики.
Плагин в SVG.js представляет собой функцию, которая принимает объект библиотеки в качестве аргумента. Стандартная структура выглядит следующим образом:
SVG.extend(SVG.Element, {
myCustomMethod: function() {
// Логика метода
return this; // Возврат this для цепочек вызовов
}
});
this для поддержания цепочек
вызовов, характерных для SVG.js.Методы можно добавлять не ко всем элементам, а только к определённым
классам, например SVG.Circle или SVG.Rect:
SVG.extend(SVG.Circle, {
pulse: function(duration = 1000, scale = 1.5) {
this.animate(duration).scale(scale).animate(duration).scale(1);
return this;
}
});
В этом примере создаётся метод pulse, который заставляет
круг пульсировать с заданной продолжительностью и масштабом. Такой
подход позволяет создавать специализированные анимации и интерактивные
эффекты без изменения базового API.
SVG.js поддерживает возможность создания собственных атрибутов через
метод attr. Для удобства можно обернуть логику в
плагин:
SVG.extend(SVG.Element, {
setShadow: function(color = '#000', blur = 5, dx = 2, dy = 2) {
const shadowId = `shadow-${Math.random().toString(36).substr(2, 9)}`;
if (!this.node.ownerSVGElement.querySelector(`#${shadowId}`)) {
const filter = this.node.ownerSVGElement.defs().element('filter').id(shadowId);
filter.element('feDropShadow', {
dx: dx,
dy: dy,
stdDeviation: blur,
floodColor: color
});
this.attr('filter', `url(#${shadowId})`);
}
return this;
}
});
Метод setShadow добавляет фильтр тени к любому элементу,
используя встроенные SVG-фильтры. Такой подход демонстрирует гибкость
SVG.js в работе с атрибутами и эффектами.
Плагины позволяют объединять последовательные анимации в удобные методы. Например, метод для плавного появления и движения:
SVG.extend(SVG.Rect, {
flyIn: function(x, y, duration = 1000) {
this.opacity(0).move(x - 50, y).animate(duration).move(x, y).opacity(1);
return this;
}
});
Теперь любой прямоугольник может «влетать» на сцену с заданными координатами. С помощью таких расширений можно создавать библиотеку пользовательских эффектов для повторного использования.
SVG.js поддерживает группы (SVG.G), к которым тоже можно
добавлять методы:
SVG.extend(SVG.G, {
staggerFade: function(delay = 100) {
this.each(function(i, children) {
this.animate(500).delay(i * delay).opacity(1);
});
return this;
}
});
Метод staggerFade позволяет последовательно появляться
элементам внутри группы с заданной задержкой. Это особенно удобно для
визуализации данных и анимации сложных сцен.
Для разделения кода и повторного использования расширений стоит оформлять их в виде отдельных модулей:
// myPlugin.js
export default function(MySVG) {
MySVG.extend(MySVG.Circle, {
bounce: function() {
this.animate(500, '<>').move(this.x(), this.y() - 20).animate(500, '<>').move(this.x(), this.y());
return this;
}
});
}
Использование:
import SVG from '@svgdotjs/svg.js';
import myPlugin from './myPlugin.js';
const draw = SVG().addTo('#canvas').size(400, 400);
myPlugin(SVG);
const circle = draw.circle(50).fill('#f06').center(200, 200);
circle.bounce();
Такой подход обеспечивает модульность, позволяет поддерживать чистую архитектуру и упрощает тестирование пользовательских расширений.
defs.Расширения позволяют создавать высокоуровневые функции для сложной графики, упрощая работу с SVG и превращая библиотеку SVG.js в полноценный инструмент для динамических визуализаций и интерактивных интерфейсов.