Ориентация экрана

Библиотека Muuri предоставляет гибкий способ организации сетки элементов с возможностью динамической перестройки при изменении размеров контейнера. Одной из ключевых задач в адаптивном дизайне является корректная работа сетки при изменении ориентации экрана — переходе между портретной и ландшафтной ориентацией. Muuri позволяет управлять этим через наблюдение за изменениями размеров контейнера и перерасчет расположения элементов.


Событие изменения размеров окна

Muuri не отслеживает напрямую ориентацию устройства, но реагирует на изменения размеров контейнера, что косвенно позволяет работать с ориентацией. Для этого используется стандартное событие resize объекта window:

window.addEventListener('resize', () => {
  grid.refreshItems().layout();
});
  • refreshItems() — обновляет информацию о каждом элементе сетки (например, размеры и положение).
  • layout() — пересчитывает расположение элементов после обновления.

Такой подход гарантирует, что сетка автоматически перестроится при повороте устройства.


Определение ориентации экрана

Для реализации специфической логики при смене ориентации может понадобиться определение текущей ориентации:

function isPortrait() {
  return window.innerHeight > window.innerWidth;
}

function isLandscape() {
  return window.innerWidth > window.innerHeight;
}

Это позволяет менять параметры сетки или стили элементов в зависимости от ориентации:

if (isPortrait()) {
  grid.getItems().forEach(item => {
    item.getElement().style.width = '100%';
  });
} else {
  grid.getItems().forEach(item => {
    item.getElement().style.width = '48%';
  });
}
grid.refreshItems().layout();

Настройка сетки для адаптивного поведения

Muuri поддерживает кастомные ширины и высоты элементов через опции layout и CSS, что особенно важно при портретной и ландшафтной ориентации:

const grid = new Muuri('.grid', {
  layout: {
    rounding: false,
    fillGaps: true
  }
});
  • rounding — отключение округления координат, чтобы избежать накопления погрешностей при частых изменениях размеров.
  • fillGaps — автоматическое заполнение пустот в сетке после перестройки элементов.

Оптимизация при частых изменениях

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

let resizeTimeout;
window.addEventListener('resize', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    grid.refreshItems().layout();
  }, 150);
});

Это снижает нагрузку на рендеринг и предотвращает мерцание элементов.


Динамическое изменение количества колонок

В Muuri можно динамически управлять количеством колонок через CSS-свойства сетки, что особенно важно при портретной и ландшафтной ориентации:

.grid {
  display: flex;
  flex-wrap: wrap;
}

.grid-item {
  flex: 1 1 calc(50% - 10px); /* две колонки */
  margin: 5px;
}

@media (max-width: 600px) {
  .grid-item {
    flex: 1 1 100%; /* одна колонка для маленьких экранов */
  }
}

После изменения CSS свойств требуется перерасчет сетки:

grid.refreshItems().layout();

Использование методов Muuri для адаптивности

  • grid.add() / grid.remove() — позволяют динамически добавлять или удалять элементы при изменении ориентации.
  • grid.sort() / grid.filter() — изменяют порядок отображения элементов или скрывают их, чтобы адаптировать сетку под новую ориентацию.
  • grid.on('layoutEnd', callback) — событие окончания перестройки сетки, полезно для анимаций при смене ориентации.

Итоговые рекомендации

  • Все операции, связанные с изменением размеров элементов или их количества, следует сопровождать вызовом refreshItems().layout().
  • Для уменьшения нагрузки использовать дебаунс при обработке событий resize.
  • Для мобильных устройств и планшетов ориентироваться на медиазапросы и функции определения ориентации, чтобы управлять количеством колонок и размерами элементов.
  • Использовать fillGaps и rounding: false для более точного и плавного перераспределения элементов при смене ориентации.

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