В Paper.js составной путь
(CompoundPath) представляет собой объект, который
объединяет несколько под-путей (Path) в один логический
объект. Он используется для создания сложных фигур с вырезами, например,
букв с внутренними отверстиями или фигур с несколькими контурами.
Каждый под-путь в составе составного пути может быть как замкнутым, так и открытым. Важно понимать, что направление под-путей определяет, какие области будут считаться «залитыми», а какие — вырезанными. Paper.js использует правило non-zero winding rule для определения заливки.
var outer = new Path.Circle(new Point(150, 150), 100);
var inner = new Path.Circle(new Point(150, 150), 50);
var compound = new CompoundPath({
children: [outer, inner],
fillColor: 'blue'
});
В этом примере внутренний круг создаёт вырез внутри внешнего круга, так как его направление автоматически противоположно внешнему.
Составные пути часто содержат большое количество сегментов, что может негативно сказаться на производительности при анимации или при сложной заливке. Основные методы оптимизации:
Метод path.simplify() уменьшает количество сегментов,
сохраняя при этом форму линии. Это особенно полезно для кривых,
импортированных из векторных редакторов, где количество точек может быть
чрезмерным.
var path = new Path.Circle(new Point(200, 200), 100);
path.flatten(0.5); // сначала упрощаем кривые в линии
path.simplify(2); // затем упрощаем сегменты
Пояснение:
flatten(tolerance) превращает кривые Безье в линейные
сегменты с указанной точностью.simplify(tolerance) удаляет лишние точки, которые почти
не влияют на форму.Составные пути работают эффективнее, если все под-пути, которые должны образовать вырезы, явно замкнуты. Незаполненные открытые контуры требуют дополнительных вычислений при рендеринге заливки.
var hole = new Path.Rectangle([100, 100], [50, 50]);
hole.closed = true;
При создании составного пути иногда остаются пустые или дублирующиеся под-пути, которые не влияют на визуализацию, но увеличивают нагрузку на отрисовку.
compound.children = compound.children.filter(function(child) {
return child.segments.length > 1;
});
Paper.js поддерживает операции булевой геометрии через методы
unite, subtract, intersect и
exclude. Для оптимизации важно объединять пути до создания
составного пути, если это возможно.
var a = new Path.Circle([150, 150], 100);
var b = new Path.Circle([200, 150], 100);
var merged = a.unite(b);
var compound = new CompoundPath({
children: [merged],
fillColor: 'red'
});
Эффект: объединение уменьшает количество под-путей и сегментов, что напрямую повышает производительность.
Для анимации сложных составных форм важно минимизировать изменения сегментов в реальном времени. Вместо динамического создания новых сегментов или под-путей лучше:
path.position и path.rotation
для перемещения и поворота.path.scale() для изменения размеров без
изменения количества сегментов.compound.scale(1.01);
compound.rotate(1);
Такой подход снижает нагрузку на рендеринг, поскольку Paper.js не пересчитывает сложные заливки каждый кадр.
flatten() перед
анимацией: особенно для кривых Безье с большим числом
контрольных точек.Эти методы позволяют создавать визуально сложные фигуры, но при этом поддерживать высокую производительность и отзывчивость интерактивных приложений.