Обработка событий касания

Two.js — это мощная библиотека для работы с 2D-графикой на канвасе, SVG и WebGL. Помимо стандартного рендеринга фигур и анимаций, она предоставляет возможности взаимодействия с пользователем через события мыши и касания. События касания особенно важны для мобильных и сенсорных устройств.

Two.js не имеет встроенной системы событий касания, аналогичной DOM-событиям, поэтому обработка touch-событий реализуется через стандартный механизм Jav * aScript: touchstart, touchmove, touchend, привязанный к DOM-элементу, на котором рендерится Two.js.


Привязка событий к холсту Two.js

В Two.js объект two.renderer.domElement представляет собой HTML-элемент канваса (или SVG), на который производится рендеринг. Для обработки касаний используется следующий подход:

const elem = two.renderer.domElement;

elem.addEventListener('touchstart', handleTouchStart, false);
elem.addEventListener('touchmove', handleTouchMove, false);
elem.addEventListener('touchend', handleTouchEnd, false);
  • touchstart — возникает при начале касания.
  • touchmove — возникает при движении пальца по элементу.
  • touchend — возникает при завершении касания.

Каждое событие содержит объект TouchEvent, который хранит массив касаний touches и changedTouches.


Координаты касания

Важный момент — преобразование координат касания в координаты сцены Two.js. Событие touch возвращает координаты относительно окна (clientX, clientY), а холст может иметь смещение и масштаб. Чтобы корректно определить точку касания на сцене:

function getTouchPosition(touch, elem) {
  const rect = elem.getBoundingClientRect();
  return {
    x: touch.clientX - rect.left,
    y: touch.clientY - rect.top
  };
}

Это позволяет правильно позиционировать фигуры и реагировать на касания по их координатам.


Обработка одиночного касания

Для простых интерактивных объектов можно использовать один палец. Например, изменение позиции фигуры при касании:

function handleTouchMove(event) {
  event.preventDefault(); // предотвращает прокрутку страницы
  const touch = event.touches[0];
  const pos = getTouchPosition(touch, two.renderer.domElement);
  
  circle.translation.set(pos.x, pos.y);
}

Здесь circle — объект Two.js (Two.Circle). Метод translation.set(x, y) перемещает объект на новые координаты.


Обработка множественных касаний

Two.js можно адаптировать для поддержки нескольких касаний, что актуально для жестов:

function handleTouchMove(event) {
  event.preventDefault();
  for (let i = 0; i < event.touches.length; i++) {
    const touch = event.touches[i];
    const pos = getTouchPosition(touch, two.renderer.domElement);
    
    // Можно сопоставлять касания с объектами по индексу
    objects[i].translation.set(pos.x, pos.y);
  }
}

При этом важно хранить соответствие между касаниями (identifier) и объектами сцены, чтобы один палец не перепрыгивал между элементами.


Жесты и мультитач

Для сложных взаимодействий, таких как масштабирование или вращение, используется анализ двух и более касаний:

function getDistance(touch1, touch2) {
  const dx = touch2.x - touch1.x;
  const dy = touch2.y - touch1.y;
  return Math.sqrt(dx * dx + dy * dy);
}

function handlePinch(event) {
  const touch1 = getTouchPosition(event.touches[0], elem);
  const touch2 = getTouchPosition(event.touches[1], elem);

  const distance = getDistance(touch1, touch2);
  const scale = distance / initialDistance;
  object.scale = scale;
}

Здесь initialDistance вычисляется при touchstart, а объект масштабируется пропорционально изменению расстояния между пальцами.


Интеграция с анимацией

Two.js поддерживает анимацию через метод two.update() и встроенный рендер-цикл. Обработчики касания можно интегрировать с анимацией:

two.bind('update', function() {
  // Обновление объектов в реальном времени
}).play();

Изменения, внесённые через касания, автоматически применяются при следующем кадре.


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

  • Использовать event.preventDefault() для предотвращения скролла при touchmove.
  • Ограничивать частоту обработки событий через requestAnimationFrame.
  • Для сложных сцен применять буферизацию объектов и минимизировать пересчёт координат.

Резюме ключевых моментов

  • Two.js использует стандартные DOM touch-события для интерактивности.
  • Необходимо преобразовывать координаты касания в координаты канваса.
  • Поддержка мультитача требует отслеживания identifier касаний.
  • Для жестов типа pinch или rotate анализируются расстояния и углы между касаниями.
  • Интеграция с анимацией позволяет плавно обновлять объекты при взаимодействии.