Инспекция состояния

Interact.js предоставляет мощный набор инструментов для управления интерактивными элементами на странице. Одним из ключевых аспектов работы с библиотекой является инспекция состояния, которая позволяет отслеживать текущие свойства элементов, их позиции, размеры и состояния взаимодействия. Это особенно важно при сложных сценариях drag-and-drop, resize и gesturing, где нужно учитывать текущее положение, скорость перемещения и ограничения элементов.

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


Объект состояния взаимодействия (Interaction)

Основной объект, через который осуществляется инспекция состояния, — это Interaction. Он создаётся автоматически при начале любого взаимодействия с элементом (например, при drag или resize) и содержит следующие ключевые свойства:

  • interaction.target — элемент, с которым осуществляется взаимодействие.

  • interaction.element — текущий DOM-элемент, на котором выполняется операция.

  • interaction.prepared — объект с информацией о том, какой тип действия готовится (drag, resize, gesture).

  • interaction.coords — координаты события:

    • page — координаты относительно страницы.
    • client — координаты относительно видимой области окна.
  • interaction.rect — размеры и позиция элемента в момент события.

  • interaction.pointerIsDown — флаг, показывающий, удерживается ли кнопка мыши или палец на сенсорном устройстве.

  • interaction._events — внутреннее хранилище слушателей событий.

Пример получения состояния взаимодействия:

interact('.draggable').draggable({
  listeners: {
    move(event) {
      console.log(event.interaction.coords.page);
      console.log(event.interaction.target);
    }
  }
});

Здесь event.interaction позволяет получить актуальные данные о перемещении элемента в любой момент времени.


Слежение за положением и размерами элементов

Interact.js позволяет динамически инспектировать размеры и позицию элементов через interaction.rect и через методы, такие как getRect() у Interactable. Эти данные обновляются при каждом событии, связанном с движением или изменением размера.

const element = document.querySelector('.resizable');

interact(element).resizable({
  edges: { left: true, right: true, bottom: true, top: true },
  listeners: {
    move(event) {
      const rect = event.interaction.rect;
      console.log(`Ширина: ${rect.width}, Высота: ${rect.height}`);
      console.log(`Позиция: x=${rect.left}, y=${rect.top}`);
    }
  }
});

Важно помнить, что rect всегда отражает текущую позицию и размеры на странице, учитывая все трансформации, применённые к элементу через CSS.


Использование состояния для динамических ограничений

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

Пример ограничения перемещения по контейнеру:

interact('.draggable').draggable({
  modifiers: [
    interact.modifiers.restrictRect({
      restriction: '.container',
      endOnly: true
    })
  ],
  listeners: {
    move(event) {
      const rect = event.interaction.rect;
      console.log(`Элемент находится внутри контейнера: left=${rect.left}, top=${rect.top}`);
    }
  }
});

Здесь инспекция состояния через event.interaction.rect позволяет корректно отображать текущую позицию относительно контейнера и накладывать ограничения.


Отслеживание событий и состояний

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

  • start — начало взаимодействия. Состояние показывает исходное положение и размеры.
  • move — перемещение или изменение размеров. Состояние обновляется на каждой итерации.
  • end — завершение действия. Состояние фиксируется в финальной позиции.
  • inertiaStart и inertiaMove — события инерции для плавного завершения движения после отпускания элемента.

Пример обработки всех этапов:

interact('.draggable').draggable({
  listeners: {
    start(event) {
      console.log('Начало взаимодействия', event.interaction.coords.page);
    },
    move(event) {
      console.log('Движение', event.interaction.rect);
    },
    end(event) {
      console.log('Завершение', event.interaction.target);
    }
  }
});

Инспекция состояния жестов (Gestures)

Interact.js поддерживает multi-touch жесты, такие как масштабирование и вращение. Состояние жеста хранится в объекте Interaction с указанием:

  • event.ds — изменение масштаба.
  • event.da — изменение угла вращения.
  • event.touches — текущие координаты всех точек касания.

Пример отслеживания pinch-зум и rotation:

interact('.gesturable').gesturable({
  listeners: {
    move(event) {
      console.log(`Масштаб: ${event.ds}, Угол: ${event.da}`);
      console.log('Координаты касаний:', event.touches);
    }
  }
});

Такой подход позволяет создавать сложные интерактивные элементы с полной информацией о состоянии на каждом шаге.


Практические советы по инспекции состояния

  • Использовать interaction.rect вместо getBoundingClientRect, чтобы получать корректные значения с учётом трансформаций.
  • Регулярно проверять флаги pointerIsDown и prepared, чтобы различать активные и завершённые взаимодействия.
  • Комбинировать события move и inertiaMove, чтобы обеспечить плавное отслеживание движения при инерции.
  • Сохранять данные состояния в отдельной структуре, если нужно обращаться к предыдущим координатам для анимаций или вычислений.

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