Передача данных через события

В библиотеке SVG.js события играют ключевую роль в интерактивности графических элементов. Каждый объект SVG, созданный с помощью библиотеки, наследует возможности DOM для обработки событий, а также добавляет собственные методы для удобного взаимодействия.

Привязка событий

Для привязки событий используется метод .on(event, handler):

const draw = SVG().addTo('body').size(600, 400);
const rect = draw.rect(100, 100).fill('#f06');

rect.on('click', function(event) {
    console.log('Прямоугольник был нажат', event);
});
  • event — тип события (например, 'click', 'mouseover', 'mouseout', 'mousedown', 'mouseup', 'mousemove').
  • handler — функция-обработчик, которая получает объект события в качестве аргумента.

Метод .off(event, handler) снимает привязку конкретного обработчика.

function handleClick(e) {
    console.log('Click!');
}

rect.on('click', handleClick);
rect.off('click', handleClick);

Передача данных через события

SVG.js позволяет передавать дополнительные данные в обработчики через контекст вызова или с помощью замыканий. Пример с замыканием:

const data = { color: '#0f0', size: 50 };

rect.on('click', function(event) {
    this.fill(data.color).size(data.size, data.size);
});

В этом примере объект data доступен внутри обработчика благодаря замыканию, что позволяет изменять свойства элемента при наступлении события.

Другой способ — использование пользовательских событий с методом .fire(event, data):

rect.on('customEvent', function(event) {
    console.log('Получены данные:', event.detail);
});

rect.fire('customEvent', { message: 'Hello, SVG.js!' });
  • event.detail содержит любые переданные данные.
  • Метод .fire позволяет инициировать собственные события, которые могут быть использованы для сложных взаимодействий между элементами.

Делегирование и каскадирование событий

SVG.js поддерживает стандартное поведение DOM: события всплывают от вложенных элементов к родительским. Это позволяет организовать делегирование:

const group = draw.group();
const circle = group.circle(50).fill('#00f');

group.on('click', function(event) {
    console.log('Группа была нажата');
});

circle.fire('click');

Здесь событие, инициированное на circle, всплывает к group, вызывая обработчик родителя. Для предотвращения всплытия используется стандартный метод event.stopPropagation():

circle.on('click', function(event) {
    event.stopPropagation();
    console.log('Только круг обработан');
});

Передача данных между элементами

Для динамического взаимодействия элементов удобно использовать пользовательские события для передачи состояния между ними:

const rect2 = draw.rect(100, 100).fill('#0ff').move(150, 0);

rect.on('updateSize', function(event) {
    this.size(event.detail.width, event.detail.height);
});

rect2.on('click', function() {
    rect.fire('updateSize', { width: 150, height: 150 });
});

Здесь клик по rect2 изменяет размеры rect через пользовательское событие 'updateSize'.

События трансформации и анимации

SVG.js интегрирует события с методами анимации. Анимационные события позволяют отслеживать изменения атрибутов и завершение анимаций:

rect.animate(1000).move(200, 200).during((pos, morph, eased) => {
    console.log(`Текущее положение: ${pos}`);
}).after(() => {
    console.log('Анимация завершена');
});
  • Метод .during(callback) вызывается на каждом кадре анимации, предоставляя текущие параметры анимации.
  • Метод .after(callback) вызывается после завершения анимации.

Передача сложных структур данных

Можно передавать объекты с несколькими полями или массивы через пользовательские события:

const ellipse = draw.ellipse(80, 50).fill('#ff0');

ellipse.on('updateProperties', function(event) {
    this.size(event.detail.width, event.detail.height).fill(event.detail.color);
});

ellipse.fire('updateProperties', { width: 120, height: 70, color: '#f0f' });

Такой подход особенно полезен для построения интерактивных интерфейсов с динамическими изменениями нескольких элементов.

Советы по работе с событиями в SVG.js

  • Для сложных проектов стоит централизовать пользовательские события, чтобы избегать дублирования обработчиков.
  • Использование .fire и .on обеспечивает гибкую передачу данных между элементами.
  • Делегирование событий через группы позволяет уменьшить количество обработчиков и повысить производительность.
  • Для анимаций и интерактивных элементов предпочтительно использовать встроенные методы .during и .after, чтобы контролировать промежуточные состояния.

Эти методы делают SVG.js мощным инструментом для динамического управления SVG-элементами и передачи данных через события, что позволяет строить полноценные интерактивные графические интерфейсы.