Анимация при фильтрации

Библиотека Masonry в JavaScript предназначена для динамического упорядочивания блоков в сетке с разной высотой. При фильтрации элементов важно не просто скрыть ненужные карточки, а сделать процесс плавным и визуально понятным. Для этого используются CSS-переходы и методы библиотеки, обеспечивающие корректное перераспределение элементов.

Использование метода layout()

Метод layout() пересчитывает расположение элементов после изменения их видимости. Он не производит анимацию сам по себе, но является ключевым для корректного перераспределения:

var grid = document.querySelector('.grid');
var msnry = new Masonry(grid, {
  itemSelector: '.grid-item',
  columnWidth: 200,
  gutter: 10
});

// Скрытие элемента и пересчет сетки
var item = grid.querySelector('.grid-item');
item.style.display = 'none';
msnry.layout();

Чтобы сделать процесс плавным, необходимо использовать CSS-переходы, влияющие на трансформацию и прозрачность элементов.

Анимация с помощью CSS

Для плавного скрытия и появления элементов удобно использовать свойства opacity и transform:

.grid-item {
  transition: transform 0.4s ease, opacity 0.4s ease;
  opacity: 1;
}

.grid-item.hidden {
  opacity: 0;
  transform: scale(0.8);
}

При фильтрации добавляется класс hidden к элементам, которые нужно скрыть, а затем вызывается layout() для перераспределения видимых элементов:

function filterItems(category) {
  var items = grid.querySelectorAll('.grid-item');
  
  items.forEach(function(item) {
    if (item.dataset.category === category || category === 'all') {
      item.classList.remove('hidden');
    } else {
      item.classList.add('hidden');
    }
  });

  // Перераспределение сетки после применения классов
  msnry.layout();
}

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

Для более заметной анимации часто используют задержку изменения display, чтобы сначала проигралась анимация прозрачности, а затем элемент полностью удалялся из потока документа:

items.forEach(function(item) {
  if (item.classList.contains('hidden')) {
    item.addEventListener('transitionend', function hideItem() {
      item.style.display = 'none';
      item.removeEventListener('transitionend', hideItem);
    });
  } else {
    item.style.display = 'block';
  }
});

Комбинирование Masonry с библиотекой анимаций

Для более сложных эффектов можно использовать сторонние библиотеки, например GSAP. Она позволяет анимировать x, y, opacity и другие CSS-свойства, что делает фильтрацию более выразительной:

gsap.to('.grid-item', {
  duration: 0.5,
  opacity: 0,
  scale: 0.8,
  stagger: 0.05,
  onComplete: function() {
    msnry.layout();
  }
});

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

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

  • Использовать transform вместо top/left для GPU-ускорения.
  • Ограничивать количество одновременно анимируемых элементов.
  • Минимизировать перерисовку DOM, вызывая layout() один раз после всех изменений.

Практические советы

  1. Всегда комбинировать CSS-переходы и layout() — Masonry корректно распределяет элементы, CSS делает это плавно.
  2. Фильтрация через классы более эффективна, чем динамическое удаление и добавление DOM-элементов.
  3. Событие transitionend позволяет синхронизировать скрытие с завершением анимации, избегая резких исчезновений.
  4. Плавность и последовательность: использование stagger или небольших задержек создает эффект волны при фильтрации.
  5. Мобильная оптимизация: на небольших экранах уменьшать количество одновременно анимируемых элементов.

Итоговая структура фильтрации с анимацией

  1. Присвоение классов для скрытия/показа элементов.
  2. Включение CSS-переходов для transform и opacity.
  3. Вызов msnry.layout() после изменения классов.
  4. Использование transitionend или сторонних библиотек для тонкой настройки анимации.
  5. Оптимизация производительности при большом количестве элементов.

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