Концепция маски в PixiJS

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

В PixiJS маска может быть представлена объектом Graphics или любым другим объектом, поддерживающим интерфейс PIXI.DisplayObject. Маски можно применять к отдельным спрайтам, группам объектов внутри контейнеров или даже к сцене целиком.

const app = new PIXI.Application({ width: 800, height: 600 });
document.body.appendChild(app.view);

const sprite = PIXI.Sprite.from('example.png');
app.stage.addChild(sprite);

const mask = new PIXI.Graphics();
mask.beginFill(0xffffff);
mask.drawCircle(150, 150, 100);
mask.endFill();

sprite.mask = mask;
app.stage.addChild(mask);

В этом примере спрайт отображается только в пределах круга, определённого объектом mask.


Особенности работы масок

  1. Маски не наследуются автоматически. Если маска применена к контейнеру, все дочерние элементы будут отображаться согласно форме маски. Применение маски к отдельному объекту не влияет на соседние элементы.

  2. Маска действует в локальных координатах. Положение маски учитывается относительно родительского контейнера объекта. При перемещении родительского контейнера маска и объект будут двигаться синхронно.

  3. Динамические маски. Маску можно изменять во время работы приложения. Это позволяет создавать эффекты открытия, анимации и интерактивные области. Изменение формы Graphics автоматически обновляет видимую область.

app.ticker.add(() => {
    mask.rotation += 0.01;
});

В этом примере маска вращается, создавая эффект движущейся области видимости.


Применение масок к контейнерам

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

const container = new PIXI.Container();

const sprite1 = PIXI.Sprite.from('image1.png');
const sprite2 = PIXI.Sprite.from('image2.png');

container.addChild(sprite1, sprite2);
app.stage.addChild(container);

const mask = new PIXI.Graphics();
mask.beginFill(0xffffff);
mask.drawRect(50, 50, 200, 200);
mask.endFill();

container.mask = mask;
app.stage.addChild(mask);

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


Маски и производительность

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

  • Простые геометрические формы (круги, прямоугольники) вместо сложных кривых.
  • Кэширование маски через generateTexture(), чтобы создать текстурную маску вместо динамической отрисовки Graphics.
const maskTexture = app.renderer.generateTexture(mask);
const maskSprite = new PIXI.Sprite(maskTexture);
sprite.mask = maskSprite;

Использование текстурной маски снижает нагрузку на GPU при сложных или анимированных сценах.


Взаимодействие с прозрачностью и альфа-каналом

Маска учитывает прозрачность спрайта, но сама по себе не наследует прозрачность от маски. Это значит, что полностью прозрачная маска не будет показывать объект. Для полупрозрачных областей следует использовать фильтры, например AlphaFilter, так как стандартная маска работает только как бинарная область видимости.


Маски и сцены с несколькими слоями

Для многослойных сцен маски могут применяться отдельно к каждому слою или контейнеру:

  • Локальная маска: применяется к конкретному контейнеру или объекту.
  • Глобальная маска: при желании можно создать общую маску для нескольких контейнеров, добавив их в один родительский контейнер и применив маску к нему.

Это позволяет реализовать эффекты, такие как spotlight, затемнение фона или выделение интерактивных областей.


Итоговые рекомендации

  • Маска — инструмент ограничения видимости, не влияющий на цвета и фильтры объекта.
  • Использовать простые геометрические формы для повышения производительности.
  • Динамическое изменение маски позволяет создавать эффекты анимации.
  • Для полупрозрачных эффектов маска не подходит, следует использовать фильтры.
  • Контейнеры и дочерние элементы наследуют маску при необходимости.

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