Кастомные анимации

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

В основе кастомизации лежит свойство transition, а также интеграция с библиотеками типа GSAP или нативным requestAnimationFrame. Packery работает с позициями элементов через CSS transform, что позволяет плавно изменять положение блоков без перерасчета DOM.


Настройка анимаций через CSS

Packery автоматически применяет анимацию при перемещении элементов, если заданы CSS-свойства:

.grid-item {
  transition: transform 0.4s ease-in-out;
}

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

  • transform — управляет смещением блока.
  • 0.4s — длительность анимации.
  • ease-in-out — функция ускорения, изменяемая для разных эффектов.
  • Можно использовать cubic-bezier для создания сложных кривых движения.

Чтобы отключить стандартные анимации и полностью управлять ими через JS, нужно:

var pckry = new Packery('.grid', {
  itemSelector: '.grid-item',
  transitionDuration: 0
});

Управление анимациями через JavaScript

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

  • layoutComplete — вызывается после завершения выравнивания сетки.
  • dragItemPositioned — срабатывает при окончании перетаскивания блока.

Пример использования с GSAP:

pckry.on('layoutComplete', function() {
  pckry.items.forEach(function(item) {
    gsap.fromTo(item.element, 
      { scale: 0.8, opacity: 0 }, 
      { scale: 1, opacity: 1, duration: 0.6, ease: "power2.out" }
    );
  });
});

Особенности:

  • item.element — DOM-элемент блока.
  • fromTo позволяет задать начальное и конечное состояние.
  • Использование GSAP делает анимацию независимой от стандартного CSS transition.

Синхронизация с drag&drop

Packery тесно интегрирован с Draggabilly, что позволяет анимировать элементы при перетаскивании. Основной подход — подписка на событие dragMove и обновление анимации в реальном времени:

pckry.items.forEach(function(item) {
  var draggie = new Draggabilly(item.element);
  pckry.bindDraggabillyEvents(draggie);

  draggie.on('dragMove', function(event, pointer) {
    gsap.to(item.element, {
      rotation: pointer.x / 10,
      duration: 0.2
    });
  });
});

Преимущества:

  • Эффект наклона или масштабирования создаёт ощущение интерактивности.
  • Анимация идёт параллельно с перемещением, не вызывая сбоев Packery.

Кастомные layout-функции с анимацией

Packery позволяет задавать собственные алгоритмы размещения элементов через stamp или изменение координат блоков перед вызовом layout():

pckry.items.forEach(function(item, i) {
  item.position.x = i * 150;
  item.position.y = Math.sin(i) * 50 + 100;
});

pckry.layout();

Для анимации можно использовать requestAnimationFrame:

function animateItems() {
  pckry.items.forEach(function(item, i) {
    var x = i * 150;
    var y = Math.sin(Date.now() / 500 + i) * 50 + 100;
    gsap.to(item.element, { x: x, y: y, duration: 0.5 });
  });
  requestAnimationFrame(animateItems);
}

animateItems();

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


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

  1. Ограничение количества элементов анимируемых одновременно — анимация сотен блоков одновременно снижает FPS.
  2. Использование transform вместо top/left — GPU-ускорение обеспечивает плавность.
  3. Throttle для drag-событий — уменьшает нагрузку при постоянном перемещении элементов.
  4. Отказ от layout() при каждом кадре — лучше обновлять только стили элементов через JS/GSAP.

Комбинация с другими эффектами

  • Постепенное появление: можно использовать задержки (delay) для stagger-эффекта.
  • Цветовые трансформации: с помощью GSAP легко менять background или border при перемещении.
  • Сложные кривые: анимация по синусоиде, спирали или по произвольной траектории создается через прямое изменение координат элементов.

Packery с кастомными анимациями позволяет создавать не просто сетку, а полноценный интерактивный интерфейс, где каждый блок ведет себя как независимый объект, а перемещения выглядят плавно и живо.