Обработка событий мыши

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

const elem = document.getElementById('draw-area');
const two = new Two({
  width: 800,
  height: 600,
  type: Two.Types.svg // можно использовать canvas или webgl
}).appendTo(elem);

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


Обработка событий мыши на сцене

Two.js не предоставляет встроенной системы событий для объектов, но можно использовать нативные события DOM на контейнере:

elem.addEventListener('mousedown', (event) => {
  console.log('Нажата кнопка мыши', event.clientX, event.clientY);
});

elem.addEventListener('mousemove', (event) => {
  console.log('Движение мыши', event.clientX, event.clientY);
});

elem.addEventListener('mouseup', (event) => {
  console.log('Отпущена кнопка мыши', event.clientX, event.clientY);
});

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

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

Проверка попадания курсора на фигуры

Чтобы реагировать на клик или наведение на объекты Two.js, нужно реализовать ручной hit-test. Например, для прямоугольника:

const rect = two.makeRectangle(200, 150, 100, 50);
rect.fill = '#FF8000';
rect.noStroke();

function isMouseOverRect(mouse, rect) {
  return mouse.x > rect.position.x - rect.width/2 &&
         mouse.x < rect.position.x + rect.width/2 &&
         mouse.y > rect.position.y - rect.height/2 &&
         mouse.y < rect.position.y + rect.height/2;
}

elem.addEventListener('mousemove', (event) => {
  const mouse = getMousePos(event);
  if (isMouseOverRect(mouse, rect)) {
    rect.fill = '#00FF00';
  } else {
    rect.fill = '#FF8000';
  }
  two.update();
});

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


Перетаскивание объектов

Перетаскивание реализуется через комбинацию событий mousedown, mousemove и mouseup. Пример для прямоугольника:

let selected = null;
let offset = {x:0, y:0};

elem.addEventListener('mousedown', (event) => {
  const mouse = getMousePos(event);
  if (isMouseOverRect(mouse, rect)) {
    selected = rect;
    offset.x = mouse.x - rect.position.x;
    offset.y = mouse.y - rect.position.y;
  }
});

elem.addEventListener('mousemove', (event) => {
  if (selected) {
    const mouse = getMousePos(event);
    selected.position.x = mouse.x - offset.x;
    selected.position.y = mouse.y - offset.y;
    two.update();
  }
});

elem.addEventListener('mouseup', () => {
  selected = null;
});

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


Взаимодействие с несколькими объектами

Для сцены с несколькими фигурами создаётся массив объектов и проверка осуществляется через цикл:

const shapes = [
  two.makeRectangle(100, 100, 80, 40),
  two.makeCircle(300, 200, 50)
];

shapes.forEach(shape => shape.noStroke());

elem.addEventListener('mousemove', (event) => {
  const mouse = getMousePos(event);
  shapes.forEach(shape => {
    if (shape instanceof Two.Rectangle) {
      shape.fill = isMouseOverRect(mouse, shape) ? '#00FF00' : '#FF8000';
    } else if (shape instanceof Two.Circle) {
      const dx = mouse.x - shape.position.x;
      const dy = mouse.y - shape.position.y;
      shape.fill = (dx*dx + dy*dy < shape.radius*shape.radius) ? '#00FF00' : '#FF8000';
    }
  });
  two.update();
});

Такой метод масштабируется на любое количество объектов и позволяет добавлять индивидуальные реакции на события.


Использование событий для анимации

События мыши могут быть интегрированы с анимацией Two.js. Например, плавное приближение к курсору:

const circle = two.makeCircle(400, 300, 30);
circle.fill = '#0080FF';
circle.noStroke();

two.bind('update', () => {
  if (target) {
    circle.position.x += (target.x - circle.position.x) * 0.1;
    circle.position.y += (target.y - circle.position.y) * 0.1;
  }
}).play();

let target = null;
elem.addEventListener('mousemove', (event) => {
  target = getMousePos(event);
});

Такой подход создаёт эффект плавного следования объекта за курсором, добавляя интерактивность сцене.


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

Для расширенного контроля можно использовать библиотеку Hammer.js или Pointer Events. Two.js совместим с этими подходами, что позволяет отслеживать мульти-тач, масштабирование и вращение объектов на сцене, комбинируя события мыши и касания.


Методы обработки событий мыши в Two.js позволяют создавать интерактивные, динамичные сцены, реализовывать перетаскивание, hover-эффекты и анимацию объектов с высокой производительностью, используя нативные DOM-события и вычисления hit-test для фигуры.