Мультитач

Interact.js предоставляет мощный набор инструментов для работы с мультитач-событиями, позволяя отслеживать несколько точек касания одновременно. Основной принцип работы с мультитач — это использование объекта InteractEvent, который содержит массив touches. Каждый элемент этого массива представляет собой отдельную точку касания с координатами clientX, clientY и дополнительными данными, такими как identifier и target.

interact('.draggable')
  .draggable({
    listeners: {
      move(event) {
        const touches = event.touches;
        for (let i = 0; i < touches.length; i++) {
          const t = touches[i];
          console.log(`Точка ${i}: x=${t.clientX}, y=${t.clientY}`);
        }
      }
    },
    maxPointers: 2
  });

Ключевой момент: свойство maxPointers ограничивает количество точек касания, одновременно влияющих на объект. Например, установка maxPointers: 2 позволяет объекту реагировать только на двухпальцевые жесты.


Работа с жестами

Interact.js поддерживает базовые мультитач-жесты, такие как масштабирование (pinch) и вращение (rotate). Для их использования необходимо подключить модуль gesturable() к элементу. Объект события GestureEvent предоставляет свойства scale и rotation, которые отражают текущие изменения между точками касания.

interact('.gesturable')
  .gesturable({
    listeners: {
      move(event) {
        event.target.style.transform =
          `scale(${event.scale}) rotate(${event.rotation}deg)`;
      }
    }
  });
  • event.scale — коэффициент масштабирования относительно начального состояния.
  • event.rotation — угол поворота в градусах относительно начальной позиции.

Особенность: значение event.delta позволяет определить, насколько изменилась величина жеста за один кадр события.


Координация нескольких касаний

Для сложных интерфейсов часто требуется различать касания разных пальцев. event.touches содержит уникальные идентификаторы identifier, которые позволяют отслеживать каждый палец отдельно.

interact('.multi-touch')
  .draggable({
    listeners: {
      move(event) {
        event.touches.forEach(touch => {
          console.log(`Палец ${touch.identifier}: x=${touch.clientX}, y=${touch.clientY}`);
        });
      }
    },
    maxPointers: 5
  });

Совет по организации кода: хранение состояния каждой точки касания в отдельной структуре данных упрощает создание жестов типа “раздвижение двумя пальцами”, “вращение” или “перетаскивание нескольких объектов одновременно”.


Ограничения и оптимизация

  • Количество касаний: мобильные устройства обычно поддерживают от 5 до 10 одновременных касаний. Установка слишком большого maxPointers может привести к снижению производительности.
  • События pointerdown, pointermove, pointerup: Interact.js автоматически агрегирует их в мультитач-события, что снимает необходимость вручную обрабатывать каждый touchstart и touchend.
  • Оптимизация анимации: для плавного масштабирования и вращения рекомендуется использовать requestAnimationFrame или CSS-переходы вместо прямого изменения style внутри обработчика события.

Примеры сложных мультитач-жестов

1. Масштабирование и перетаскивание одновременно

interact('.combined')
  .draggable({ maxPointers: 2 })
  .gesturable({
    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) scale(${event.scale}) rotate(${event.rotation}deg)`;

        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);
      }
    }
  });

2. Отслеживание нескольких объектов

interact('.multi-object')
  .draggable({
    maxPointers: 3,
    listeners: {
      move(event) {
        const id = event.pointerId;
        const dx = event.dx;
        const dy = event.dy;

        event.target.style.transform =
          `translate(${dx}px, ${dy}px)`;
      }
    }
  });

Важные нюансы при разработке

  • Использование touch-action: none в CSS предотвращает стандартное поведение браузера при мультитач-жестах, такое как прокрутка или масштабирование страницы.
  • modifiers позволяют задавать ограничения для мультитач-перемещений: ограничение области перетаскивания, сетку для привязки координат, инерцию и пр.
  • Для мультитач-жестов важно учитывать события pointercancel, которые происходят при неожиданной потере касания (например, при уведомлениях системы).

Резюме по мультитач в Interact.js

  • event.touches и pointerId — ключевые элементы для работы с несколькими касаниями.
  • maxPointers контролирует количество одновременно активных касаний.
  • Модуль gesturable() реализует масштабирование и вращение.
  • Хранение состояния точек касания и использование CSS-переводов обеспечивает плавную и отзывчивую работу интерфейсов.
  • Комбинация draggable() и gesturable() позволяет создавать гибкие мультитач-интерактивные элементы.

Этот подход обеспечивает гибкость и масштабируемость для создания мультитач-интерфейсов в веб-приложениях с использованием Interact.js.