Маска через Graphics-объект

В PixiJS маска является мощным инструментом для управления видимостью объектов на сцене. Основная идея маски — определить область, через которую будет видно содержимое спрайта или контейнера. Одним из способов создания маски является использование Graphics-объекта.


Создание Graphics-объекта

Graphics — это векторный объект, позволяющий рисовать фигуры с помощью методов beginFill, lineStyle, drawRect, drawCircle, drawPolygon и других. Для маски важна заполненная область (fill), так как прозрачная область не будет пропускать контент. Пример создания простого прямоугольника:

const mask = new PIXI.Graphics();
mask.beginFill(0xffffff); // Цвет не важен для маски, главное, чтобы была заливка
mask.drawRect(50, 50, 200, 150);
mask.endFill();

Применение маски к объекту

После создания Graphics-объекта его можно использовать в качестве маски для любого спрайта или контейнера:

const sprite = PIXI.Sprite.from('image.png');
sprite.mask = mask;

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


Маска для контейнера

Маска может применяться не только к отдельному спрайту, но и к целому контейнеру. Все дочерние объекты контейнера будут видны только внутри области маски.

const container = new PIXI.Container();
container.addChild(sprite1, sprite2, sprite3);
container.mask = mask;

Таким образом можно создавать сложные визуальные эффекты, когда несколько объектов видимы только через одну форму.


Динамические маски

Graphics-объект для маски можно изменять в процессе работы приложения. Это позволяет создавать анимации масок:

app.ticker.add(() => {
    mask.clear();
    mask.beginFill(0xffffff);
    mask.drawCircle(100 + Math.sin(app.ticker.lastTime / 500) * 50, 100, 60);
    mask.endFill();
});

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


Ограничения и особенности

  1. Только залитые области: линии без заливки не будут видны в маске. Чтобы маска работала, необходимо использовать beginFill.
  2. Производительность: динамические маски могут влиять на FPS при большом количестве объектов. Следует оптимизировать сложные фигуры.
  3. Вложенность: маска применяется на уровне родителя. Если объект внутри контейнера имеет собственную маску, PixiJS объединяет их с помощью пересечения.
  4. Позиционирование: координаты маски и объекта должны быть согласованы. Для подвижных объектов рекомендуется использовать контейнер для группы и применять маску к нему.

Комплексные фигуры

Graphics позволяет создавать сложные маски с использованием нескольких форм и булевых операций:

mask.beginFill(0xffffff);
mask.drawRect(50, 50, 200, 150);
mask.drawCircle(150, 120, 50);
mask.endFill();

В PixiJS несколько фигур в одном Graphics-объекте автоматически объединяются. Для создания вырезов или «дыр» можно использовать трюк с blendMode при сложной сцене, но прямой поддержки булевых операций нет.


Использование с анимацией и событиями

Graphics-маски хорошо сочетаются с интерактивными объектами:

  • Маска может перемещаться за курсором.
  • Маска может реагировать на клики, формируя область интерактивности.
  • Комбинирование с анимационными библиотеками (GSAP, PixiJS animate) позволяет создавать плавные эффекты затухания, появления и скрытия контента.

Пример движения маски по сцене:

app.stage.interactive = true;
app.stage.on('pointermove', (event) => {
    mask.position.set(event.data.global.x - 50, event.data.global.y - 50);
});

В этом случае видимая область объекта следует за курсором, создавая эффект «светового прожектора».


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