Процесс перемещения

Muuri — это гибкая библиотека для создания сеток с поддержкой перетаскивания и анимации. Основной единицей работы является сеточный контейнер, который содержит элементы (items). Чтобы включить функциональность перемещения, необходимо при инициализации сетки задать соответствующие опции:

const grid = new Muuri('.grid', {
  dragEnabled: true, // Включение перетаскивания
  layout: {
    rounding: false // Отключение округления для более точного позиционирования
  }
});

Ключевой момент: dragEnabled: true автоматически делает все элементы сетки перемещаемыми с использованием мыши или тач-устройств. При этом Muuri отслеживает начальную и конечную позиции элемента, обеспечивая плавную анимацию и сохранение структуры сетки.


Настройка ограничений движения

Перетаскиваемые элементы можно ограничивать по направлениям движения и контейнерам.

const grid = new Muuri('.grid', {
  dragEnabled: true,
  dragSort: true, // Позволяет сортировать элементы внутри сетки
  dragSortHeuristics: {
    sortInterval: 50,
    minDragDistance: 10,
    minBounceBackAngle: 1
  },
  dragAxis: 'xy' // 'x', 'y' или 'xy' — направление движения
});
  • dragAxis — ограничивает движение по указанной оси.
  • dragSort — позволяет автоматически переставлять элементы внутри одной или нескольких сеток при перетаскивании.
  • dragSortHeuristics — параметры, влияющие на чувствительность и логику сортировки при движении элементов.

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


События перемещения

Muuri предоставляет обширный набор событий, которые позволяют отслеживать процесс перетаскивания и выполнять действия на каждом этапе.

Основные события:

  • dragStart — срабатывает при начале перетаскивания элемента.
  • dragMove — вызывается на каждом шаге движения.
  • dragEnd — срабатывает при завершении перетаскивания, после того как элемент возвращается на своё место или вставляется в новую позицию.
  • move — вызывается после того, как элемент завершил анимацию перемещения в сетке.

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

grid.on('dragStart', (item) => {
  item.getElement().style.border = '2px dashed #333';
});

grid.on('dragEnd', (item) => {
  item.getElement().style.border = '';
});

Важно: Событие dragEnd вызывается после завершения анимации, что позволяет синхронизировать внешние данные или обновлять состояние интерфейса.


Программное управление перемещением

Muuri позволяет не только перетаскивать элементы мышью, но и управлять их позицией через код.

const item = grid.getItem(element); // Получение объекта элемента

// Перемещение элемента на новую позицию в сетке
grid.move(item, 3); // Перемещает элемент на индекс 3

Метод move автоматически выполняет анимацию и перестраивает сетку, сохраняя плавность интерфейса. Для более сложных сценариев можно использовать grid.sort() или grid.filter() для реорганизации элементов с учётом их порядка или категории.


Перетаскивание между несколькими сетками

Muuri поддерживает drag-and-drop между сетками, что полезно для канбан-досок или фильтруемых списков.

const gridA = new Muuri('.grid-a', { dragEnabled: true });
const gridB = new Muuri('.grid-b', { dragEnabled: true });

[gridA, gridB].forEach(grid => {
  grid.on('dragReleaseEnd', (item) => {
    item.getGrid().refreshItems().layout();
  });
});

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

  • Элемент сохраняет свои данные при перемещении между сетками.
  • Можно ограничивать перемещение только между определёнными сетками с помощью dragContainer и dragSort.
  • Muuri автоматически управляет анимацией входа и выхода элемента из контейнера.

Настройка пользовательской анимации

Анимация перемещения элементов настраивается через опции layout и dragSort:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layout: {
    duration: 400, // Длительность анимации в мс
    easing: 'ease' // Функция плавности анимации
  },
  dragSortDuration: 300,
  dragSortEasing: 'cubic-bezier(0.25, 1, 0.5, 1)'
});
  • duration и dragSortDuration задают время анимации для перестановки и сортировки соответственно.
  • easing и dragSortEasing контролируют кривую ускорения, влияя на ощущение движения.

Отслеживание изменений позиции элементов

После завершения перемещения может потребоваться синхронизация данных. Для этого удобно использовать событие move:

grid.on('move', (items) => {
  items.forEach((item, index) => {
    console.log(`Элемент ${item.getElement().textContent} теперь на позиции ${index}`);
  });
});

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


Дополнительные возможности перемещения

  • Locking — блокировка конкретных элементов от перемещения.
  • Drag handles — назначение части элемента для начала перетаскивания.
  • Constraints — ограничение зоны движения элемента внутри контейнера или за его пределами.
grid.getItems().forEach(item => {
  item.getElement().querySelector('.handle').addEventListener('mousedown', (e) => {
    grid.dragStart(item, e);
  });
});

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


Muuri обеспечивает полный контроль над процессом перемещения, от включения drag-and-drop до тонкой настройки анимации, сортировки и взаимодействия между несколькими сетками. С его помощью можно реализовать динамичные интерфейсы с плавной визуализацией перестановки элементов и полной синхронизацией данных.