Локальные и глобальные координаты

В библиотеке PixiJS каждая графическая сущность (DisplayObject) имеет собственную систему координат. Основной принцип заключается в том, что координаты элемента всегда локальны относительно его родителя. Это значит, что точка (0,0) всегда находится в верхнем левом углу родительского контейнера, а не сцены в целом.

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

Свойства позиции и трансформации

У объектов в PixiJS есть несколько ключевых свойств для работы с координатами и трансформацией:

  • x, y — позиция объекта относительно родителя.
  • position — объект типа PIXI.Point, объединяющий x и y.
  • scale — масштаб объекта (scale.x, scale.y).
  • rotation — угол поворота в радианах.
  • pivot — точка поворота и масштабирования относительно локальных координат.
  • anchor — для спрайтов, аналог pivot, задает точку привязки в диапазоне [0,1].

Пример использования:

const sprite = PIXI.Sprite.from('image.png');
sprite.position.set(100, 50);
sprite.scale.set(2, 2);
sprite.rotation = Math.PI / 4; // 45 градусов
sprite.pivot.set(sprite.width / 2, sprite.height / 2);

В этом примере sprite позиционируется в (100,50) относительно родителя, увеличивается в 2 раза и поворачивается вокруг центра.

Преобразование между локальными и глобальными координатами

PixiJS предоставляет методы для перевода координат:

  • toGlobal(localPoint, point, skipUpdate) — преобразует локальные координаты объекта в глобальные координаты сцены.
  • toLocal(globalPoint, from, point, skipUpdate) — преобразует глобальные координаты в локальные координаты относительно текущего объекта.

localPoint и globalPoint представляют собой объекты PIXI.Point. Аргумент from в toLocal позволяет указать объект, относительно которого заданы глобальные координаты.

Пример:

const globalPosition = sprite.toGlobal(new PIXI.Point(0, 0));
const localPosition = sprite.toLocal(globalPosition);

В этом случае localPosition будет примерно равен (0,0), если объект не имеет сложных вложенных трансформаций.

Иерархия объектов и наследование трансформаций

Все Container в PixiJS могут содержать дочерние объекты. При этом позиция, масштаб и поворот дочернего объекта умножаются на трансформации родителя. Это обеспечивает естественное наследование координат.

const container = new PIXI.Container();
container.position.set(200, 100);

const child = new PIXI.Sprite.from('child.png');
child.position.set(50, 50);

container.addChild(child);
app.stage.addChild(container);

Глобальная позиция child будет (250,150) — сумма позиции родителя и позиции самого ребенка. При вращении или масштабировании родителя, дочерний объект автоматически изменит своё положение и размер относительно сцены.

Примеры применения

  1. Перемещение группы объектов: Вместо изменения позиции каждого спрайта, достаточно сдвинуть контейнер, содержащий все объекты.
  2. Поворот и масштабирование сцены: Камера реализуется как контейнер, трансформации которого влияют на все дочерние объекты.
  3. Обработка кликов: Для определения объекта, на который был произведен клик, можно преобразовать глобальные координаты мыши в локальные координаты объекта.
app.stage.interactive = true;
app.stage.on('pointerdown', (event) => {
    const local = child.toLocal(event.data.global);
    console.log('Локальная позиция клика: ', local);
});

Pivot и Anchor: контроль центра трансформации

pivot и anchor позволяют задавать точку отсчета трансформаций. Разница между ними заключается в том, что pivot используется на всех объектах типа DisplayObject, а anchor — только на Sprite.

  • Pivot: координаты задаются в пикселях.
  • Anchor: координаты задаются как доля размеров объекта (от 0 до 1).

Пример:

sprite.anchor.set(0.5); // центр спрайта
sprite.rotation = Math.PI / 2; // поворот вокруг центра

Использование pivot или anchor критично при анимациях и вращении объектов, чтобы движение выглядело естественным.

Преобразование координат при сложной иерархии

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

const parent = new PIXI.Container();
parent.position.set(100, 100);
parent.rotation = Math.PI / 6;

const child = new PIXI.Container();
child.position.set(50, 0);

parent.addChild(child);
app.stage.addChild(parent);

const pointInChild = new PIXI.Point(0,0);
const globalPoint = child.toGlobal(pointInChild);

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

Практические советы

  • Использовать локальные координаты при создании сложных анимаций и иерархий объектов.
  • Для вычисления позиции на экране всегда применять toGlobal.
  • Для взаимодействия с объектами через события мыши или касания — сначала преобразовывать глобальные координаты в локальные через toLocal.
  • Тщательно настраивать pivot или anchor, чтобы анимации и вращения выглядели естественно.

Локальные и глобальные координаты в PixiJS — фундаментальная концепция, которая обеспечивает гибкость управления объектами и их трансформациями, делая возможным создание сложных сцен с минимальными усилиями по позиционированию и анимации.