Автопрокрутка при перетаскивании

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

Настройка автопрокрутки

Автопрокрутка активируется через параметр autoScroll, который можно передавать при создании взаимодействия с элементом:

interact('.draggable')
  .draggable({
    inertia: true,
    autoScroll: true,
    onmove: dragMoveListener
  });

Здесь autoScroll: true включает базовую автопрокрутку. При этом Interact.js автоматически определяет, когда курсор приближается к границе прокручиваемого контейнера или окна, и начинает перемещать содержимое.

Параметры autoScroll

Для более гибкой настройки автопрокрутки используется объект:

interact('.draggable').draggable({
  autoScroll: {
    container: document.getElementById('scroll-container'),
    margin: 50,
    speed: 400,
    interval: 20
  }
});
  • container — элемент DOM, внутри которого будет происходить прокрутка. Если не указан, прокрутка применяется к window.
  • margin — расстояние в пикселях от границы контейнера, при приближении к которой начинается прокрутка.
  • speed — скорость прокрутки в пикселях в секунду. Высокие значения ускоряют движение, низкие делают прокрутку плавной.
  • interval — частота обновления прокрутки в миллисекундах. Уменьшение интервала делает движение более отзывчивым, увеличение снижает нагрузку на браузер.

Пример прокрутки внутри контейнера

<div id="scroll-container" style="overflow: auto; width: 400px; height: 300px;">
  <div class="draggable" style="width: 50px; height: 50px; background: red;"></div>
</div>
interact('.draggable').draggable({
  inertia: true,
  autoScroll: {
    container: document.getElementById('scroll-container'),
    margin: 30,
    speed: 300,
    interval: 20
  },
  onmove: function (event) {
    const target = event.target;
    const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
    const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

    target.style.transform = `translate(${x}px, ${y}px)`;
    target.setAttribute('data-x', x);
    target.setAttribute('data-y', y);
  }
});

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

Автопрокрутка окна браузера

Если необходимо, чтобы при перетаскивании элемент инициировал прокрутку всей страницы, можно опустить параметр container:

interact('.draggable').draggable({
  inertia: true,
  autoScroll: {
    margin: 50,
    speed: 400
  },
  onmove: dragMoveListener
});

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

Настройка направлений прокрутки

Interact.js позволяет ограничивать направления прокрутки, используя свойство axis внутри draggable:

interact('.draggable').draggable({
  axis: 'y', // автопрокрутка только по вертикали
  autoScroll: {
    container: document.getElementById('scroll-container'),
    margin: 20,
    speed: 200
  },
  onmove: dragMoveListener
});
  • axis: 'x' — только горизонтальное перемещение и прокрутка.
  • axis: 'y' — только вертикальное перемещение и прокрутка.
  • axis: 'xy' (по умолчанию) — свободное перемещение и прокрутка в обеих осях.

Динамическая регулировка скорости прокрутки

Скорость автопрокрутки может изменяться в зависимости от расстояния курсора до края контейнера:

autoScroll: {
  container: document.getElementById('scroll-container'),
  margin: 50,
  speed: function (pointer, container) {
    const distance = Math.min(
      pointer.y - container.getBoundingClientRect().top,
      container.getBoundingClientRect().bottom - pointer.y
    );
    return Math.max(100, 500 - distance * 5);
  }
}

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

Ограничения и особенности

  • Автопрокрутка срабатывает только при активном событии drag.
  • Если контейнер имеет overflow: hidden, прокрутка работать не будет.
  • При использовании вложенных прокручиваемых контейнеров Interact.js выбирает ближайший доступный контейнер.
  • При высоких значениях скорости возможны резкие скачки — рекомендуется сочетать с плавными CSS-переходами или небольшими интервалами обновления.

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

  1. Не устанавливать слишком низкий interval, если элементов много или сложная анимация — это увеличивает нагрузку на рендеринг.
  2. Использовать requestAnimationFrame для расчета перемещений и обновления стилей, если требуется высокая отзывчивость.
  3. Ограничивать область автопрокрутки через margin для предотвращения случайного прокручивания при малых движениях курсора.

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