Drag and drop элементов

Библиотека SVG.js предоставляет удобные инструменты для работы с графикой SVG, включая управление позиционированием элементов с помощью drag and drop. Для реализации перетаскивания используется метод .draggable(), который позволяет сделать любой SVG-элемент интерактивным и перемещаемым по холсту.

Подключение плагина

Функционал drag and drop не включен в базовый пакет SVG.js и реализуется через плагин svg.draggable.js. Для его подключения достаточно импортировать скрипт после основного SVG.js:

<script src="svg.min.js"></script>
<script src="svg.draggable.js"></script>

После этого метод .draggable() становится доступен для любого элемента SVG.

Активация перетаскивания

Простейший пример активации drag and drop:

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

В данном примере прямоугольник можно перетаскивать мышью. Метод .draggable() создает обработчики событий mousedown, mousemove и mouseup автоматически, отслеживая координаты курсора и обновляя позицию элемента.

Ограничения перемещения

Для управления областью перемещения используется объект с параметрами:

rect.draggable({
  minX: 50,
  minY: 50,
  maxX: 400,
  maxY: 400
});
  • minX, minY — минимальные координаты элемента.
  • maxX, maxY — максимальные координаты элемента.

Можно также использовать функцию constraint для более сложных условий:

rect.draggable({
  constraint: function(x, y) {
    return { x: Math.max(0, Math.min(400, x)), y: Math.max(0, Math.min(400, y)) };
  }
});

Эта функция получает новые координаты x и y и возвращает откорректированные значения, что позволяет задавать произвольные границы движения.

События drag and drop

SVG.js предоставляет ряд событий, которые помогают отслеживать состояние перетаскивания:

  • dragstart — начинается перетаскивание
  • dragmove — элемент перемещается
  • dragend — перетаскивание завершено

Пример использования:

rect.on('dragstart', function(e) {
  console.log('Начало перетаскивания', e);
});

rect.on('dragmove', function(e) {
  console.log('Двигается к', this.x(), this.y());
});

rect.on('dragend', function(e) {
  console.log('Перетаскивание завершено');
});

Объект события e содержит информацию о позиции курсора, а методы элемента .x() и .y() возвращают текущие координаты SVG-элемента.

Перетаскивание групп элементов

Метод .draggable() работает не только с отдельными элементами, но и с группами (<g>).

const group = draw.group();
const circle = draw.circle(50).fill('#0f9');
const text = draw.text('SVG.js').move(60, 20);
group.add(circle).add(text).draggable();

При перемещении группы все элементы внутри нее смещаются одновременно, что удобно для сложных объектов с несколькими компонентами.

Drag and drop с трансформациями

Если элемент имеет трансформации (rotate, scale, translate), перетаскивание корректно учитывает текущее состояние:

rect.rotate(45).scale(1.5).draggable();

SVG.js автоматически обновляет матрицу трансформации при движении элемента. Для точного контроля можно использовать методы .dx() и .dy(), которые добавляют смещение к текущим координатам:

rect.on('dragmove', function(e) {
  this.dx(5).dy(0); // смещает элемент по x на 5 пикселей при каждом событии
});

Сочетание drag and drop с другими эффектами

Перетаскивание можно комбинировать с анимациями и изменением стилей:

rect.draggable().on('dragend', function() {
  this.animate(500).fill('#09f');
});

После завершения перетаскивания прямоугольник плавно меняет цвет, сохраняя позицию, на которую его переместили.

Применение к динамически создаваемым элементам

Для элементов, создаваемых в процессе работы приложения, достаточно вызывать .draggable() после добавления элемента на холст:

function addCircle() {
  const circle = draw.circle(40).fill('#fa0').move(Math.random()*400, Math.random()*400);
  circle.draggable();
}

Это позволяет динамически создавать интерактивные объекты, не меняя основной код.

Итоговые рекомендации

  • Для простого перетаскивания достаточно element.draggable().
  • Для ограничения области движения использовать minX, maxX, minY, maxY или constraint.
  • Для сложных объектов применять группы и управлять событиями dragstart, dragmove, dragend.
  • Drag and drop корректно работает с трансформациями и анимациями.
  • Динамически созданные элементы также могут быть интерактивными при вызове .draggable().

Эти инструменты позволяют создавать полноценные интерактивные SVG-приложения с удобным управлением перемещением элементов и гибким контролем поведения drag and drop.