InternalBounds

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

Ключевое отличие от bounds:

  • bounds включает все видимые элементы, включая обводку (stroke) и тени.
  • internalBounds отражает «чистую» геометрию объекта, игнорируя визуальные эффекты.

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


Использование internalBounds на примере Path

var path = new Path.Rectangle({
    point: [50, 50],
    size: [100, 100],
    strokeColor: 'black',
    strokeWidth: 20
});

// Границы с учетом strokeWidth
console.log(path.bounds); // Rectangle { x: 40, y: 40, width: 120, height: 120 }

// Внутренние границы без strokeWidth
console.log(path.internalBounds); // Rectangle { x: 50, y: 50, width: 100, height: 100 }

В примере видно, что bounds расширены на половину толщины обводки (strokeWidth / 2) с каждой стороны, а internalBounds строго соответствует геометрии прямоугольника.


Применение с Group

Объекты типа Group объединяют несколько элементов, и у группы также есть internalBounds. Он вычисляется на основе внутренних границ всех дочерних объектов, исключая внешние эффекты.

var circle = new Path.Circle([150, 150], 50);
circle.strokeWidth = 10;

var rectangle = new Path.Rectangle([100, 100], [200, 200]);
rectangle.strokeWidth = 30;

var group = new Group([circle, rectangle]);

console.log(group.bounds);          // Включает strokeWidth всех объектов
console.log(group.internalBounds);  // Внутренние границы, игнорируя strokeWidth

Использование internalBounds в группах позволяет точно позиционировать или выравнивать объекты, не влияя на визуальные эффекты.


internalBounds и позиционирование

Свойство internalBounds особенно полезно при центрировании объектов или выравнивании их по сетке, когда важно учитывать только чистую геометрию.

var path = new Path.Rectangle([0, 0], [200, 100]);
path.strokeWidth = 50;

// Центрирование объекта без учета strokeWidth
path.position = view.center;
path.bounds.center;        // Центр с учетом strokeWidth
path.internalBounds.center; // Чистый центр геометрии

Используя internalBounds.center, можно точно позиционировать объект по координатам, не смещая его визуальное тело из-за толстой обводки.


Отличие от visibleBounds

Paper.js также предоставляет visibleBounds, который учитывает любые визуальные эффекты объекта, включая фильтры, тени и обводку. Сравнение свойств:

Свойство Учитывает strokeWidth Учитывает эффекты Влияние на центр
bounds Да Нет Да
internalBounds Нет Нет Нет
visibleBounds Да Да Да

Таким образом, internalBounds — это чисто геометрическое свойство, позволяющее работать с объектом как с «математической формой», независимо от того, как он выглядит визуально.


Практические сценарии применения

  1. Выравнивание объектов без учета обводки: internalBounds используется для точного позиционирования объектов в интерфейсе или при анимации.

  2. Коллизия и hit-test: Для вычисления пересечений объектов важно опираться на их внутренние границы, чтобы исключить влияние визуальных эффектов.

  3. Динамическое масштабирование: При масштабировании объектов, внутренние границы помогают корректно изменять размеры, не меняя расположение относительно центра.

function fitToBounds(item, targetRect) {
    var scaleX = targetRect.width / item.internalBounds.width;
    var scaleY = targetRect.height / item.internalBounds.height;
    item.scale(Math.min(scaleX, scaleY));
    item.position = targetRect.center;
}

Взаимодействие с transform

Любые трансформации (rotate, scale, translate) изменяют internalBounds, так как они влияют на геометрию объекта напрямую, но не включают strokeWidth и эффекты.

var path = new Path.Circle([100, 100], 50);
path.strokeWidth = 20;

path.rotate(45);
console.log(path.bounds);         // Обновленный bounds с учетом обводки
console.log(path.internalBounds); // Обновленный internalBounds без обводки

Это позволяет использовать internalBounds для расчета точного пространства, занимаемого объектом после трансформации, что особенно полезно при сложных анимациях и компоновке элементов на холсте.