Перемещение элементов — одна из ключевых возможностей библиотеки Packery. В отличие от обычных сеточных систем, где элементы занимают фиксированные позиции, Packery позволяет динамически изменять расположение блоков внутри контейнера. Перемещение может происходить автоматически при перестройке сетки, либо вручную при взаимодействии пользователя с интерфейсом.
В основе механизма перемещения лежит алгоритм «упаковки» элементов, который пересчитывает доступное пространство контейнера и размещает блоки так, чтобы минимизировать пустоты между ними.
При перемещении элемента Packery выполняет несколько последовательных операций:
Каждый элемент внутри контейнера рассматривается как прямоугольная область. Алгоритм отслеживает свободные участки контейнера и при необходимости перераспределяет элементы, чтобы сохранить плотную компоновку.
Особенности алгоритма:
Packery предоставляет методы для программного изменения расположения
элементов. Один из наиболее важных — shiftLayout.
Этот метод инициирует перерасчёт позиций элементов с учётом новых координат.
var grid = document.querySelector('.grid');
var pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
После инициализации элементы автоматически размещаются внутри контейнера.
Перемещение элемента можно инициировать вручную, изменив его координаты и вызвав перерасчёт layout.
var item = grid.querySelector('.grid-item');
item.style.left = '200px';
item.style.top = '100px';
pckry.shiftLayout();
После вызова shiftLayout() библиотека:
fitМетод fit используется для перемещения элемента в
определённую позицию контейнера.
Синтаксис:
pckry.fit( element, x, y );
Параметры:
| Параметр | Описание |
|---|---|
| element | перемещаемый DOM-элемент |
| x | координата X |
| y | координата Y |
var item = grid.querySelector('.grid-item');
pckry.fit(item, 300, 150);
После выполнения:
(300,150)При изменении размеров элементов Packery автоматически пересчитывает расположение. Это позволяет создавать адаптивные интерфейсы.
Пример изменения размера:
var item = grid.querySelector('.grid-item');
item.style.width = '200px';
pckry.layout();
Метод layout():
Одно из наиболее распространённых применений Packery — создание интерфейсов с перетаскиванием элементов.
Для этого используется интеграция с библиотекой Draggabilly.
var pckry = new Packery('.grid', {
itemSelector: '.grid-item',
gutter: 10
});
var items = document.querySelectorAll('.grid-item');
items.forEach(function(item){
var draggie = new Draggabilly(item);
pckry.bindDraggabillyEvents(draggie);
});
После привязки событий:
При перемещении одного элемента Packery проверяет пересечение с другими элементами.
Алгоритм выполняет:
Если элемент занимает позицию, где уже находится другой элемент, библиотека:
Это создаёт эффект «живой» сетки, где элементы автоматически перемещаются при изменениях.
Иногда требуется запретить перемещение элемента за пределы контейнера.
Packery автоматически ограничивает область движения размерами родительского контейнера. Однако дополнительные ограничения можно реализовать через настройки Drag & Drop.
Пример:
var draggie = new Draggabilly(item, {
containment: '.grid'
});
Опция containment:
При изменении позиции Packery использует CSS-трансформации для плавного перемещения элементов.
Преимущества такого подхода:
Пример CSS:
.grid-item {
transition: transform 0.4s;
}
При перестройке layout элементы перемещаются анимировано.
Packery предоставляет события, позволяющие реагировать на изменения расположения элементов.
Основные события:
| Событие | Описание |
|---|---|
| layoutComplete | завершение перестройки сетки |
| dragItemPositioned | завершение перемещения элемента |
| fitComplete | завершение метода fit |
pckry.on('dragItemPositioned', function(item){
console.log('Элемент перемещён', item.element);
});
Это позволяет:
После перемещения элементов часто требуется сохранить их расположение, чтобы восстановить его при следующей загрузке страницы.
Пример сохранения координат:
pckry.on('dragItemPositioned', function(){
var positions = [];
pckry.items.forEach(function(item){
positions.push({
id: item.element.dataset.id,
x: item.rect.x,
y: item.rect.y
});
});
localStorage.setItem('layout', JSON.stringify(positions));
});
При загрузке страницы можно восстановить позиции:
var saved = JSON.parse(localStorage.getItem('layout'));
После этого координаты применяются к элементам и выполняется перерасчёт layout.
При добавлении новых элементов Packery автоматически перераспределяет сетку.
var newItem = document.createElement('div');
newItem.classList.add('grid-item');
grid.appendChild(newItem);
pckry.appended(newItem);
Метод appended():
При большом количестве элементов частые перемещения могут создавать нагрузку на браузер. Для оптимизации используются следующие подходы:
Минимизация перерасчётов
Перерасчёт layout следует вызывать только при необходимости.
Использование CSS transform
Packery перемещает элементы через transform, что снижает
нагрузку на reflow.
Групповые обновления
Если происходит несколько изменений:
pckry.reloadItems();
pckry.layout();
Это позволяет обновить сетку одной операцией.
При работе с Packery важно учитывать несколько особенностей:
Эти свойства позволяют создавать интерфейсы со сложной динамической компоновкой элементов, где блоки могут свободно перемещаться, перестраиваться и автоматически занимать доступные области контейнера.