В PixiJS scissor-маска используется для ограничения области
рендеринга до прямоугольной области на экране. Это позволяет
оптимизировать рендеринг и создавать интерфейсные элементы с обрезкой
содержимого, например, панели прокрутки или динамические окна. В отличие
от обычной маски (mask), scissor-маска работает на уровне
WebGL, не требует создания дополнительных графических объектов и
поддерживает только прямоугольные области.
Для использования scissor-маски необходимо включить поддержку WebGL
через PIXI.Renderer или PIXI.Application и
настроить координаты области обрезки.
const app = new PIXI.Application({ width: 800, height: 600 });
document.body.appendChild(app.view);
const graphics = new PIXI.Graphics();
graphics.beginFill(0xff0000);
graphics.drawRect(0, 0, 200, 200);
graphics.endFill();
app.stage.addChild(graphics);
Scissor-маска реализуется с помощью рендерера. Для установки
прямоугольной области используется метод
renderer.gl.scissor, а для включения —
renderer.gl.enable(gl.SCISSOR_TEST). В PixiJS это можно
делать через объект renderer, полученный из
app.renderer.
const renderer = app.renderer;
const gl = renderer.gl;
gl.enable(gl.SCISSOR_TEST);
gl.scissor(100, 100, 200, 200); // x, y, width, height
Параметры scissor задаются в пикселях
относительно нижнего левого угла канваса. Если canvas
масштабируется или используется resolution не равный 1,
необходимо учитывать коэффициент масштабирования:
const scale = renderer.resolution;
gl.scissor(100 * scale, 100 * scale, 200 * scale, 200 * scale);
Для ограничения группы объектов можно применять scissor-маску к контейнеру. Поскольку scissor-маска действует глобально на рендер, необходимо сохранять текущее состояние маски, чтобы не повлиять на остальные объекты сцены.
const container = new PIXI.Container();
container.addChild(graphics);
app.stage.addChild(container);
renderer.batch.flush(); // Обязательная очистка батча перед изменением маски
gl.enable(gl.SCISSOR_TEST);
gl.scissor(50 * scale, 50 * scale, 300 * scale, 300 * scale);
renderer.render(container);
gl.disable(gl.SCISSOR_TEST);
Обязательная последовательность действий:
renderer.batch.flush() перед изменением
scissor.| Параметр | Scissor-маска | Mask (Graphics) |
|---|---|---|
| Форма | Только прямоугольная | Любая форма |
| Производительность | Высокая, работает на уровне WebGL | Ниже, создаёт дополнительные объекты и фреймы |
| Ограничения | Координаты в пикселях, действует на весь рендер | Локально для объекта или контейнера |
| Использование | Контейнеры и рендер оптимизированных областей | Универсальная маска для сложной графики |
При необходимости создавать несколько уровней маски можно сохранять состояние текущей области с помощью стека координат:
const scissorStack = [];
function pushScissor(x, y, width, height) {
scissorStack.push(gl.getParameter(gl.SCISSOR_BOX));
gl.enable(gl.SCISSOR_TEST);
gl.scissor(x * scale, y * scale, width * scale, height * scale);
}
function popScissor() {
const prev = scissorStack.pop();
if(prev) {
gl.scissor(prev[0], prev[1], prev[2], prev[3]);
} else {
gl.disable(gl.SCISSOR_TEST);
}
}
Этот подход позволяет создавать вложенные прямоугольные области, например, для многоуровневых интерфейсов или областей прокрутки.
Scissor-маска оперирует пикселями канваса, а не логическими
координатами сцены. При работе с app.stage.scale или
renderer.resolution координаты и размеры прямоугольника
необходимо корректировать:
const rect = { x: 50, y: 50, width: 400, height: 300 };
gl.scissor(
rect.x * renderer.resolution,
rect.y * renderer.resolution,
rect.width * renderer.resolution,
rect.height * renderer.resolution
);
Игнорирование масштабирования приведёт к неверной обрезке объектов.
renderer.batch.flush() при
изменении маски.mask), так как scissor ограничен
прямоугольником.Scissor-маска является мощным инструментом для оптимизации и управления прямоугольными областями в PixiJS, особенно при создании UI-элементов с обрезкой и прокруткой.