Кривые в библиотеке Paper.js представлены сегментами
(Segment), соединёнными в пути (Path). Каждый
сегмент может содержать управляющие точки, определяющие форму кривой
Безье. В основе лежит кубическая кривая Безье,
задаваемая четырьмя точками:
Каждый сегмент хранит:
point — координаты опорной точкиhandleIn — входящая управляющая точка (от предыдущего
сегмента)handleOut — исходящая управляющая точка (к следующему
сегменту)var segment = new paper.Segment({
point: [100, 100],
handleIn: [-50, 0],
handleOut: [50, 0]
});
Кубическая кривая Безье описывается параметрическим уравнением:
[ B(t) = (1 - t)^3 P_0 + 3(1 - t)^2 t P_1 + 3(1 - t)t^2 P_2 + t^3 P_3,t ]
где:
В Paper.js эта математика скрыта за API, но понимание структуры позволяет точно управлять формой кривой.
var path = new paper.Path();
path.strokeColor = 'black';
path.add(new paper.Segment([50, 250], null, [100, 0]));
path.add(new paper.Segment([250, 250], [-100, 0], null));
Здесь:
handleOuthandleInЭто создаёт плавную кривую между двумя точками.
Path.curveTovar path = new paper.Path();
path.moveTo([50, 250]);
path.curveTo([150, 150], [200, 350], [300, 250]);
Параметры:
Если handleIn и handleOut равны
[0, 0], сегмент является прямой линией.
path.add([100, 100]);
path.add([200, 200]);
При симметричных управляющих точках получается гладкая кривая.
segment.handleIn = [-50, 0];
segment.handleOut = [50, 0];
Если handleIn и handleOut не симметричны —
появляется излом.
Каждый путь (Path) состоит из массива кривых
(Curve), каждая из которых соединяет два сегмента.
var curve = path.curves[0];
Свойства кривой:
curve.point1 — начальная точкаcurve.point2 — конечная точкаcurve.handle1 — первая управляющая точкаcurve.handle2 — вторая управляющая точкаvar point = curve.getPointAt(0.5);
Значение t = 0.5 соответствует середине кривой.
var tangent = curve.getTangentAt(0.5);
Используется для:
var normal = curve.getNormalAt(0.5);
Нормаль перпендикулярна касательной.
var length = curve.length;
Paper.js вычисляет длину численно, используя аппроксимацию.
Для точки на расстоянии:
var point = curve.getPointAt(length / 2);
Метод divideAt разбивает кривую на две части:
var newCurve = curve.divideAt(0.5);
После вызова:
Paper.js предоставляет встроенные алгоритмы сглаживания:
path.smooth();
Режимы:
path.smooth({
type: 'continuous'
});
Варианты:
asymmetriccontinuouscatmull-romgeometricСглаживание автоматически корректирует handleIn и
handleOut.
path.segments[0].handleOut.x += 20;
tool.onMouseD rag = function(event) {
path.segments[0].handleOut = event.point.subtract(path.segments[0].point);
};
var path1 = new paper.Path.Circle([100, 100], 50);
var path2 = new paper.Path.Rectangle([50, 50], [200, 200]);
var result = path1.interpolate(path2, 0.5);
Создаётся промежуточная форма.
var flattened = path.flatten(10);
Параметр — максимальное отклонение.
Используется для:
var intersections = path1.getIntersections(path2);
Каждое пересечение содержит:
Ключевые моменты:
handle требует перерасчётаОптимизация:
simplify()flatten() при необходимостиvar path = new paper.Path();
path.strokeColor = 'black';
for (var i = 0; i < 10; i++) {
var point = new paper.Point(i * 50, 200);
var segment = new paper.Segment(point);
segment.handleIn = new paper.Point(-25, i % 2 ? -50 : 50);
segment.handleOut = new paper.Point(25, i % 2 ? 50 : -50);
path.add(segment);
}
var position = 0;
view.onFr ame = function(event) {
position += 1;
var point = path.getPointAt(position);
circle.position = point;
};
var tangent = path.getTangentAt(position);
circle.rotation = tangent.angle;
Кривые наследуют трансформации пути:
path.scale(1.5);
path.rotate(45);
path.translate([100, 0]);
Все управляющие точки трансформируются автоматически.
Paper.js позволяет выполнять операции:
var result = path1.unite(path2);
var result = path1.subtract(path2);
var result = path1.intersect(path2);
Результат — новый путь, состоящий из кривых.
path.closed = true;
Замыкание:
path.curves.forEach(function(curve) {
console.log(curve.length);
});
var location = path.getNearestLocation(point);
Возвращает:
tГлубокое понимание структуры сегментов, управляющих точек и API
Curve позволяет точно контролировать геометрию, создавать
сложные формы, анимации и интерактивные графические системы на основе
Paper.js.