hitArea и кастомная область попадания

В PixiJS свойство hitArea используется для определения области объекта, в которой будут регистрироваться события взаимодействия, такие как pointerdown, click или mouseover. По умолчанию область попадания объекта совпадает с его графическим содержимым (sprite.texture или graphics), однако hitArea позволяет явно задать любую форму, независимо от видимой графики.

Типы объектов, которые можно использовать для hitArea:

  • Rectangle — прямоугольная область.
  • Circle — круглая область.
  • Ellipse — эллипс.
  • Polygon — многоугольник.
  • CustomHitArea — собственная реализация с методом contains(x, y).

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

const sprite = new PIXI.Sprite(texture);
sprite.interactive = true;
sprite.hitArea = new PIXI.Rectangle(0, 0, 100, 50);

sprite.on('pointerdown', () => {
    console.log('Спрайт был нажат!');
});

В этом примере событие срабатывает только при клике внутри области 100x50, даже если видимая графика спрайта больше или меньше.


Кастомные области попадания

PixiJS предоставляет возможность создавать собственные области попадания с помощью объектов, реализующих метод contains(x, y). Это особенно полезно для сложных форм, где стандартные геометрические объекты не подходят.

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

class CustomHitArea {
    constructor(vertices) {
        this.vertices = vertices;
    }

    contains(x, y) {
        let inside = false;
        const n = this.vertices.length;
        for (let i = 0, j = n - 1; i < n; j = i++) {
            const xi = this.vertices[i][0], yi = this.vertices[i][1];
            const xj = this.vertices[j][0], yj = this.vertices[j][1];

            const intersect = ((yi > y) !== (yj > y)) &&
                (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
            if (intersect) inside = !inside;
        }
        return inside;
    }
}

const polygonArea = new CustomHitArea([[0,0],[100,0],[100,100],[0,100]]);
sprite.hitArea = polygonArea;

Метод contains должен возвращать true, если точка (x, y) находится внутри области, и false в противном случае. Для проверки попадания можно использовать алгоритмы вроде ray-casting для полигонов.


Интерактивность и hitArea

Чтобы объект реагировал на события, необходимо установить свойство interactive = true. С помощью hitArea можно настроить область для:

  • pointerdown / pointerup
  • mouseover / mouseout
  • pointermove
  • rightclick / pointertap

При работе с контейнерами (PIXI.Container) кастомная hitArea действует для всего контейнера, а события будут отслеживаться в пределах указанной формы, игнорируя дочерние элементы, если они не имеют своих интерактивных областей.

Пример для контейнера:

const container = new PIXI.Container();
container.interactive = true;
container.hitArea = new PIXI.Circle(50, 50, 40);

container.on('pointerdown', () => {
    console.log('Клик по контейнеру внутри круга');
});

Сложные области с использованием нескольких форм

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

class MultiHitArea {
    constructor(areas) {
        this.areas = areas;
    }

    contains(x, y) {
        return this.areas.some(area => area.contains(x, y));
    }
}

const rect = new PIXI.Rectangle(0, 0, 50, 50);
const circle = new PIXI.Circle(75, 75, 25);
sprite.hitArea = new MultiHitArea([rect, circle]);

Такой подход позволяет комбинировать прямоугольники, круги и любые кастомные формы, создавая интерактивные зоны любой сложности.


Производительность и оптимизация

  • Использование простых геометрических форм (Rectangle, Circle) быстрее, чем сложные кастомные области.
  • Для больших сцен с множеством интерактивных объектов рекомендуется избегать сложных полигонов и кастомных contains с тяжелыми вычислениями.
  • В некоторых случаях для динамических форм можно пересоздавать hitArea при изменении размеров или позиции объекта.

Взаимодействие с событиями

hitArea полностью интегрируется с системой событий PixiJS. Это значит, что можно:

  • Настраивать область, которая не совпадает с визуальным контентом.
  • Игнорировать клики вне заданной формы.
  • Создавать «невидимые кнопки» или интерактивные зоны на графике, где визуальные элементы не охватывают всю область.

Эти возможности делают hitArea ключевым инструментом для создания сложных интерфейсов и игр с произвольными интерактивными зонами.