Визуализация bounds

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

Каждый объект Paper.js, наследующийся от Item (например, Path, Shape, Raster, Group), имеет свойство bounds. Это свойство возвращает объект Rectangle, который содержит координаты верхнего левого угла (x, y) и размеры (width, height) объекта.

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

console.log(circle.bounds); // Rectangle { x: 20, y: 20, width: 60, height: 60 }

В приведенном примере bounds круга охватывает всю область, занятую кругом, включая радиус.


Свойства и методы объекта Rectangle

Объект Rectangle, возвращаемый bounds, имеет следующие ключевые свойства:

  • x, y — координаты верхнего левого угла.
  • width, height — ширина и высота прямоугольника.
  • topLeft, topRight, bottomLeft, bottomRight — точки углов.
  • center — центр прямоугольника.
  • size — объект Size с шириной и высотой.

Кроме того, Rectangle поддерживает методы для преобразований:

  • contains(point) — проверяет, находится ли точка внутри bounds.
  • intersects(rectangle) — проверяет пересечение с другим прямоугольником.
  • expand(amount) — расширяет прямоугольник на указанное количество пикселей.
  • scale(factor, centerPoint) — масштабирует прямоугольник относительно точки.
var rect = circle.bounds;
rect.expand(10); // увеличивает bounds на 10 пикселей со всех сторон
console.log(rect.width, rect.height); // ширина и высота увеличены

Различие между bounds, strokeBounds и handleBounds

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

  • bounds — охватывает только геометрические точки объекта (контур), без учёта толщины линии.
  • strokeBounds — учитывает толщину линии (strokeWidth) при вычислении прямоугольника.
  • handleBounds — охватывает объект вместе с кривыми Безье и управляющими точками, что особенно важно при анимации и сложных путях.
var path = new Path.Circle({
    center: [100, 100],
    radius: 40,
    strokeColor: 'black',
    strokeWidth: 10
});

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

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

Bounds часто применяются для точного позиционирования объектов на холсте. Основные техники:

  • Центрирование объекта:
var rect = new Path.Rectangle({
    point: [0, 0],
    size: [80, 50],
    fillColor: 'blue'
});

rect.position = view.center; // центрирование на холсте
  • Выравнивание по краям:
rect.bounds.topLeft = new Point(10, 10); // позиция верхнего левого угла
rect.bounds.bottomRight = new Point(200, 100); // масштабирование по углам
  • Отступы и смещения:
rect.bounds.x += 20; // сдвиг вправо
rect.bounds.y += 15; // сдвиг вниз

Работа с bounds в группах и сложных объектах

Объекты Group имеют собственный bounds, который автоматически пересчитывается при добавлении или удалении дочерних элементов. Это упрощает работу с композитными фигурами.

var circle = new Path.Circle({ center: [50, 50], radius: 20 });
var square = new Path.Rectangle({ point: [70, 70], size: [40, 40] });

var group = new Group([circle, square]);
console.log(group.bounds); // охватывает оба объекта

При изменении положения дочернего объекта bounds группы автоматически обновляется:

square.position.x += 50;
console.log(group.bounds); // обновленные координаты

Проверка пересечения и столкновений

Bounds позволяют быстро проверять пересечения объектов без сложных вычислений точек:

var rect1 = new Path.Rectangle([0, 0], [100, 50]);
var rect2 = new Path.Rectangle([50, 25], [80, 60]);

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

Для динамических анимаций это особенно полезно, так как позволяет отслеживать столкновения до рендеринга.


Динамическое масштабирование и трансформации

Bounds облегчают масштабирование и перемещение объектов с сохранением пропорций:

var rect = new Path.Rectangle([0, 0], [120, 60]);
var factor = 1.5;

// масштабирование относительно центра объекта
rect.bounds.scale(factor, rect.bounds.center);

Также можно легко применять padding и margin вокруг объекта, расширяя bounds:

var paddedBounds = rect.bounds.clone().expand(20);

Практическая оптимизация при работе с bounds

  1. Использовать strokeBounds, если важна точная видимая область с учётом толщины линий.
  2. Для сложных кривых и анимаций использовать handleBounds.
  3. Кэшировать bounds для статичных объектов, чтобы не пересчитывать их при каждом рендере.
  4. Использовать bounds для вычисления коллизий вместо проверки каждой точки контура.

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