Two.js — это мощная библиотека для создания 2D-графики в браузере на JavaScript. При работе с ней структурирование проекта и грамотная организация кода имеют критическое значение, особенно для крупных анимационных или интерактивных приложений.
Правильная структура помогает отделять логику, визуальные элементы и вспомогательные функции:
/project-root
│
├─ /src
│ ├─ index.js // точка входа
│ ├─ /scenes // сцены и их логика
│ ├─ /objects // графические объекты и их классы
│ ├─ /utils // вспомогательные функции
│ └─ /styles // CSS или другие стили
│
├─ /assets
│ ├─ images
│ └─ fonts
│
├─ index.html
└─ package.json
/src/index.js — инициализация
экземпляра Two.js, подключение сцен и объектов./src/scenes — содержит отдельные
модули для каждой анимации или интерактивного состояния./src/objects — классы для повторно
используемых объектов, например, персонажей, фигур или сложных
графических паттернов./src/utils — функции для
математических вычислений, генерации случайных чисел, работы с цветами и
событиями.Такой подход повышает читаемость и облегчает поддержку кода, особенно когда проект растет.
Создание экземпляра Two.js начинается с указания контейнера и размеров канваса:
import Two from 'two.js';
const elem = document.getElementById('draw-area');
const two = new Two({
width: 800,
height: 600,
type: Two.Types.svg // Можно выбрать 'webgl', 'canvas' или 'svg'
}).appendTo(elem);
Ключевые моменты:
type определяет рендерер, что влияет на
производительность и возможности.width и
height, но их можно динамически обновлять для адаптивного
дизайна.После инициализации Two.js создается основная сцена, в которой будут размещаться объекты:
const circle = two.makeCircle(400, 300, 50);
circle.fill = '#FF8000';
circle.stroke = 'orangered';
circle.linewidth = 5;
two.update();
Каждый графический объект лучше инкапсулировать в отдельный класс:
export class MovingCircle {
constructor(two, x, y, radius, color) {
this.circle = two.makeCircle(x, y, radius);
this.circle.fill = color;
this.speed = Math.random() * 2 + 1;
}
upd ate() {
this.circle.translation.x += this.speed;
if (this.circle.translation.x > 800) {
this.circle.translation.x = 0;
}
}
}
update() отвечает за анимацию, что
отделяет визуальные изменения от логики приложения.Two.js предоставляет метод bind для связывания
обновлений сцены с циклом анимации:
two.bind('update', function(frameCount) {
circles.forEach(circle => circle.update());
}).play();
frameCount используется для синхронизации анимации и
расчета сложных движений.Two.js поддерживает группировку объектов для удобного управления:
const group = two.makeGroup();
group.add(circle1, circle2);
group.translation.se t(100, 50); // Перемещение всей группы
Все математические и вспомогательные функции стоит хранить в отдельном модуле:
export function randomColor() {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return `rgb(${r},${g},${b})`;
}
utils облегчает тестирование и
переиспользование кода.Для больших проектов важно:
Такой подход позволяет расширять проект, добавлять новые сцены, эффекты и объекты без нарушения существующего кода.
Для проектов с изображениями или шрифтами важно использовать асинхронную загрузку:
function loadImage(src) {
return new Promise((resolve) => {
const img = new Image();
img.onl oad = () => resolve(img);
img.src = src;
});
}
async function init() {
const image = await loadImage('assets/images/sprite.png');
const texture = two.makeSprite(image, 400, 300);
}
Two.js интегрируется с DOM-событиями для интерактивности:
two.renderer.domElement.addEventListener('click', (e) => {
const circle = two.makeCircle(e.offsetX, e.offsetY, 30);
circle.fill = randomColor();
});
Эта структура организации кода обеспечивает чистую архитектуру проектов на Two.js, повышает повторное использование компонентов и упрощает поддержку крупных интерактивных приложений.