В основе работы с графикой в Two.js лежит декартова система координат, где начало (0, 0) располагается в левом верхнем углу холста. Ось X направлена вправо, ось Y — вниз. Все команды перемещения и рисования опираются именно на эту систему.
Каждый графический объект в Two.js представляет собой либо примитив (например, прямоугольник или круг), либо произвольный путь (path), состоящий из набора точек (вершин) и сегментов между ними. Управление перемещением и рисованием осуществляется через изменение координат этих точек и параметров объектов.
Two.js предоставляет базовые методы для создания геометрических фигур:
const two = new Two({ width: 500, height: 500 }).appendTo(document.body);
const rect = two.makeRectangle(100, 100, 50, 50);
const circle = two.makeCircle(200, 200, 25);
two.update();
Координаты (100, 100) и (200, 200) задают
положение центра объектов.
Каждый объект имеет свойство translation, которое
отвечает за его позицию:
rect.translation.set(150, 150);
Это основной способ перемещения объекта без изменения его геометрии.
rect.translation.x += 10;
rect.translation.y += 5;
Такой подход используется при анимации и динамическом перемещении.
Путь — это последовательность точек, соединённых линиями или кривыми. В Two.js путь создаётся с помощью массива вершин:
const path = two.makePath(
50, 50,
150, 50,
150, 150,
50, 150,
true
);
Последний параметр true означает, что путь замкнут.
Каждая вершина в пути — это объект типа Two.Anchor. Он
содержит:
x, y)controls.left,
controls.right)Пример ручного создания пути:
const anchors = [
new Two.Anchor(100, 100),
new Two.Anchor(200, 100),
new Two.Anchor(200, 200),
new Two.Anchor(100, 200)
];
const shape = new Two.Path(anchors, true);
two.add(shape);
two.update();
По умолчанию точки соединяются прямыми линиями. Это аналог команды
lineTo в Canvas API.
Изменение координат вершин приводит к изменению формы:
shape.vertices[0].x = 120;
shape.vertices[0].y = 80;
Two.js поддерживает кривые Безье через управляющие точки:
const anchor = new Two.Anchor(150, 150);
anchor.controls.left.set(-50, 0);
anchor.controls.right.set(50, 0);
Это создаёт плавную кривую между сегментами.
Для включения кривых используется режим:
shape.curved = true;
shape.translation.set(300, 300);
shape.vertices[1].set(220, 120);
shape.vertices.forEach(v => {
v.x += 10;
v.y += 10;
});
Это изменяет саму форму, а не только её положение.
Параметр замыкания влияет на способ рисования:
shape.closed = true; // замкнутый
shape.closed = false; // открытый
Замкнутый путь автоматически соединяет последнюю и первую точки.
Two.js не использует явные команды вроде moveTo или
lineTo, но их логика реализуется через последовательность
вершин.
Первая вершина пути:
new Two.Anchor(x, y)
Добавление следующей вершины:
vertices.push(new Two.Anchor(x, y));
Добавление вершины с управляющими точками:
const a = new Two.Anchor(200, 200);
a.controls.left.set(-30, 0);
a.controls.right.set(30, 0);
Добавление точек в реальном времени:
shape.vertices.push(new Two.Anchor(mouseX, mouseY));
shape._flagVertices = true;
two.update();
Флаг _flagVertices сообщает системе о необходимости
перерисовки.
shape.translation.set(250, 250);
shape.rotation = Math.PI / 4;
shape.scale = 2;
Все трансформации применяются относительно центра объекта.
Объекты можно объединять:
const group = two.makeGroup(rect, circle);
group.translation.set(300, 300);
Перемещение группы влияет на все вложенные элементы.
Two.js использует внутренние матрицы для вычисления трансформаций. Обычно прямое управление ими не требуется, но важно понимать:
translation — позицияrotation — уголscale — масштабВсе они комбинируются в итоговую матрицу преобразования.
two.bind('upd ate', function(frameCount) {
rect.translation.x += 1;
rect.translation.y += 0.5;
}).play();
Анимация основана на цикле обновления.
Можно реализовать движение вдоль пути:
let t = 0;
two.bind('update', function() {
t += 0.01;
const x = 200 + Math.cos(t) * 100;
const y = 200 + Math.sin(t) * 100;
circle.translation.se t(x, y);
}).play();
Для плавного перемещения используется линейная интерполяция:
function lerp(start, end, t) {
return start + (end - start) * t;
}
Пример:
let t = 0;
two.bind('upd ate', function() {
t += 0.01;
rect.translation.x = lerp(100, 400, t);
});
Two.js не имеет встроенной поддержки относительных команд (как SVG
l, m), но их можно реализовать вручную:
let last = shape.vertices[shape.vertices.length - 1];
shape.vertices.push(new Two.Anchor(
last.x + 50,
last.y + 0
));
Любые изменения требуют обновления:
two.update();
При использовании анимации это происходит автоматически.
В Two.js рисование и перемещение тесно связаны:
Понимание этой разницы позволяет:
Типичная последовательность:
const two = new Two().appendTo(document.body);
const shape = two.makeRectangle(0, 0, 100, 100);
shape.translation.se t(250, 250);
two.bind('update', function() {
shape.rotation += 0.01;
}).play();
Two.js абстрагирует команды рисования:
Это позволяет одинаково работать с разными рендерами без изменения кода логики.
Ключевые моменты:
Грамотное разделение этих уровней позволяет создавать сложные и управляемые графические сцены.