Библиотека SVG.js предоставляет мощный и гибкий
механизм для работы с векторной графикой в браузере, основываясь на
объектной модели SVG. Одной из ключевых возможностей является
расширение прототипов элементов, что позволяет
создавать собственные методы для стандартных объектов SVG, таких как
Rect, Circle, Line,
Path и других.
В SVG.js каждый графический элемент представлен объектом с прототипом, который содержит методы для управления атрибутами, трансформациями и событиями. Для добавления нового метода необходимо обратиться к прототипу конкретного типа элемента:
SVG.Rect.prototype.addShadow = function(offsetX, offsetY, blur, color) {
this.style('filter', `drop-shadow(${offsetX}px ${offsetY}px ${blur}px ${color})`);
return this; // возврат для цепочек методов
};
В этом примере создаётся метод addShadow для
прямоугольников. Он добавляет эффект тени через CSS-свойство
filter. Возврат this позволяет использовать
метод в цепочках вызовов:
let rect = draw.rect(100, 50).fill('#f06').addShadow(5, 5, 10, 'rgba(0,0,0,0.5)');
Element как общий базовыйВсе элементы SVG наследуются от базового прототипа
SVG.Element. Расширяя его, можно создавать методы,
доступные для всех типов элементов:
SVG.Element.prototype.fadeOut = function(duration = 1000) {
this.animate(duration).opacity(0);
return this;
};
Теперь fadeOut можно применять к любому объекту, будь то
круг, прямоугольник или текст:
draw.circle(80).fill('#0f9').fadeOut(1500);
draw.text('Привет!').font({size: 24}).fadeOut();
SVG.js поддерживает метод цепочек, что делает код
компактным и читаемым. При создании методов для прототипов важно всегда
возвращать this, чтобы не ломать цепочку:
SVG.Circle.prototype.grow = function(factor) {
let currentRadius = this.radius();
this.radius(currentRadius * factor);
return this;
};
draw.circle(50).fill('#09f').grow(1.5).move(100, 100);
Группы (SVG.Group) часто используют для объединения
нескольких объектов. Прототип группы можно расширять аналогично:
SVG.G.prototype.rotateAll = function(angle) {
this.each(function() {
this.rotate(angle, this.cx(), this.cy());
});
return this;
};
let group = draw.group();
group.circle(40).fill('#f90').move(50, 50);
group.rect(60, 30).fill('#09f').move(20, 20);
group.rotateAll(45);
Метод each перебирает все дочерние элементы группы,
применяя к ним заданную трансформацию.
Для часто используемых операций удобно создавать методы, расширяющие базовый прототип:
SVG.Element.prototype.centerOn = function(x, y) {
let bbox = this.bbox();
this.move(x - bbox.width / 2, y - bbox.height / 2);
return this;
};
draw.rect(120, 80).fill('#fa0').centerOn(200, 150);
draw.circle(60).fill('#0af').centerOn(200, 150);
Метод bbox() возвращает габариты элемента, что позволяет
корректно центрировать объекты на холсте.
SVG.js поддерживает анимированные методы. Расширяя прототип, можно создавать комбинированные эффекты:
SVG.Rect.prototype.pulse = function(duration = 500, scale = 1.2) {
let originalWidth = this.width();
let originalHeight = this.height();
this.animate(duration, '<>').size(originalWidth * scale, originalHeight * scale)
.animate(duration, '<>').size(originalWidth, originalHeight);
return this;
};
draw.rect(80, 80).fill('#f0f').pulse();
Такой метод автоматически создает “пульсирующую” анимацию с возвратом к исходному размеру.
this в новых методах для поддержки
цепочек вызовов.SVG.Element для методов,
применимых ко всем объектам.SVG.G) для работы с набором
элементов.bbox(),
animate(), move(), radius(),
fill()) для получения и изменения состояния объектов.Расширение прототипов делает SVG.js гибким инструментом для построения динамических интерфейсов, интерактивной графики и визуализации данных, позволяя создавать собственные высокоуровневые методы, которые упрощают и ускоряют работу с векторной графикой.