Настройка перетаскивания

Packery — это мощная библиотека для создания динамических сеток, в которых элементы можно упорядочивать и перемещать. Одним из ключевых функционалов является возможность перетаскивания элементов (drag-and-drop), обеспечиваемая через интеграцию с библиотекой Draggabilly или нативными средствами HTML5. Важно понимать, что Packery самостоятельно не реализует перетаскивание, а управляет позиционированием элементов после того, как их переместили.

var grid = document.querySelector('.grid');
var pckry = new Packery(grid, {
  itemSelector: '.grid-item',
  gutter: 10
});

Здесь itemSelector определяет элементы сетки, которые могут участвовать в перетаскивании.


Интеграция с Draggabilly

Для полноценного drag-and-drop необходимо подключить Draggabilly:

var itemElems = grid.querySelectorAll('.grid-item');
itemElems.forEach(function(itemElem) {
  var draggie = new Draggabilly(itemElem);
  pckry.bindDraggabillyEvents(draggie);
});
  • Draggabilly(itemElem) — создаёт объект, управляющий перетаскиванием конкретного элемента.
  • bindDraggabillyEvents(draggie) — связывает события Draggabilly с Packery, чтобы сетка автоматически перестраивалась при перемещении.

Ключевой момент: после каждого завершённого перетаскивания Packery автоматически вызывает перестройку сетки, гарантируя отсутствие перекрытий и корректное распределение элементов.


Настройка ограничений перетаскивания

Packery позволяет управлять поведением перетаскиваемых элементов через Draggabilly:

var draggie = new Draggabilly(itemElem, {
  containment: '.grid',
  axis: 'y'
});
  • containment — ограничивает область перемещения элементом сетки или другим контейнером.
  • axis — ограничивает движение по одной оси ('x' или 'y').
  • grid.snap (в Draggabilly) — опция привязки к сетке, чтобы элементы «прилипали» к ячейкам.

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


События перетаскивания

Packery и Draggabilly предоставляют мощные события для отслеживания действий пользователя:

  • dragStart — вызывается при начале перетаскивания элемента.
  • dragMove — вызывается при каждом изменении позиции во время перетаскивания.
  • dragEnd — вызывается после завершения перемещения, момент, когда Packery перестраивает сетку.

Пример подписки на события:

draggie.on('dragStart', function() {
  itemElem.classList.add('is-dragging');
});

draggie.on('dragEnd', function() {
  itemElem.classList.remove('is-dragging');
});

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


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

Packery поддерживает drag-and-drop даже для элементов, добавленных после инициализации:

var newItem = document.createElement('div');
newItem.className = 'grid-item';
grid.appendChild(newItem);

var draggie = new Draggabilly(newItem);
pckry.appended(newItem);
pckry.bindDraggabillyEvents(draggie);

Метод appended уведомляет Packery о новом элементе, чтобы сетка перестроилась и включила его в расчёты позиционирования.

Важно всегда вызывать bindDraggabillyEvents для новых элементов, иначе они не будут интерактивными.


Советы по производительности

  1. Ограничение количества одновременно перетаскиваемых элементов снижает нагрузку на перестройку сетки.
  2. Использование CSS transform вместо top/left ускоряет анимацию перемещения.
  3. Дебаунс событий dragMove помогает избежать лишних вызовов перестройки сетки при быстрых движениях.

Настройка поведения при коллизиях

Packery использует алгоритм “masonry-style”, автоматически подбирающий ближайшую свободную позицию для элемента после перетаскивания. Можно контролировать это через параметры:

var pckry = new Packery(grid, {
  itemSelector: '.grid-item',
  gutter: 10,
  percentPosition: true
});
  • percentPosition — позволяет использовать проценты для позиционирования, что улучшает адаптивность сетки.
  • gutter — задаёт расстояние между элементами, влияя на то, как Packery «впихивает» элементы после перетаскивания.

Для сложных сеток с неравномерными размерами элементов можно использовать callback layoutComplete для дополнительной настройки после завершения перестройки.


Перетаскивание с ограничением сортировки

Если нужно запретить изменение порядка некоторых элементов:

pckry.items.forEach(function(item) {
  if (item.element.classList.contains('fixed')) {
    var draggie = new Draggabilly(item.element, { disable: true });
  }
});

Это позволяет иметь фиксированные блоки, которые остаются на своих местах, не нарушая общую динамику сетки.


Настройка перетаскивания в Packery, объединённая с Draggabilly, обеспечивает полный контроль над динамическими сетками, позволяя создавать сложные интерфейсы с интерактивными элементами, анимацией и адаптивным расположением.