Перемещение элементов

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

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


Принцип работы механизма перемещения

При перемещении элемента Packery выполняет несколько последовательных операций:

  1. Определение текущего положения элемента.
  2. Расчёт потенциальной новой позиции.
  3. Проверка пересечений с другими элементами.
  4. Перераспределение свободного пространства.
  5. Анимационное перемещение элементов.

Каждый элемент внутри контейнера рассматривается как прямоугольная область. Алгоритм отслеживает свободные участки контейнера и при необходимости перераспределяет элементы, чтобы сохранить плотную компоновку.

Особенности алгоритма:

  • элементы не перекрываются
  • автоматически заполняются пустые области
  • сохраняется логическая структура сетки
  • перемещение может быть анимированным

Перемещение элементов программным способом

Packery предоставляет методы для программного изменения расположения элементов. Один из наиболее важных — shiftLayout.

Этот метод инициирует перерасчёт позиций элементов с учётом новых координат.

Пример базовой инициализации

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

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

После инициализации элементы автоматически размещаются внутри контейнера.


Изменение позиции элемента

Перемещение элемента можно инициировать вручную, изменив его координаты и вызвав перерасчёт layout.

var item = grid.querySelector('.grid-item');

item.style.left = '200px';
item.style.top = '100px';

pckry.shiftLayout();

После вызова shiftLayout() библиотека:

  • обновляет координаты элемента
  • проверяет столкновения
  • перераспределяет остальные элементы

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

Метод fit используется для перемещения элемента в определённую позицию контейнера.

Синтаксис:

pckry.fit( element, x, y );

Параметры:

Параметр Описание
element перемещаемый DOM-элемент
x координата X
y координата Y

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

var item = grid.querySelector('.grid-item');

pckry.fit(item, 300, 150);

После выполнения:

  • элемент перемещается к координатам (300,150)
  • остальные элементы перестраиваются
  • сетка автоматически оптимизируется

Перемещение элементов при изменении размера

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

Пример изменения размера:

var item = grid.querySelector('.grid-item');

item.style.width = '200px';

pckry.layout();

Метод layout():

  • анализирует новые размеры элементов
  • пересчитывает сетку
  • перемещает блоки в доступные области

Перемещение элементов с помощью Drag & Drop

Одно из наиболее распространённых применений Packery — создание интерфейсов с перетаскиванием элементов.

Для этого используется интеграция с библиотекой Draggabilly.


Подключение Drag & Drop

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

var items = document.querySelectorAll('.grid-item');

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

  pckry.bindDraggabillyEvents(draggie);
});

После привязки событий:

  • элемент можно захватить мышью
  • перемещать внутри контейнера
  • Packery автоматически перестраивает сетку

Обработка столкновений элементов

При перемещении одного элемента Packery проверяет пересечение с другими элементами.

Алгоритм выполняет:

  1. проверку границ контейнера
  2. поиск пересечений
  3. перемещение конфликтующих элементов
  4. перераспределение пространства

Если элемент занимает позицию, где уже находится другой элемент, библиотека:

  • сдвигает соседние элементы
  • ищет ближайшее свободное место
  • перестраивает сетку

Это создаёт эффект «живой» сетки, где элементы автоматически перемещаются при изменениях.


Ограничение области перемещения

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

Packery автоматически ограничивает область движения размерами родительского контейнера. Однако дополнительные ограничения можно реализовать через настройки Drag & Drop.

Пример:

var draggie = new Draggabilly(item, {
  containment: '.grid'
});

Опция containment:

  • ограничивает перемещение внутри контейнера
  • предотвращает выход элементов за границы сетки

Анимация перемещения

При изменении позиции Packery использует CSS-трансформации для плавного перемещения элементов.

Преимущества такого подхода:

  • высокая производительность
  • использование GPU-ускорения
  • плавные переходы

Пример CSS:

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

При перестройке layout элементы перемещаются анимировано.


Отслеживание событий перемещения

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

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

Событие Описание
layoutComplete завершение перестройки сетки
dragItemPositioned завершение перемещения элемента
fitComplete завершение метода fit

Пример подписки на событие

pckry.on('dragItemPositioned', function(item){
  console.log('Элемент перемещён', item.element);
});

Это позволяет:

  • обновлять состояние интерфейса
  • сохранять положение элементов
  • синхронизировать данные с сервером

Сохранение позиции элементов

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

Пример сохранения координат:

pckry.on('dragItemPositioned', function(){

  var positions = [];

  pckry.items.forEach(function(item){
    positions.push({
      id: item.element.dataset.id,
      x: item.rect.x,
      y: item.rect.y
    });
  });

  localStorage.setItem('layout', JSON.stringify(positions));

});

При загрузке страницы можно восстановить позиции:

var saved = JSON.parse(localStorage.getItem('layout'));

После этого координаты применяются к элементам и выполняется перерасчёт layout.


Перемещение при динамическом добавлении элементов

При добавлении новых элементов Packery автоматически перераспределяет сетку.

var newItem = document.createElement('div');
newItem.classList.add('grid-item');

grid.appendChild(newItem);

pckry.appended(newItem);

Метод appended():

  • добавляет элемент в систему Packery
  • рассчитывает его позицию
  • перемещает соседние элементы

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

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

Минимизация перерасчётов

Перерасчёт layout следует вызывать только при необходимости.

Использование CSS transform

Packery перемещает элементы через transform, что снижает нагрузку на reflow.

Групповые обновления

Если происходит несколько изменений:

pckry.reloadItems();
pckry.layout();

Это позволяет обновить сетку одной операцией.


Особенности поведения перемещений

При работе с Packery важно учитывать несколько особенностей:

  • порядок элементов в DOM не всегда совпадает с визуальным порядком
  • координаты рассчитываются относительно контейнера
  • перемещение может вызывать цепную реакцию перестроения сетки
  • размеры элементов влияют на свободное пространство

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