Обработка межсеточного drag

Библиотека Muuri предоставляет мощный инструмент для создания сеток с возможностью перетаскивания элементов. Drag-and-drop (перетаскивание) является одной из ключевых возможностей, обеспечивая динамическую перестановку элементов внутри сетки и между сетками. В Muuri drag реализован с помощью встроенного механизма drag и событий, которые позволяют отслеживать начало, движение и завершение перетаскивания.

Включение drag для элементов

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

const grid = new Muuri('.grid', {
  dragEnabled: true,
  dragSort: true, // разрешает сортировку и перетаскивание между сетками
});

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

  • dragEnabled: true — делает элементы интерактивными для перетаскивания.
  • dragSort: true — позволяет элементам перемещаться между сетками.
  • Можно использовать селекторы для ограничения области drag через dragStartPredicate.

Настройка условий начала drag

Muuri предоставляет гибкую систему для определения, когда элемент можно начать перетаскивать. Основной инструмент — функция dragStartPredicate:

dragStartPredicate: {
  handle: '.handle', // только по элементу с классом handle
  distance: 5,       // минимальное смещение в пикселях
  delay: 0           // задержка перед началом перетаскивания
}
  • handle — определяет «ручку», по которой можно захватить элемент.
  • distance — предотвращает случайное срабатывание drag при клике.
  • delay — используется для тонкой настройки UX, например, для поддержки мобильных устройств.

Межсеточная сортировка (cross-grid drag)

Одним из самых мощных возможностей Muuri является поддержка drag между разными сетками. Для этого достаточно передать массив сеток в параметр dragSort:

const grid1 = new Muuri('.grid1', { dragEnabled: true });
const grid2 = new Muuri('.grid2', { dragEnabled: true });

grid1.getItems().forEach(item => item.getElement().style.cursor = 'move');

const allGrids = [grid1, grid2];

allGrids.forEach(g => g.on('dragReleaseEnd', () => g.layout()));
grid1._dragSort = allGrids;
grid2._dragSort = allGrids;

Особенности межсеточного drag:

  • Элемент может быть перемещён только в сетки, включённые в массив dragSort.
  • При перемещении между сетками автоматически обновляется расположение элементов.
  • События dragReleaseEnd, dragStart, dragMove позволяют отслеживать и контролировать процесс переноса.

События drag

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

  • dragStart(item) — срабатывает при начале перетаскивания.
  • dragMove(item, event) — во время движения элемента.
  • dragReleaseEnd(item) — после завершения drag.
  • dragRelease(item) — когда элемент отпущен, но ещё не установлен на место.
  • layoutStart(layoutType) и layoutEnd(layoutType) — полезно для отслеживания изменений позиции при drag.

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

grid.on('dragReleaseEnd', function(item) {
  console.log('Элемент перемещен:', item.getElement());
});

Управление анимацией при drag

Muuri использует плавные анимации для drag и layout. Для настройки анимации можно использовать параметры dragSortPredicate и layout:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layout: {
    duration: 400,
    easing: 'ease-in-out'
  },
  dragSort: {
    duration: 300,
    easing: 'ease'
  }
});
  • duration — длительность анимации в миллисекундах.
  • easing — тип кривой анимации.

Ограничение перетаскивания

Для ограничения перемещения элементов внутри определённых областей используется параметр dragContainer:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  dragContainer: document.body // элементы будут перемещаться относительно body
});
  • Позволяет избежать обрезки элементов при выходе за пределы сетки.
  • Удобно при создании drag между сетками с разной структурой DOM.

Программное управление элементами drag

Можно динамически включать или отключать drag для отдельных элементов:

const item = grid.getItems()[0];
item.enableDrag();  // включить drag
item.disableDrag(); // отключить drag

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

Особенности для мобильных устройств

Muuri поддерживает touch-события, однако для корректной работы рекомендуется:

  • Использовать dragStartPredicate.delay для предотвращения случайных срабатываний.
  • Настроить handle для удобного захвата элементов пальцем.
  • Обеспечить плавную анимацию с короткой задержкой для сенсорного интерфейса.

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

Muuri позволяет одновременно использовать drag, фильтры и сортировку. При этом важно:

  • Вызывать grid.layout() после фильтрации или сортировки, чтобы элементы корректно адаптировались.
  • Drag автоматически подстраивается под текущий видимый набор элементов.
  • Межсеточный drag сохраняет логику сортировки внутри каждой сетки.
grid.filter('.visible').sort('data-order');
grid.layout();

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