Инструменты браузера

Interact.js — это мощная библиотека для управления взаимодействиями с элементами DOM, включая перетаскивание (drag), изменение размеров (resize), масштабирование (gestures) и обработку событий касаний. Она позволяет создавать сложные интерактивные интерфейсы без глубокого погружения в низкоуровневую работу с событиями мыши и сенсорных устройств.

Для начала необходимо подключить библиотеку к проекту:

<script src="https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js"></script>

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


Настройка перетаскивания элементов

Перетаскивание реализуется с помощью метода interact(target).draggable(options):

interact('.draggable')
  .draggable({
    inertia: true,
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ],
    autoScroll: true,
    listeners: {
      move(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);
      }
    }
  });

Ключевые моменты:

  • inertia: true добавляет эффект инерции при отпускании элемента.
  • Модификаторы restrictRect позволяют ограничить область перемещения.
  • autoScroll: true обеспечивает прокрутку контейнера при перетаскивании к его границам.
  • Объект event содержит смещения dx, dy и целевой элемент target.

Изменение размеров элементов

Interact.js поддерживает изменение размеров с помощью метода resizable:

interact('.resizable')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    modifiers: [
      interact.modifiers.restrictSize({
        min: { width: 100, height: 50 },
        max: { width: 500, height: 500 }
      })
    ],
    inertia: true,
    listeners: {
      move(event) {
        const target = event.target;
        let { width, height } = event.rect;

        target.style.width = `${width}px`;
        target.style.height = `${height}px`;

        const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.deltaRect.left;
        const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.deltaRect.top;

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

Особенности:

  • edges определяет, с каких сторон элемента возможно изменение размеров.
  • restrictSize гарантирует минимальные и максимальные размеры.
  • event.rect содержит текущие ширину и высоту.
  • event.deltaRect учитывает сдвиг при изменении размеров, позволяя корректно изменять позицию элемента.

Масштабирование и мультитач-жесты

Interact.js поддерживает мультитач и жесты:

interact('.gesturable')
  .gesturable({
    listeners: {
      move(event) {
        const target = event.target;
        const currentScale = parseFloat(target.getAttribute('data-scale')) || 1;
        const newScale = currentScale * (1 + event.ds);

        target.style.transform = `scale(${newScale})`;
        target.setAttribute('data-scale', newScale);
      }
    }
  });

Пояснения:

  • event.ds — относительное изменение масштаба за один шаг жеста.
  • Использование атрибутов data-scale позволяет сохранять текущее состояние элемента.
  • Можно комбинировать gesturable с draggable и resizable для создания интерактивных карточек и элементов интерфейса.

Комбинированные взаимодействия

Interact.js позволяет объединять перетаскивание, изменение размеров и жесты на одном элементе:

interact('.interactive')
  .draggable({ listeners: { move: dragMoveListener } })
  .resizable({ edges: { left: true, right: true, bottom: true, top: true }, listeners: { move: resizeMoveListener } })
  .gesturable({ listeners: { move: gestureMoveListener } });

function dragMoveListener(event) { /* обработка drag */ }
function resizeMoveListener(event) { /* обработка resize */ }
function gestureMoveListener(event) { /* обработка gestures */ }

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


Ограничение областей и сетки

Interact.js предоставляет модификаторы для управления поведением элементов:

  • restrictRect — ограничение перемещения или изменения размеров элементом.
  • snap — привязка к сетке или определенным координатам:
interact('.snap-element')
  .draggable({
    modifiers: [
      interact.modifiers.snap({
        targets: [
          interact.snappers.grid({ x: 50, y: 50 })
        ],
        range: Infinity,
        relativePoints: [{ x: 0, y: 0 }]
      })
    ],
    listeners: { move: dragMoveListener }
  });
  • snap позволяет создавать сетку 50x50 px, к которой элемент будет прилипать при перемещении.

События и их обработка

Interact.js поддерживает множество событий:

  • dragstart, dragmove, dragend — события перетаскивания.
  • resizestart, resizemove, resizeend — события изменения размеров.
  • gesturestart, gesturemove, gestureend — события жестов.
  • tap, doubletap, hold — события касаний и кликов.
interact('.draggable')
  .on('dragstart', event => console.log('Начало перетаскивания'))
  .on('dragend', event => console.log('Конец перетаскивания'));

Эти события позволяют интегрировать Interact.js с любыми пользовательскими логиками или внешними библиотеками.


Работа с сенсорными устройствами

Interact.js автоматически обрабатывает события мыши и касания, включая мультитач на мобильных устройствах. Для корректного взаимодействия важно:

  • Использовать preventDefault в обработчиках, если требуется отключить стандартное поведение браузера.
  • Проверять совместимость с pointerEvents, так как библиотека использует их для унификации мыши и сенсорного ввода.

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

Для сложных интерфейсов с множеством интерактивных элементов следует:

  • Ограничивать количество модификаторов на элемент.
  • Использовать requestAnimationFrame внутри слушателей при сложной анимации.
  • Применять interact.dynamicDrop(true) для динамических областей, чтобы избежать лишних вычислений при каждом движении.

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