Создание нескольких экземпляров Two

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

// Создание первого экземпляра
const two1 = new Two({
  width: 400,
  height: 400,
  type: Two.Types.svg
}).appendTo(document.body);

// Создание второго экземпляра
const two2 = new Two({
  width: 300,
  height: 300,
  type: Two.Types.canvas
}).appendTo(document.body);

Каждый экземпляр создаёт отдельный контекст рендеринга, что позволяет использовать разные размеры, типы рендеринга (svg, canvas, webgl) и сцены, не влияя на другие экземпляры.


Управление сценой каждого экземпляра

Каждый объект Two имеет собственный scene — корневой контейнер, в котором размещаются все графические объекты.

// Создание фигур для первого экземпляра
const circle1 = two1.makeCircle(200, 200, 50);
circle1.fill = '#FF8000';
circle1.stroke = 'black';
circle1.linewidth = 2;

// Создание фигур для второго экземпляра
const rect2 = two2.makeRectangle(150, 150, 100, 50);
rect2.fill = '#0080FF';
rect2.stroke = 'black';
rect2.linewidth = 2;

Каждая фигура привязана к конкретному экземпляру Two, поэтому изменения в circle1 не затрагивают rect2.


Анимация нескольких экземпляров

Two.js использует встроенный метод update() для анимации, а также play() для запуска рендер-цикла. Для нескольких экземпляров анимацию можно организовать независимо:

two1.bind('update', function(frameCount) {
  circle1.rotation += 0.02;
});

two2.bind('update', function(frameCount) {
  rect2.rotation -= 0.03;
});

two1.play();
two2.play();

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


Совмещение экземпляров на одной странице

Несмотря на независимость, экземпляры могут взаимодействовать через DOM или JavaScript-логику. Например, синхронизация движения объектов разных экземпляров:

two1.bind('update', function() {
  rect2.translation.x = circle1.translation.x;
});

two1.play();
two2.play();

Здесь rect2 повторяет горизонтальное перемещение circle1, хотя оба объекта принадлежат разным экземплярам.


Различия в рендеринге и производительности

  • SVG: поддерживает масштабирование без потери качества, но менее эффективен при большом количестве объектов.
  • Canvas: быстрое обновление для динамических сцен, но масштабирование может приводить к размытию.
  • WebGL: оптимален для сложных графических сцен и анимаций с большим количеством объектов.

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


Организация кода при множественных экземплярах

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

function createTwoInstance(width, height, type, container) {
  const two = new Two({ width, height, type }).appendTo(container);
  const circle = two.makeCircle(width / 2, height / 2, 50);
  circle.fill = '#00FF00';
  two.bind('update', () => circle.rotation += 0.01);
  two.play();
  return two;
}

const twoA = createTwoInstance(400, 400, Two.Types.svg, document.body);
const twoB = createTwoInstance(300, 300, Two.Types.canvas, document.body);

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


Взаимодействие событий между экземплярами

События мыши или клавиатуры могут обрабатываться отдельно для каждого экземпляра, если использовать соответствующие DOM-элементы.

twoA.renderer.domElement.addEventListener('click', () => {
  console.log('Clicked on first canvas');
});

twoB.renderer.domElement.addEventListener('click', () => {
  console.log('Clicked on second canvas');
});

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


Принципы масштабирования нескольких экземпляров

  1. Изоляция сцен: каждый экземпляр имеет собственный scene и renderer.
  2. Независимая анимация: bind('update') для каждого объекта работает автономно.
  3. Синхронизация через код: связь между экземплярами возможна через внешние переменные и функции.
  4. Оптимизация рендеринга: комбинирование типов рендеринга (canvas + SVG) позволяет балансировать производительность и визуальное качество.

Эти принципы обеспечивают стабильное управление несколькими экземплярами Two.js на одной веб-странице.