Библиотека Packery предназначена для создания сеток с динамическим расположением элементов, обеспечивая плотное и оптимальное заполнение пространства. Одним из ключевых преимуществ Packery является возможность перетаскивания элементов, интегрированная через jQuery UI Draggable. Подключение Draggable позволяет пользователю интерактивно менять положение блоков, а Packery автоматически перестраивает сетку.
Для работы Draggable требуется подключение jQuery UI, так как Packery использует его API для управления перетаскиванием. Подключение осуществляется через CDN или локальные файлы:
<!-- jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<!-- jQuery UI -->
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
Важно подключать jQuery перед jQuery UI, иначе Draggable работать не будет.
После подключения jQuery UI необходимо подключить саму библиотеку Packery:
<script src="https://unpkg.com/packery@2/dist/packery.pkgd.min.js"></script>
Packery предоставляет объектную модель для управления сеткой, включая
методы layout, shiftLayout,
append и remove.
Инициализация сетки Packery осуществляется через создание нового экземпляра:
var $grid = $('.grid').packery({
itemSelector: '.grid-item',
gutter: 10
});
После инициализации Packery необходимо сделать элементы перетаскиваемыми с помощью jQuery UI:
$grid.find('.grid-item').each(function(i, itemElem) {
$(itemElem).draggable({
containment: '.grid', // Ограничение перемещения границами сетки
stop: function(event, ui) {
$grid.packery('layout'); // Обновление сетки после завершения перетаскивания
}
});
});
Ключевые моменты:
containment предотвращает выход элементов за пределы
контейнера.stop вызывается после завершения перетаскивания, что
позволяет Packery пересчитать позиции.Хотя jQuery UI Draggable полностью совместим с Packery, библиотека
Draggabilly может быть использована для более тесной
интеграции. При использовании Draggabilly можно воспользоваться методом
bindDraggabillyEvents:
var pckry = new Packery('.grid', {
itemSelector: '.grid-item',
gutter: 10
});
$('.grid-item').each(function(i, itemElem) {
var draggie = new Draggabilly(itemElem);
pckry.bindDraggabillyEvents(draggie);
});
Draggabilly автоматически синхронизирует перетаскивание с Packery, включая расчет коллизий и смещение соседних элементов.
Если в сетку добавляются новые элементы динамически, необходимо повторно инициализировать Draggable:
var $newItems = $('<div class="grid-item"></div>');
$grid.append($newItems)
.packery('appended', $newItems);
$newItems.draggable({
containment: '.grid',
stop: function(event, ui) {
$grid.packery('layout');
}
});
Метод appended сообщает Packery о новых элементах, а
повторная инициализация Draggable обеспечивает возможность их
перетаскивания.
jQuery UI Draggable поддерживает ряд полезных опций, которые могут быть применены вместе с Packery:
x) или вертикали (y).Пример с ограничением по вертикали и привязкой к сетке 50px:
$('.grid-item').draggable({
axis: 'y',
grid: [50, 50],
containment: '.grid',
stop: function() {
$grid.packery('layout');
}
});
Packery позволяет отслеживать события перетаскивания и взаимодействовать с ними:
dragItemPositioned – вызывается после позиционирования
элемента.layoutComplete – после завершения перестройки
сетки.removeComplete – после удаления элемента.Пример обработки события:
$grid.on('dragItemPositioned', function(event, draggedItem) {
console.log('Элемент перемещен:', draggedItem.element);
});
Использование этих событий позволяет строить сложные интерактивные интерфейсы с динамическим обновлением данных, анимацией или синхронизацией с сервером.
При большом количестве элементов рекомендуется:
transform: translate3d в стилях
.grid-item для аппаратного ускорения.layout() через
stop вместо drag.layout() один раз после вставки всех элементов..grid имеет
position: relative или absolute, иначе Packery
может некорректно рассчитывать координаты.Эта интеграция обеспечивает плавное перетаскивание и автоматическое перестроение сетки, делая интерфейс гибким и интерактивным.