Vanilla JavaScript подход

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


Подключение Interact.js

Для начала необходимо подключить библиотеку. Можно использовать CDN:

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

Или установить через npm:

npm install @interactjs/interactjs

После подключения библиотека доступна через глобальный объект interact.


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

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

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);
    }
  }
});

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

  • event.dx и event.dy — смещения за текущее событие.
  • data-x и data-y — способ хранения текущей позиции элемента.
  • modifiers.restrictRect позволяет ограничить движение заданной областью.

Масштабирование элементов

Interact.js поддерживает изменение размеров элементов через метод resizable():

interact('.resizable').resizable({
  edges: { left: true, right: true, bottom: true, top: true },
  modifiers: [
    interact.modifiers.restrictSize({
      min: { width: 50, height: 50 },
      max: { width: 500, height: 500 }
    })
  ],
  inertia: true,
  listeners: {
    move(event) {
      const target = event.target;
      let x = parseFloat(target.getAttribute('data-x')) || 0;
      let y = parseFloat(target.getAttribute('data-y')) || 0;

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

      x += event.deltaRect.left;
      y += event.deltaRect.top;

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

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

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

Жесты и multi-touch события

Interact.js умеет распознавать пинч и поворот для touch-устройств:

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}) rotate(${event.angle}deg)`;
      target.setAttribute('data-scale', newScale);
    }
  }
});
  • event.ds — изменение масштаба (scale delta).
  • event.angle — текущий угол поворота.
  • Поддержка multi-touch требует браузер с Pointer Events.

Ограничения и модификаторы

Модификаторы позволяют контролировать поведение элементов при drag, resize или gesture:

  • restrictRect — ограничение движения по прямоугольнику.
  • restrictEdges — ограничение краев при ресайзе.
  • restrictSize — минимальные и максимальные размеры.
  • snap — привязка к сетке или линиям.
  • restrictCenter — ограничение центра элемента в пределах области.

Пример привязки к сетке:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.snap({
      targets: [
        interact.snappers.grid({ x: 50, y: 50 })
      ],
      range: Infinity,
      relativePoints: [{ x: 0, y: 0 }]
    })
  ]
});

События Interact.js

Библиотека работает через события с расширенной информацией:

  • dragstart, dragmove, dragend
  • resizestart, resizemove, resizeend
  • gesturestart, gesturemove, gestureend
  • tap, doubletap, hold

Каждое событие содержит объект event с:

  • target — элемент, с которым взаимодействуют
  • dx, dy — смещения
  • rect — размеры и координаты
  • deltaRect — изменения размеров
  • buttons, pointerId, event.type и другие данные

Сочетание drag и resize

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

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

Функции dragMoveListener и resizeMoveListener могут использовать общую систему хранения координат (data-x, data-y) для корректного отображения.


Поддержка старых браузеров и fallback

Interact.js построен на Pointer Events, но поддерживает fallback на mouse и touch события. Это позволяет использовать библиотеку на большинстве современных устройств и браузеров без дополнительной полифилизации.


Рекомендации по структуре кода

  1. Хранение состояния элементов через data-attributes (data-x, data-y, data-scale) — универсальный подход для drag, resize и gesture.
  2. Вынос слушателей в функции для переиспользования кода.
  3. Модификаторы всегда подключать по необходимости, чтобы минимизировать вычислительные затраты.
  4. Комбинировать события аккуратно — drag и resize одновременно могут конфликтовать, если неправильно настроены edges и modifiers.

Interact.js с Vanilla JavaScript позволяет строить комплексные интерактивные интерфейсы без использования фреймворков, обеспечивая гибкость в управлении элементами, поддержку touch и multi-touch, а также богатые возможности ограничения и привязки элементов.