Подключение Draggabilly

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

Установка Draggabilly

Draggabilly можно подключить несколькими способами:

  1. Через CDN — удобно для быстрого подключения в проект без сборщика модулей:
<script src="https://unpkg.com/draggabilly@2/dist/draggabilly.pkgd.min.js"></script>
  1. Через npm — для проектов с использованием сборщиков модулей (Webpack, Parcel, Vite и т.д.):
npm install draggabilly

После установки импорт можно выполнить так:

import Draggabilly from 'draggabilly';

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

Чтобы элементы сетки Packery можно было перетаскивать, необходимо создать экземпляры Draggabilly для каждого элемента. Рассмотрим пошагово:

  1. Инициализация Packery
var grid = document.querySelector('.grid');
var pckry = new Packery(grid, {
  itemSelector: '.grid-item',
  gutter: 10
});
  1. Создание Draggabilly для каждого элемента
var items = grid.querySelectorAll('.grid-item');
items.forEach(function(item) {
  var draggie = new Draggabilly(item);
  pckry.bindDraggabillyEvents(draggie);
});

Объяснение ключевых моментов:

  • Draggabilly(item) — создаёт объект, отвечающий за перетаскивание конкретного DOM-элемента.
  • bindDraggabillyEvents(draggie) — связывает события Draggabilly с Packery, чтобы сетка корректно перестраивалась при перемещении элементов.

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

Draggabilly поддерживает множество параметров конфигурации:

var draggie = new Draggabilly(item, {
  containment: '.grid',   // ограничивает движение элементом родителя
  axis: 'x'               // ограничивает движение только по оси X
});
  • containment — предотвращает выход элемента за пределы контейнера.
  • axis — можно ограничить движение по одной из осей ('x' или 'y').
  • handle — задаёт CSS-селектор для области, с которой можно перетаскивать элемент, например .handle.

Динамическая работа с новыми элементами

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

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

var draggie = new Draggabilly(newItem);
pckry.appended(newItem);
pckry.bindDraggabillyEvents(draggie);
  • pckry.appended(newItem) — уведомляет Packery о новом элементе и перестраивает сетку.
  • bindDraggabillyEvents(draggie) — обеспечивает возможность перетаскивания добавленного элемента.

Оптимизация производительности

При большом количестве элементов рекомендуется:

  1. Создавать Draggabilly только для видимых элементов, если используется виртуализация.
  2. Использовать событие dragEnd для сохранения состояния сетки:
draggie.on('dragEnd', function() {
  console.log('Новая позиция элемента:', draggie.position);
});
  1. Удалять события Draggabilly перед удалением элементов из DOM:
draggie.destroy();

Это предотвращает утечки памяти и некорректное поведение Packery.

Совместимость с CSS-трансформациями

Packery использует transform: translate() для позиционирования элементов. Draggabilly автоматически учитывает эти трансформации при перетаскивании, что обеспечивает плавную работу сетки без конфликтов. Важно, чтобы элементы имели position: absolute внутри контейнера Packery:

.grid-item {
  width: 100px;
  height: 100px;
  position: absolute;
}

Отслеживание событий и пользовательская логика

Draggabilly поддерживает множество событий:

  • dragStart — начало перетаскивания
  • dragMove — движение элемента
  • dragEnd — завершение перетаскивания

Пример привязки:

draggie.on('dragStart', function() {
  item.style.zIndex = 10; // поднимаем элемент выше других
});

draggie.on('dragEnd', function() {
  item.style.zIndex = '';
});

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


Packery и Draggabilly вместе образуют мощный инструмент для построения динамичных, интерактивных сеток. Их интеграция проста и гибка, позволяя контролировать поведение элементов, ограничивать перемещение и управлять сеткой в реальном времени.