Архитектура библиотеки

Two.js — это легковесная библиотека для работы с двумерной графикой в JavaScript, предоставляющая высокоуровневый API для создания и анимации векторных объектов. Основная цель архитектуры библиотеки — абстрагировать низкоуровневую работу с DOM, Canvas и SVG, предоставляя единый интерфейс для создания графики.

Основные компоненты

1. Двигатель рендеринга (Renderer) Two.js использует концепцию рендерера, который инкапсулирует логику отрисовки объектов на выбранной платформе. Существует три типа рендереров:

  • Canvas Renderer — отрисовка через <canvas>. Подходит для динамичных сцен с большим количеством объектов.
  • SVG Renderer — создаёт векторную графику в DOM, сохраняя масштабируемость и возможность стилизации через CSS.
  • WebGL Renderer (экспериментальный) — ускоренная отрисовка с использованием GPU, применима для сложных анимаций.

Рендерер хранит ссылки на все объекты сцены и управляет циклом отрисовки.

2. Сцена (Scene) Сцена в Two.js представляет собой контейнер для всех графических элементов. Она управляет иерархией объектов, обеспечивает правильное позиционирование и трансформации. Каждый объект сцены может иметь родителя и потомков, что позволяет строить сложные композиции.

3. Объекты (Elements) Основные строительные блоки Two.js:

  • Primitives — простейшие фигуры: Rectangle, Circle, Ellipse, Polygon, Line.
  • Paths — кривые и сложные контуры с поддержкой Bezier и сглаживания.
  • Groups — объединение нескольких объектов для совместных трансформаций и управления свойствами.

Каждый объект обладает набором свойств состояния, включая position, rotation, scale, stroke, fill и opacity. Изменения этих свойств автоматически отражаются при следующем вызове рендера.

4. Материалы и стили (Styles) Two.js не использует концепцию материалов как в 3D-библиотеках, но предоставляет мощный механизм управления стилями объектов. Можно устанавливать свойства:

  • fill — цвет заливки
  • stroke — цвет контура
  • linewidth — толщина линии
  • opacity — прозрачность

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

Цикл рендеринга

Two.js применяет двухуровневую архитектуру обновления:

  1. Обновление состояния объектов При изменении свойств объектов Two.js обновляет внутренние матрицы трансформаций. Это позволяет избежать непосредственного пересчёта координат при каждой операции с объектом.

  2. Отрисовка Рендерер перебирает все элементы сцены и визуализирует их на выбранной платформе (Canvas, SVG или WebGL). Two.js оптимизирует процесс, выполняя минимальные перерисовки, что повышает производительность.

Для анимации Two.js использует встроенный таймер, который вызывает метод update() сцены на каждом кадре. Это позволяет плавно изменять свойства объектов через ключевые кадры или вручную обновляя значения свойств.

Система трансформаций

Каждый объект имеет собственную матрицу трансформаций, которая включает в себя:

  • Перемещение (translation)
  • Вращение (rotation)
  • Масштаб (scale)

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

Поддержка событий

Two.js поддерживает базовую систему событий через подписку на изменение свойств объектов. Возможности включают:

  • change — триггер при любом изменении свойства объекта
  • insert / remove — уведомление о добавлении или удалении объекта из сцены

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

Архитектура расширяемости

Two.js проектируется с учетом расширяемости:

  • Можно создавать собственные примитивы и группы, наследуя базовый класс Two.Element.
  • Рендереры имеют унифицированный API, что позволяет добавлять новые платформы или оптимизации без изменения основной логики библиотеки.
  • Поддержка плагинов и модулей анимации через цепочку Two.bind позволяет расширять функционал без модификации ядра.

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

Two.js применяет следующие подходы для повышения эффективности:

  • Отложенная отрисовка — объекты рендерятся только при изменении состояния.
  • Матрицы трансформаций — повторное вычисление координат избегается за счёт хранения локальных и глобальных матриц.
  • Групповая обработка — применение трансформаций ко всей группе объектов за один проход.

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