Синхронизация между холстами

Two.js предоставляет высокоуровневый API для работы с векторной графикой на HTML5 Canvas, SVG и WebGL. При работе с несколькими холстами часто возникает необходимость синхронизировать состояние объектов между ними, чтобы изменения на одном холсте автоматически отражались на других. Это может быть полезно при создании сложных визуализаций, панорам, мультиэкранных интерфейсов или редакторов графики.


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

Для начала создаются отдельные экземпляры Two для каждого холста. Каждый экземпляр управляет своим DOM-элементом (canvas или svg) и имеет независимый рендеринг.

const elem1 = document.getElementById('canvas1');
const elem2 = document.getElementById('canvas2');

const two1 = new Two({ width: 500, height: 500 }).appendTo(elem1);
const two2 = new Two({ width: 500, height: 500 }).appendTo(elem2);

Каждый экземпляр имеет собственный метод update и цикл анимации. Синхронизация потребует передачи состояния объектов из одного экземпляра в другой.


Копирование объектов между холстами

Two.js использует объекты Shape, Group, Path и т.д. для представления графических элементов. Чтобы синхронизировать объекты, их свойства нужно копировать или связывать.

Простейший способ — клонирование:

function cloneShape(shape) {
  const clone = shape.constructor(shape.vertices ? shape.vertices.map(v => v.clone()) : []);
  clone.fill = shape.fill;
  clone.stroke = shape.stroke;
  clone.linewidth = shape.linewidth;
  clone.translation.copy(shape.translation);
  clone.rotation = shape.rotation;
  clone.scale = shape.scale;
  return clone;
}

const circle1 = two1.makeCircle(100, 100, 50);
const circle2 = cloneShape(circle1);
two2.add(circle2);
two1.update();
two2.update();

Важно сохранять позицию, цвет, размер, трансформации, иначе визуальная копия будет отличаться.


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

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

circle1.translation.bind(Two.Events.change, () => {
  circle2.translation.copy(circle1.translation);
  two2.update();
});

Можно создать функцию bindShapes для универсальной привязки всех свойств:

function bindShapes(source, target, props = ['translation', 'rotation', 'scale']) {
  props.forEach(prop => {
    if (source[prop] && target[prop]) {
      source[prop].bind(Two.Events.change, () => {
        target[prop].copy(source[prop]);
        target._renderer.flagReset = true;
      });
    }
  });
}

Это позволяет поддерживать динамическую синхронизацию даже при анимации объектов.


Групповая синхронизация

Для сложных сцен часто используются группы (Group). Синхронизация группы требует копирования всех дочерних объектов и привязки их свойств:

const group1 = two1.makeGroup(circle1, two1.makeRectangle(200, 200, 100, 50));
const group2 = two2.makeGroup();

group1.children.forEach(child => {
  const clone = cloneShape(child);
  group2.add(clone);
  bindShapes(child, clone);
});

two1.update();
two2.update();

Группы позволяют легко управлять несколькими объектами одновременно, сохраняя структуру сцены при синхронизации.


Синхронизация анимации

При использовании Two.js для анимаций (two.bind('update', callback)) важно синхронизировать не только статические свойства, но и вычисляемые параметры:

two1.bind('update', (frameCount, timeDelta) => {
  circle1.rotation += 0.01;
  circle2.rotation = circle1.rotation;
});

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

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


Оптимизация синхронизации

  • Избегать частого клонирования: создавать объекты один раз и обновлять их свойства.
  • Использовать методы copy и clone для векторов и трансформаций вместо полной пересоздания объектов.
  • Ограничивать количество обновлений: не вызывать two.update() на каждом кадре для всех холстов, если достаточно периодической синхронизации.
  • Использовать группы для комплексных сцен: упрощает синхронизацию больших наборов объектов.

Применение в реальных проектах

Синхронизация холстов полезна при:

  • Мультиэкранных визуализациях, где один источник анимации управляет всеми дисплеями.
  • Интерактивных редакторах, где несколько представлений сцены показывают один и тот же объект (вид сверху, изометрия, детали).
  • Совместных редакторах, где изменения одного пользователя мгновенно отображаются на других холстах.

Эти методы создают живую связь между независимыми экземплярами Two.js, позволяя строить сложные визуальные системы с единым управлением.