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

Packery — это мощная библиотека для создания нестандартных сеток с упорядочиванием элементов по свободной компоновке, а Isotope расширяет её возможности, добавляя фильтрацию, сортировку и анимацию элементов. Совместное использование этих библиотек позволяет создавать динамичные, интерактивные интерфейсы с плавающими элементами разного размера, при этом сохраняя полный контроль над их порядком и визуальной организацией.


Подключение библиотек

Для корректной работы необходимо подключить обе библиотеки в следующем порядке:

<link rel="stylesheet" href="path/to/your/styles.css">
<script src="https://unpkg.com/packery@2/dist/packery.pkgd.min.js"></script>
<script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>

Важно подключать Packery до Isotope, так как Isotope использует Packery как layout-модуль.


Инициализация Packery как layout-модуля Isotope

Создание контейнера с элементами выполняется стандартным образом:

<div class="grid">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
</div>

Инициализация Isotope с использованием Packery:

var elem = document.querySelector('.grid');

var iso = new Isotope(elem, {
  itemSelector: '.grid-item',
  layoutMode: 'packery',
  packery: {
    gutter: 10
  }
});

Ключевые моменты:

  • itemSelector указывает на отдельные элементы сетки.
  • layoutMode: 'packery' сообщает Isotope использовать Packery для расчёта расположения элементов.
  • Параметр gutter задаёт промежуток между элементами.

Настройка размеров элементов

Packery поддерживает элементы разных размеров, что особенно важно при работе с динамическим контентом.

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

.grid-item.w2 { width: 210px; } /* два столбца */
.grid-item.h2 { height: 210px; } /* две строки */

При инициализации Packery через Isotope эти размеры учитываются автоматически, и элементы занимают нужное место без перекрытия.


Фильтрация и сортировка с Isotope

Isotope позволяет динамически изменять видимые элементы без пересоздания сетки:

// Фильтрация по классу
document.querySelector('#filter-buttons').addEventListener('click', function(event) {
  if (!event.target.matches('button')) return;
  var filterValue = event.target.getAttribute('data-filter');
  iso.arrange({ filter: filterValue });
});

// Сортировка по атрибуту
iso.arrange({ sortBy: 'name' });

Особенности взаимодействия:

  • Packery не влияет на фильтрацию — Isotope скрывает элементы и пересчитывает расположение оставшихся.
  • Анимация происходит плавно, благодаря встроенным возможностям Isotope.

Динамическое добавление и удаление элементов

Добавление новых элементов в сетку требует обновления как Packery, так и Isotope:

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

iso.appended(newItem);
iso.layout();

Удаление элементов:

var itemToRemove = elem.querySelector('.grid-item:last-child');
iso.remove(itemToRemove);
iso.layout();

Важные моменты:

  • iso.appended() уведомляет Isotope о новых элементах.
  • iso.layout() перерассчитывает позицию всех элементов, чтобы избежать пустот.

Обработка событий Packery через Isotope

Isotope позволяет подписываться на события Packery, например, при завершении компоновки:

iso.on('arrangeComplete', function(filteredItems) {
  console.log('Сетка обновлена, элементов:', filteredItems.length);
});

Это даёт возможность реагировать на изменения сетки, синхронизировать другие UI-компоненты или выполнять дополнительные анимации.


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

  1. Использовать фиксированные размеры элементов, когда это возможно — снижает нагрузку на пересчёт сетки.
  2. Группировать массовые изменения (например, добавление нескольких элементов за один вызов iso.appended) — уменьшает количество перерасчётов.
  3. Оптимизировать изображения — Packery учитывает размеры элементов при рендере, поэтому задержка загрузки изображений может вызвать неправильное позиционирование.

Кастомизация поведения Packery в Isotope

Packery предоставляет дополнительные настройки, которые можно передавать через объект packery:

var iso = new Isotope(elem, {
  itemSelector: '.grid-item',
  layoutMode: 'packery',
  packery: {
    gutter: 10,
    percentPosition: true,
    transitionDuration: '0.4s'
  }
});
  • percentPosition: true позволяет использовать относительные размеры для адаптивных сеток.
  • transitionDuration задаёт скорость анимации при перестроении сетки.

Адаптивные сетки и медиа-запросы

Packery отлично сочетается с CSS Grid или Flexbox для адаптивных сеток. Пример адаптивной ширины элементов:

.grid-item {
  width: 100%;
}

@media (min-width: 600px) {
  .grid-item { width: 48%; }
}

@media (min-width: 900px) {
  .grid-item { width: 30%; }
}

При изменении ширины окна iso.layout() автоматически пересчитывает позиции элементов, обеспечивая корректное расположение в адаптивном дизайне.


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

Packery и Isotope можно комбинировать с:

  • Lazy loading изображений: пересчёт сетки после загрузки новых картинок.
  • Drag & drop: Packery поддерживает draggable элементы, совместимые с Isotope.
  • Интерактивные фильтры: селекторы, чекбоксы, диапазоны — обновляют сетку без потери анимации.

Совместная работа Packery и Isotope создаёт гибкую и динамичную сетку, которая подходит как для галерей, так и для интерфейсов с произвольными элементами разной высоты и ширины, обеспечивая плавную анимацию, фильтрацию и сортировку без потери производительности.