Применение bounds в расчётах

В Paper.js объекты графики (Path, Shape, Group, Raster) имеют свойство bounds, которое возвращает объект типа Rectangle, описывающий минимальный ограничивающий прямоугольник объекта. Этот прямоугольник определяется самой геометрией объекта и включает все его видимые точки. bounds является удобным инструментом для вычисления позиции, размеров и взаимного расположения объектов на холсте.

let circle = new Path.Circle({
    center: [50, 50],
    radius: 40,
    fillColor: 'red'
});

console.log(circle.bounds); 
// Rectangle { point: { x: 10, y: 10 }, size: { width: 80, height: 80 } }

В этом примере объект circle имеет центр в точке (50,50) и радиус 40, а его bounds автоматически рассчитывается как прямоугольник от (10,10) до (90,90).


Виды bounds

Paper.js предоставляет несколько типов ограничивающих прямоугольников, каждый из которых имеет свою область применения:

  • bounds — включает все видимые части объекта, не учитывая трансформации потомков, если объект — группа.
  • strokeBounds — включает ширину контура (stroke) объекта.
  • handleBounds — учитывает контрольные точки кривых Безье, используемые для сглаживания и анимаций.
  • internalBounds — минимальный прямоугольник, полностью содержащий контур без учёта stroke.

Пример:

let rect = new Path.Rectangle({
    point: [20, 20],
    size: [100, 50],
    strokeColor: 'blue',
    strokeWidth: 10
});

console.log(rect.bounds);        // без учёта strokeWidth
console.log(rect.strokeBounds);  // с учётом strokeWidth

Использование разных видов bounds позволяет точно контролировать позиционирование и коллизию объектов.


Расчёт размеров и позиций через bounds

Bounds часто применяются для вычисления размеров объектов и их центров. Свойства объекта Rectangle, возвращаемого bounds, включают:

  • x, y — координаты верхнего левого угла.
  • width, height — размеры прямоугольника.
  • topLeft, topRight, bottomLeft, bottomRight — точки углов.
  • center, topCenter, bottomCenter, leftCenter, rightCenter — ключевые точки для выравнивания объектов.

Пример центрирования одного объекта относительно другого:

let circle = new Path.Circle({ center: [0,0], radius: 30 });
let rect = new Path.Rectangle({ point: [100,100], size: [200,150] });

circle.position = rect.bounds.center;

В этом случае центр круга будет совпадать с центром прямоугольника.


Выравнивание объектов с помощью bounds

Выравнивание объектов на холсте часто требует расчёта их границ. Например, чтобы выровнять объекты по левому краю:

let obj1 = new Path.Circle({ center: [50,50], radius: 20 });
let obj2 = new Path.Circle({ center: [150,100], radius: 30 });

let leftEdge = Math.min(obj1.bounds.left, obj2.bounds.left);

obj1.position.x += leftEdge - obj1.bounds.left;
obj2.position.x += leftEdge - obj2.bounds.left;

Здесь bounds.left позволяет вычислить самую левую границу среди объектов и корректировать позицию каждого объекта.


Работа с группами и nested bounds

Для групп объектов свойство bounds учитывает все вложенные элементы:

let group = new Group([
    new Path.Circle({ center: [10,10], radius: 10 }),
    new Path.Rectangle({ point: [20,20], size: [40,30] })
]);

console.log(group.bounds); 
// Rectangle, охватывающий и круг, и прямоугольник

Для работы с внутренними границами отдельных элементов можно использовать children[i].bounds.


Использование bounds для анимации

Bounds помогают создавать анимации объектов относительно их текущей позиции и размеров. Например, плавное движение объекта к правому краю канваса:

let path = new Path.Rectangle({ point: [10,10], size: [50,30], fillColor: 'green' });

function onFrame(event) {
    if(path.bounds.right < view.size.width){
        path.position.x += 2; // движение вправо
    }
}

Свойство bounds.right позволяет ограничивать движение объекта, чтобы он не выходил за пределы видимой области.


Коллизии и пересечения

Для обнаружения пересечений объектов удобно использовать их bounds:

if (rect1.bounds.intersects(rect2.bounds)) {
    console.log('Объекты пересекаются');
}

Метод intersects() возвращает true, если прямоугольники пересекаются, что значительно упрощает обработку столкновений без сложных геометрических вычислений.


Масштабирование и трансформации через bounds

Bounds используются для вычисления масштабов и пропорций объектов:

let path = new Path.Rectangle({ point: [0,0], size: [100,50] });
let scaleFactor = 2;
path.scale(scaleFactor);

console.log(path.bounds.width); // 200
console.log(path.bounds.height); // 100

При масштабировании важно помнить, что bounds пересчитывается автоматически, отражая новые размеры объекта.


Итоговое применение bounds

  • Позиционирование и центрирование: вычисление ключевых точек через bounds.center.
  • Выравнивание объектов: использование left, right, top, bottom.
  • Коллизии и пересечения: intersects() и contains().
  • Анимации и ограничения движения: проверка координат bounds относительно размеров канваса.
  • Масштабирование и трансформации: контроль размеров после scale() или rotate().

Использование bounds делает Paper.js мощным инструментом для точной геометрии, выравнивания, анимаций и коллизий, позволяя работать с объектами не вручную, а через их минимальные ограничивающие прямоугольники.