Адаптация под размеры экрана

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


Использование mirror и масштабирование

При инициализации Draggable можно включить зеркало (mirror), которое создаёт визуальную копию перетаскиваемого элемента. На маленьких экранах важно контролировать размеры зеркала, чтобы оно не перекрывало другие элементы интерфейса.

import { Draggable } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.list-item'), {
  draggable: '.draggable-item',
  mirror: {
    constrainDimensions: true
  }
});
  • constrainDimensions: true — зеркальная копия сохраняет ширину и высоту исходного элемента, что обеспечивает предсказуемое поведение на мобильных устройствах.
  • Можно дополнительно использовать CSS-переменные или медиазапросы для изменения размеров .draggable-mirror в зависимости от ширины экрана.
@media (max-width: 768px) {
  .draggable-mirror {
    transform: scale(0.8);
  }
}

Реакция на изменение окна

Draggable позволяет динамически обновлять позицию элементов при изменении размеров окна. Для этого стоит использовать событие resize:

window.addEventListener('resize', () => {
  draggable.destroy();
  draggable.init();
});
  • destroy() — удаляет текущие слушатели и очищает состояние.
  • init() — заново инициализирует Draggable с актуальными размерами контейнера.
  • Такой подход предотвращает наложение элементов и неправильное определение координат при адаптивной верстке.

Установка ограничений зоны перетаскивания

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

const draggable = new Draggable(document.querySelectorAll('.list-item'), {
  draggable: '.draggable-item',
  containers: [document.querySelector('.list-container')]
});
  • Ограничение контейнера помогает избежать выхода элементов за границы экрана на малых разрешениях.
  • В сочетании с CSS overflow: hidden можно полностью контролировать видимую область перетаскивания.

Использование медиазапросов для разных сценариев перетаскивания

На больших экранах часто используется горизонтальное или вертикальное перетаскивание, а на мобильных — только вертикальное. Это реализуется через динамическое изменение селектора и опций Draggable:

function initDraggable() {
  const direction = window.innerWidth < 768 ? 'vertical' : 'horizontal';
  
  return new Draggable(document.querySelectorAll('.list-item'), {
    draggable: '.draggable-item',
    axis: direction
  });
}

let draggableInstance = initDraggable();

window.addEventListener('resize', () => {
  draggableInstance.destroy();
  draggableInstance = initDraggable();
});
  • axis — ограничивает движение по одной оси, что упрощает интерфейс на маленьких экранах.
  • Динамическое пересоздание Draggable при изменении размера окна поддерживает согласованное поведение элементов.

Управление размерами через CSS Grid и Flexbox

Draggable не управляет сеткой самостоятельно, поэтому важно правильно организовать контейнер:

.list-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}

@media (max-width: 480px) {
  .list-container {
    grid-template-columns: 1fr;
  }
}
  • minmax позволяет автоматически подстраивать ширину элементов под доступное пространство.
  • На мобильных устройствах изменение сетки предотвращает наложение элементов и улучшает отзывчивость интерфейса при перетаскивании.

Поддержка сенсорных устройств

Draggable автоматически работает с мышью и сенсорными экранами, но для мобильной оптимизации стоит обратить внимание на handle и touch-action:

const draggable = new Draggable(document.querySelectorAll('.list-item'), {
  draggable: '.draggable-item',
  handle: '.drag-handle'
});
.drag-handle {
  touch-action: pan-y;
}
  • handle — задаёт конкретную область для захвата элемента, предотвращая случайные срабатывания.
  • touch-action — оптимизирует жесты, сохраняя плавность перетаскивания и скролла на мобильных устройствах.

Использование событий для адаптивного поведения

Draggable предоставляет обширный набор событий, таких как drag:start, drag:move и drag:stop. Для адаптивного интерфейса можно динамически менять стиль или размер элемента в зависимости от экрана:

draggable.on('drag:start', (evt) => {
  if (window.innerWidth < 768) {
    evt.source.style.width = '90%';
  }
});
  • Подход позволяет создавать интерфейс, где элементы подстраиваются под текущий размер экрана во время перетаскивания.
  • Можно сочетать с анимациями CSS для плавного изменения размеров.

Интеграция с анимационными библиотеками

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

import gsap from 'gsap';

draggable.on('drag:stop', (evt) => {
  gsap.to(evt.source, { duration: 0.3, scale: 1 });
});
  • Анимации могут учитывать размер экрана, создавая эффект “возврата” или плавного перемещения.
  • На мобильных устройствах такие анимации улучшают восприятие интерфейса и предотвращают резкие скачки элементов.

Итоговое оформление адаптивного Draggable

Комбинация:

  • зеркала с сохранением размеров,
  • ограничений контейнера,
  • оси движения через axis,
  • медиазапросов для сетки и стилей,
  • событий для динамических изменений,

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