Изменение layout на разных экранах

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

Использование свойства layout и его опций

Свойство layout определяет поведение сетки при изменении размеров контейнера. Оно принимает объект с различными настройками:

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

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

Динамическая перестройка сетки при изменении размеров окна

Muuri предоставляет методы refreshItems() и layout() для перерасчета позиций элементов:

window.addEventListener('resize', () => {
  grid.refreshItems().layout();
});

Однако для более сложной адаптивности нужно использовать условные блоки, чтобы сетка меняла стратегию layout в зависимости от ширины экрана:

function updateLayout() {
  const width = window.innerWidth;
  
  if (width < 600) {
    grid._settings.layout.horizontal = true;
    grid._settings.layout.fillGaps = false;
  } else if (width < 1024) {
    grid._settings.layout.horizontal = false;
    grid._settings.layout.fillGaps = true;
  } else {
    grid._settings.layout.horizontal = false;
    grid._settings.layout.fillGaps = true;
  }

  grid.layout();
}

window.addEventListener('resize', updateLayout);
updateLayout();

Использование медиазапросов для управления layout

Интеграция CSS-медиазапросов с Muuri позволяет оптимизировать визуальные изменения сетки без постоянного прослушивания событий resize. Основная идея — задать CSS-классы для разных размеров экрана и переключать их через JS:

.grid.small-screen .item {
  width: 100%;
}

.grid.medium-screen .item {
  width: 48%;
}

.grid.large-screen .item {
  width: 30%;
}
function setGridClass() {
  const width = window.innerWidth;
  const gridElement = document.querySelector('.grid');
  
  gridElement.classList.remove('small-screen', 'medium-screen', 'large-screen');

  if (width < 600) {
    gridElement.classList.add('small-screen');
  } else if (width < 1024) {
    gridElement.classList.add('medium-screen');
  } else {
    gridElement.classList.add('large-screen');
  }

  grid.layout();
}

window.addEventListener('resize', setGridClass);
setGridClass();

Настройка разных стратегий layout для мобильных и десктопных устройств

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

const mobileLayout = {
  fillGaps: false,
  horizontal: true
};

const desktopLayout = {
  fillGaps: true,
  horizontal: false
};

function switchLayout() {
  if (window.innerWidth < 768) {
    grid._settings.layout = mobileLayout;
  } else {
    grid._settings.layout = desktopLayout;
  }
  grid.layout();
}

window.addEventListener('resize', switchLayout);
switchLayout();

Плавная анимация при изменении layout

Muuri поддерживает анимированное перестроение элементов, что особенно важно при изменении layout на разных экранах. Для этого используются параметры layout.duration и layout.easing:

grid._settings.layout.duration = 400; // миллисекунды
grid._settings.layout.easing = 'ease-in-out';

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

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

  • Минимизировать вызовы layout() на событии resize. Использовать debounce или requestAnimationFrame.
  • Предварительное определение размеров элементов через CSS уменьшает количество пересчетов сетки.
  • Использовать refreshItems() только при изменении DOM. Если изменился только размер контейнера, достаточно layout().
let resizeTimeout;

window.addEventListener('resize', () => {
  clearTimeout(resizeTimeout);
  resizeTimeout = setTimeout(() => {
    switchLayout();
  }, 200);
});

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

Muuri позволяет одновременно использовать адаптивный layout и drag-and-drop. При изменении ширины экрана важно:

  1. Вызвать grid.layout() после изменения layout.
  2. Сохранять позиции элементов через grid.getItems().
  3. При фильтрации применять grid.filter() с последующим grid.layout() для сохранения структуры.

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