Маска через класс MaskData

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


Основы класса MaskData

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

  • type — тип маски, определяющий способ применения (PIXI.MASK_TYPES), например, геометрические фигуры или спрайты.
  • maskObject — объект, который используется в качестве маски (например, Graphics или Sprite).
  • isMaskData — флаг, который однозначно идентифицирует объект как экземпляр MaskData.
  • enableScissor — управление использованием scissor-тестирования для оптимизации рендеринга.

MaskData тесно интегрирован с Renderer и Container, что позволяет применять маски в различных комбинациях и настраивать их поведение в зависимости от нужд сцены.


Создание маски с Graphics через MaskData

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

  1. Создание графического объекта:
const maskGraphics = new PIXI.Graphics();
maskGraphics.beginFill(0xffffff);
maskGraphics.drawCircle(150, 150, 100);
maskGraphics.endFill();
  1. Инициализация MaskData:
const maskData = new PIXI.MaskData(maskGraphics);
maskData.type = PIXI.MASK_TYPES.OBJECT;
  1. Применение к контейнеру:
const container = new PIXI.Container();
container.addChild(sprite);
container.renderable = true;

// Добавление маски через внутренний API
container._mask = maskData;

Использование MaskData напрямую позволяет контролировать рендеринг маски на уровне движка, обходя стандартные методы .mask = maskGraphics, что полезно при работе с несколькими сложными масками или при оптимизации производительности.


Маска с Sprite

Класс MaskData также поддерживает маскирование спрайтов, что позволяет создавать текстурированные маски:

const maskSprite = PIXI.Sprite.from('mask.png');
const maskData = new PIXI.MaskData(maskSprite);
maskData.type = PIXI.MASK_TYPES.SPRITE;

container._mask = maskData;

Особенности маски со спрайтом:

  • Маска учитывает альфа-канал изображения.
  • Позволяет анимировать маску с помощью свойств x, y, scale и rotation.
  • Поддерживает комплексные эффекты при комбинировании с blendMode.

Комбинирование масок

MaskData можно использовать для создания стека масок на одном контейнере:

const mask1 = new PIXI.MaskData(maskGraphics1);
const mask2 = new PIXI.MaskData(maskGraphics2);

container._mask = [mask1, mask2];

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

  • Фоновые градиенты, обрезаемые динамическими фигурами.
  • Появление и исчезновение объектов по определенным траекториям.
  • Эффекты “просвета” через анимированные формы.

Управление рендерингом и оптимизация

MaskData предоставляет параметры для оптимизации:

  • Scissor-тест (enableScissor) уменьшает количество пикселей, которые необходимо рендерить, что критично для больших сцен с динамическими масками.
  • Использование type = PIXI.MASK_TYPES.NONE позволяет временно отключить маску без удаления объекта.
  • Прямое управление маской через MaskData сокращает лишние обновления рендеринга при анимации.

Интеграция с фильтрами и контейнерами

Маски на основе MaskData совместимы с фильтрами и дочерними контейнерами. Можно, например, применить маску к контейнеру с несколькими спрайтами и одновременно использовать фильтр размытия:

container.filters = [new PIXI.filters.BlurFilter(5)];
container._mask = maskData;

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


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

  • MaskData работает на низком уровне и не предназначен для замены стандартного .mask без причины. Основное применение — оптимизация и сложные эффекты.
  • Маски могут быть динамическими, но требуют правильного обновления позиции и масштабов, иначе визуальные артефакты будут заметны.
  • Применение нескольких масок увеличивает нагрузку на GPU, особенно при использовании текстурных спрайтов.

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