Two.js предоставляет удобные инструменты для работы с векторной
графикой, в том числе создание и редактирование пути
(Path). Пути состоят из последовательности
вершин (Vector) и могут быть как
замкнутыми, так и открытыми. Оптимизация и упрощение путей позволяет
уменьшить количество точек без потери визуальной формы, что важно для
производительности и плавности анимаций.
Path в Two.js формируется с помощью объекта
Two.Path. Ключевые свойства:
vertices – массив объектов Two.Vector,
задающий точки пути.closed – логическое значение, определяющее замкнутый ли
путь.curved – определяет, будут ли линии между точками
кривыми или прямыми.stroke и fill – цвет обводки и
заливки.linewidth – толщина линии.Пример создания простого пути:
const path = two.makePath(
new Two.Anchor(0, 0),
new Two.Anchor(50, 0),
new Two.Anchor(50, 50),
new Two.Anchor(0, 50),
true
);
path.stroke = '#000000';
path.fill = '#ff0000';
path.linewidth = 2;
Массив vertices можно фильтровать по критерию близости
соседних точек. Например:
function simplifyVertices(vertices, tolerance) {
const simplified = [vertices[0]];
for (let i = 1; i < vertices.length; i++) {
const last = simplified[simplified.length - 1];
const current = vertices[i];
const dx = current.x - last.x;
const dy = current.y - last.y;
if (Math.sqrt(dx*dx + dy*dy) > tolerance) {
simplified.push(current);
}
}
return simplified;
}
path.vertices = simplifyVertices(path.vertices, 5);
Пояснение: этот метод оставляет только точки,
расстояние между которыми больше заданного порога
tolerance, убирая мелкие колебания и перегруженные
сегменты.
Этот алгоритм используется для более точного упрощения кривых, сохраняя их форму:
function rdp(points, epsilon) {
let dmax = 0;
let index = 0;
const end = points.length - 1;
for (let i = 1; i < end; i++) {
const d = perpendicularDistance(points[i], points[0], points[end]);
if (d > dmax) {
index = i;
dmax = d;
}
}
if (dmax > epsilon) {
const recResults1 = rdp(points.slice(0, index+1), epsilon);
const recResults2 = rdp(points.slice(index), epsilon);
return recResults1.slice(0, -1).concat(recResults2);
} else {
return [points[0], points[end]];
}
}
function perpendicularDistance(point, lineStart, lineEnd) {
const dx = lineEnd.x - lineStart.x;
const dy = lineEnd.y - lineStart.y;
return Math.abs(dy*point.x - dx*point.y + lineEnd.x*lineStart.y - lineEnd.y*lineStart.x) /
Math.sqrt(dx*dx + dy*dy);
}
path.vertices = rdp(path.vertices, 2);
Особенности метода:
epsilon для контроля точности.После упрощения пути можно дополнительно сгладить линии:
path.curved = true;
path.cap = 'round';
path.join = 'round';
Использование свойства curved позволяет Two.js
автоматически интерполировать кривые между точками, делая визуализацию
плавной.
При работе с большим количеством вершин и сложными анимациями:
Two.Path.makeObservable() для
автоматического обновления сцены после изменения вершин.Пример:
Two.Path.makeObservable(path);
path.vertices = rdp(path.vertices, 1.5);
two.update();
epsilon) критичен: слишком большое
значение может сильно исказить форму, слишком маленькое — не даст
заметного эффекта.Эти методы упрощения пути делают работу с Two.js более эффективной и позволяют создавать интерактивные графические элементы с высокой производительностью и эстетикой.