Механизм масок в Two.js основан на использовании любого графического объекта (или группы объектов) в качестве области видимости для другого элемента. Маска определяет, какие части целевого объекта будут видимы, а какие — скрыты. В отличие от простых масок, где используется один примитив (например, круг или прямоугольник), сложные маски формируются из нескольких объектов, объединённых в группу.
Ключевая особенность: маска учитывает суммарную геометрию всех вложенных элементов, включая их трансформации, порядок наложения и свойства прозрачности.
Two.js предоставляет возможность объединять объекты в группу
(Two.Group), которая затем может быть использована как
маска.
const two = new Two({ width: 500, height: 500 }).appendTo(document.body);
// Создание элементов маски
const circle = two.makeCircle(200, 200, 100);
const rect = two.makeRectangle(300, 200, 150, 150);
// Группировка
const maskGroup = two.makeGroup(circle, rect);
// Целевой объект
const image = two.makeRectangle(250, 250, 400, 400);
image.fill = '#3498db';
// Применение маски
image.mask = maskGroup;
two.update();
В данном примере маска формируется объединением круга и
прямоугольника. Видимой остаётся только та часть image,
которая пересекается с объединённой областью этих фигур.
При использовании нескольких объектов внутри маски действует правило:
Если у элементов маски заданы значения opacity или
используются полупрозрачные цвета:
circle.opacity = 0.5;
rect.opacity = 0.8;
то итоговая маска может работать как градиентная область видимости, особенно при использовании CanvasRenderer.
Two.js поддерживает вложенные группы, что позволяет создавать иерархически сложные маски:
const smallCircle = two.makeCircle(150, 150, 50);
const bigCircle = two.makeCircle(350, 350, 100);
const subGroup = two.makeGroup(smallCircle);
const mainGroup = two.makeGroup(subGroup, bigCircle);
image.mask = mainGroup;
Особенности:
Маска — это полноценный объект сцены, поэтому к ней применимы все трансформации:
maskGroup.translation.set(50, 0);
maskGroup.scale = 1.5;
maskGroup.rotation = Math.PI / 4;
Все изменения немедленно влияют на область видимости целевого объекта.
Сложные маски часто используются в анимации. Two.js позволяет изменять структуру маски в реальном времени.
two.bind('update', function(frameCount) {
circle.radius = 100 + Math.sin(frameCount * 0.05) * 50;
rect.rotation += 0.02;
});
Результат:
Помимо базовых фигур, маска может включать сложные пути
(Two.Path):
const path = two.makePath(
100, 100,
200, 50,
300, 150,
true
);
path.fill = '#000';
const maskGroup = two.makeGroup(path, circle);
image.mask = maskGroup;
Преимущества:
Хотя маска учитывает все элементы, порядок (z-index)
может влиять при использовании прозрачности и сложных наложений:
maskGroup.add(rect, circle);
Two.js напрямую не поддерживает инверсию маски (вырезание области), но её можно имитировать:
const full = two.makeRectangle(250, 250, 500, 500);
full.fill = '#000';
const hole = two.makeCircle(250, 250, 100);
hole.fill = 'transparent';
const maskGroup = two.makeGroup(full, hole);
image.mask = maskGroup;
Результат зависит от рендерера и может требовать дополнительных настроек.
В CanvasRenderer маски работают быстрее, но могут иметь ограничения по качеству
В SVGRenderer:
Сложные маски из множества объектов:
Комбинация кругов для создания эффекта множественных отверстий:
const holes = [];
for (let i = 0; i < 5; i++) {
holes.push(two.makeCircle(100 + i * 80, 250, 40));
}
const maskGroup = two.makeGroup(...holes);
image.mask = maskGroup;
Использование разных типов фигур:
Комбинация:
создаёт эффект «живой» маски, применяемый в:
image.opacity = 0.7;
Работает независимо от маски, но визуально смешивается с ней.
Обводка не учитывается в маске, если не преобразована в заливку.
При работе с несколькими объектами внутри маски полезно:
временно отключать маску:
image.mask = null;изменять цвет элементов маски:
circle.fill = 'red';проверять трансформации групп
При построении масштабных сцен рекомендуется:
Two.js допускает использование маски у объекта, который сам находится в маске:
inner.mask = anotherMask;
outer.mask = inner;
Это позволяет создавать:
Создание объектов маски динамически:
function createRandomMask() {
const shapes = [];
for (let i = 0; i < 10; i++) {
shapes.push(two.makeCircle(
Math.random() * 500,
Math.random() * 500,
Math.random() * 50
));
}
return two.makeGroup(...shapes);
}
image.mask = createRandomMask();
Сложные маски в Two.js представляют собой мощный инструмент композиции, позволяющий управлять видимостью объектов на уровне геометрии и анимации. Их использование открывает возможности для создания выразительных визуальных эффектов, выходящих за рамки простых форм и статичных сцен.