Заполнение пробелов

Packery — это библиотека для динамического расположения элементов в сетке с произвольными размерами, обеспечивающая минимизацию пустого пространства. В отличие от стандартных грид-систем, Packery работает по принципу «bin-packing», то есть максимально эффективно упаковывает элементы в доступное пространство, учитывая их размеры и порядок.

Базовое использование требует подключения библиотеки и инициализации контейнера:

const grid = document.querySelector('.grid');
const pckry = new Packery(grid, {
  itemSelector: '.grid-item',
  gutter: 10
});
  • itemSelector — CSS-селектор для элементов сетки.
  • gutter — отступ между элементами.

Packery автоматически вычисляет оптимальное расположение элементов и распределяет их по строкам и колонкам с учётом пробелов.


Заполнение пробелов

Основная сила Packery заключается в умном заполнении пустых мест. Если в сетке появляются элементы разной высоты или ширины, стандартные сетки оставляют пустые области. Packery минимизирует эти зоны:

  • Фрагментация пространства: библиотека отслеживает свободные области в сетке, представляя их в виде «свободных ячеек».
  • Перемещение элементов: элементы могут переставляться внутри контейнера для более плотного заполнения.
  • Адаптация под размеры: при изменении размеров контейнера или элементов Packery автоматически перераспределяет элементы.

Пример добавления элемента и динамического заполнения пустого места:

const newItem = document.createElement('div');
newItem.className = 'grid-item';
grid.appendChild(newItem);
pckry.appended(newItem);
pckry.layout();

Метод appended сообщает Packery о новом элементе, после чего layout перераспределяет все элементы.


Работа с разными размерами элементов

Packery позволяет работать с элементами произвольных размеров, благодаря чему достигается эффект «мозаики». Чтобы добиться корректного заполнения:

  1. Установить размеры через CSS:
.grid-item {
  width: 100px;
  height: 100px;
}

.grid-item.wide {
  width: 210px;
}

.grid-item.tall {
  height: 210px;
}
  1. Использовать опцию stamp для закрепления определённых элементов в сетке:
pckry.stamp(document.querySelector('.grid-item.stamp'));
pckry.layout();

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


Динамическое обновление

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

  • appended(elements) — добавляет новые элементы.
  • removed(elements) — удаляет элементы из сетки.
  • prepended(elements) — вставляет элементы в начало контейнера.
  • layout() — принудительно пересчитывает расположение всех элементов.

Пример удаления элемента:

const item = document.querySelector('.grid-item');
pckry.remove(item);
pckry.layout();

Управление пустым пространством

Для точной настройки заполнения пробелов можно использовать:

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

Эти параметры помогают минимизировать неиспользуемое пространство при изменении размеров окна или элементов.


Взаимодействие с другими библиотеками

Packery часто используют совместно с Draggabilly для реализации перетаскивания элементов. Пример:

const draggies = [];
pckry.getItemElements().forEach(itemElem => {
  const draggie = new Draggabilly(itemElem);
  pckry.bindDraggabillyEvents(draggie);
  draggies.push(draggie);
});

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


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

Для больших сеток рекомендуется:

  • Использовать imagesLoaded, чтобы убедиться, что размеры изображений известны перед вызовом layout().
  • Минимизировать вызовы layout() при массовых изменениях, группируя добавления/удаления.
  • Применять фиксированные размеры элементов или сетку с колонками для ускорения вычислений.

Пример с imagesLoaded:

imagesLoaded(grid, function() {
  pckry.layout();
});

Итоговые рекомендации по заполнению пробелов

  • Использовать gutter и columnWidth для согласованной структуры.
  • Закреплять ключевые элементы через stamp.
  • Применять динамическое добавление через appended() и layout().
  • Комбинировать с Draggabilly для интерактивного перемещения.
  • Контролировать загрузку изображений, чтобы не нарушить вычисления Packery.

Эти приёмы позволяют создавать адаптивные, плотные и визуально аккуратные сетки с минимальными пустыми зонами.