Системы координат

Interact.js — это мощная библиотека для управления интерактивными элементами на веб-странице, включая перетаскивание, масштабирование и вращение. Одним из ключевых понятий при работе с этой библиотекой является система координат, в которой оперируют события и положения элементов.

Координаты элемента и страницы

Interact.js различает несколько типов координат:

  1. page coordinates — координаты относительно всей страницы. Они учитывают прокрутку и позиционирование документа. Доступны через свойства события event.pageX и event.pageY. Используются для вычисления абсолютного положения курсора мыши или пальца на странице.

  2. client coordinates — координаты относительно видимой области окна браузера (viewport). Свойства event.clientX и event.clientY дают положение курсора без учёта прокрутки страницы. Полезны для позиционирования элементов относительно видимой области.

  3. screen coordinates — координаты относительно экрана устройства. Свойства event.screenX и event.screenY предоставляют абсолютное положение курсора на экране. Применяются редко, в основном для интеграции с внешними приложениями или системными событиями.

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

Interact.js добавляет свои вычисленные координаты через объект interactEvent, доступный в обработчиках событий dragmove, gesturemove, resizemove:

  • interactEvent.pageX и interactEvent.pageY — положение элемента на странице с учётом смещения от начала страницы.
  • interactEvent.clientX и interactEvent.clientY — положение элемента относительно окна браузера.
  • interactEvent.delta — объект с изменениями координат по осям { x, y } относительно предыдущего события. Позволяет точно отслеживать движение элемента.
  • interactEvent.rect — объект с текущими размерами и координатами элемента: { left, top, right, bottom, width, height }. Используется для вычисления границ и ограничения движения.

Относительные и абсолютные координаты

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

  • Абсолютные координаты — используются при вычислении позиции элемента на странице или при привязке к фиксированной сетке.
  • Относительные координаты — применяются при вычислении смещения элемента относительно его первоначальной позиции или родительского контейнера.

Для установки позиции элемента часто используется CSS-свойство transform: translate(x, y) вместо изменения top и left, что обеспечивает более плавное и оптимизированное перемещение. Interact.js при этом предоставляет interactEvent.dx и interactEvent.dy — приращения по координатам за один шаг движения.

Работа с системами координат при перетаскивании

Событие dragmove передаёт объект события с координатами, которые можно использовать для обновления позиции элемента:

interact('.draggable')
  .draggable({
    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);
      }
    }
  });

В этом примере data-x и data-y используются для хранения текущей позиции элемента. Перемещение происходит относительно исходной точки, что обеспечивает корректную работу даже при многократных событиях dragmove.

Масштабирование и вращение с учётом координат

Interact.js предоставляет поддержку жестов gesturestart, gesturemove, gestureend для работы с масштабированием и вращением. Координаты событий позволяют вычислять центр взаимодействия и применять трансформации относительно этой точки:

  • interactEvent.scale — коэффициент масштабирования, вычисляемый между начальной и текущей точками касания.
  • interactEvent.rotation — угол поворота в градусах, вычисляемый между двумя касаниями.
  • interactEvent.clientX и interactEvent.clientY в этом контексте указывают центр жеста, относительно которого следует применять трансформации.

Применение координат к CSS-трансформациям:

const cx = event.clientX;
const cy = event.clientY;

target.style.transform = `
  translate(${x}px, ${y}px)
  scale(${event.scale})
  rotate(${event.rotation}deg)
`;

Использование центра жеста позволяет элементу масштабироваться и вращаться относительно позиции пальцев или курсора, а не смещать весь элемент непредсказуемо.

Ограничение движения через координаты

Interact.js поддерживает модификаторы для ограничения движения элементов в пределах определённой области:

.interact('.draggable')
  .draggable({
    modifiers: [
      interact.modifiers.restrictRect({
        restriction: 'parent',
        endOnly: true
      })
    ]
  });

Модификатор restrictRect использует координаты rect элемента и родителя для вычисления допустимых границ. Это гарантирует, что при перетаскивании элемент не выйдет за пределы контейнера.

Работа с координатными сетками

Сетка координат (grid) позволяет фиксировать движение элемента на определённых шагах по осям:

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

Координаты события округляются к ближайшей точке сетки, что удобно для интерфейсов с фиксированными позициями элементов.

Системы координат в сложных интерфейсах

В сложных интерфейсах, где элементы находятся внутри вложенных контейнеров с различными трансформациями, важно учитывать:

  • Трансформации родителя (transform, scale, rotate) влияют на локальные координаты дочерних элементов.
  • Для вычисления абсолютной позиции элемента можно использовать метод getBoundingClientRect(), который возвращает координаты относительно окна.
  • Для точного позиционирования внутри родительского контейнера часто приходится конвертировать координаты между системами: от client → page → local offset.

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