Packery — это мощная библиотека для создания динамических сеток с возможностью перетаскивания элементов. Одной из ключевых задач при работе с интерактивными сетками является ограничение области, в пределах которой элементы могут перемещаться. Это позволяет избежать наложения на неподходящие зоны страницы, сохранить визуальную целостность интерфейса и улучшить пользовательский опыт.
draggablePackery использует Draggabilly или встроенный
механизм перетаскивания. Для ограничения области движения необходимо
работать с опцией containment. При инициализации
Draggabilly для элемента можно задать:
var gridItem = document.querySelector('.grid-item');
var draggie = new Draggabilly(gridItem, {
containment: '.grid-container'
});
Здесь containment указывает CSS-селектор или
DOM-элемент, внутри которого элемент будет ограничен. Если указать
родительский контейнер сетки, перемещение за его пределы будет
невозможно.
Когда Packery инициализируется с поддержкой перетаскивания:
var grid = document.querySelector('.grid');
var pckry = new Packery(grid, {
itemSelector: '.grid-item',
gutter: 10
});
var itemElems = grid.querySelectorAll('.grid-item');
itemElems.forEach(function(itemElem) {
var draggie = new Draggabilly(itemElem, {
containment: grid
});
pckry.bindDraggabillyEvents(draggie);
});
Ключевой момент: привязка Draggabilly к элементу
через bindDraggabillyEvents позволяет Packery корректно
перестраивать сетку при перетаскивании, при этом элемент не выходит за
границы контейнера.
Иногда необходимо ограничивать движение элемента не только по границам контейнера, но и по конкретной области, заданной в пикселях или процентах. Для этого можно использовать обработчики событий Draggabilly:
var draggie = new Draggabilly(itemElem);
draggie.on('dragMove', function(event, pointer, moveVector) {
var rect = grid.getBoundingClientRect();
var itemRect = itemElem.getBoundingClientRect();
// Ограничение по X
if (itemRect.left < rect.left) {
draggie.setPosition(rect.left - itemRect.left, 0);
} else if (itemRect.right > rect.right) {
draggie.setPosition(rect.right - itemRect.right, 0);
}
// Ограничение по Y
if (itemRect.top < rect.top) {
draggie.setPosition(0, rect.top - itemRect.top);
} else if (itemRect.bottom > rect.bottom) {
draggie.setPosition(0, rect.bottom - itemRect.bottom);
}
});
Это позволяет создавать сложные ограничения, например, прямоугольные или произвольные области, в которых движение разрешено.
Draggabilly и Packery позволяют ограничивать движение элемента только
по одной оси. Для этого используется опция axis:
var draggie = new Draggabilly(itemElem, {
axis: 'x' // движение только по горизонтали
});
Возможные значения:
'x' — только горизонтальное движение'y' — только вертикальное движениеСовместное использование axis и containment
позволяет полностью контролировать поведение сетки и создавать
интерфейсы с фиксированными линиями движения элементов.
Для простых случаев можно комбинировать Packery с CSS-свойствами контейнера:
.grid-container {
position: relative;
overflow: hidden;
width: 800px;
height: 600px;
}
overflow: hidden предотвращает визуальное выход
элементов за границы контейнера, даже если Draggabilly по ошибке
позволяет их сдвинуть.
Если размеры контейнера или области должны меняться во время работы
страницы, можно обновлять containment для Draggabilly:
function updateContainment() {
var newContainer = document.querySelector('.new-boundary');
draggie.options.containment = newContainer;
}
После изменения Packery автоматически корректирует позиции элементов при следующем перетаскивании, если привязка к Draggabilly сохранена.
bindDraggabillyEvents для корректного перераспределения
сетки.containment для простых ограничений внутри
контейнера.dragMove для сложных или
динамических зон.axis, если сетка имеет
линейное распределение.overflow: hidden.Эти методы обеспечивают точное и надежное управление областью перемещения элементов в сетке Packery, позволяя создавать гибкие и предсказуемые пользовательские интерфейсы.