Маскирование в Two.js основано на использовании одного объекта в качестве области видимости для другого. Любая фигура или группа может выступать маской, ограничивая отображение дочернего элемента только той областью, где маска «прозрачна».
Ключевые особенности:
maskTwo.Path,
Two.Group, Two.Circle и др.)Пример базового применения:
const two = new Two({ width: 500, height: 500 }).appendTo(document.body);
const rect = two.makeRectangle(250, 250, 300, 300);
rect.fill = 'blue';
const circleMask = two.makeCircle(250, 250, 100);
rect.mask = circleMask;
two.update();
В этом примере прямоугольник отображается только внутри круга.
Стандартная маска в Two.js работает по принципу «показать внутри формы». Это означает:
Иногда требуется противоположное поведение:
Такой эффект называется инвертированием маски.
Инвертированная маска — это логическое отрицание стандартной маски:
| Тип маски | Что видно |
|---|---|
| Обычная | Внутри формы |
| Инвертированная | Вне формы |
В Two.js нет встроенного свойства вроде
invertMask = true, поэтому инвертирование достигается через
композицию объектов.
Создаётся большая фигура (обычно прямоугольник), покрывающая всю сцену, и из неё «вырезается» область маски.
const two = new Two({ width: 500, height: 500 }).appendTo(document.body);
// Основной объект
const rect = two.makeRectangle(250, 250, 300, 300);
rect.fill = 'green';
// Большая маска
const fullMask = two.makeRectangle(250, 250, 500, 500);
// Вырезаемая область
const hole = two.makeCircle(250, 250, 100);
// Группа маски
const maskGroup = two.makeGroup(fullMask, hole);
// Настройка режима объединения
maskGroup.subtractions = [hole];
// Применение маски
rect.mask = maskGroup;
two.update();
subtractionsПри использовании CanvasRenderer возможно ручное
управление композитингом через глобальные операции наложения
(globalCompositeOperation).
destination-outctx.globalCompositeOperation = 'destination-out';
Это приводит к «вырезанию» формы из уже нарисованного изображения.
При использовании SVGRenderer Two.js генерирует
<clipPath>. Инверсия может быть реализована
через:
mask вместо clipPath<mask>Однако:
Один из наиболее универсальных способов — комбинирование двух масок:
Создать группу, представляющую весь экран
Добавить в неё:
Назначить группу как маску
const two = new Two({ width: 600, height: 400 }).appendTo(document.body);
// Контент
const content = two.makeRectangle(300, 200, 400, 300);
content.fill = 'orange';
// Полная область
const full = two.makeRectangle(300, 200, 600, 400);
full.fill = 'white';
// Отверстие
const hole = two.makeCircle(300, 200, 80);
hole.fill = 'black';
// Группа маски
const mask = two.makeGroup(full, hole);
// Назначение
content.mask = mask;
two.update();
Инвертированные маски особенно полезны при анимации:
two.bind('update', function(frameCount) {
hole.translation.x = 300 + Math.sin(frameCount * 0.05) * 100;
});
Эффект:
Инвертированные маски могут быть затратными:
Причины:
Причины:
Причины:
const hole1 = two.makeCircle(200, 200, 50);
const hole2 = two.makeCircle(400, 200, 50);
maskGroup.add(hole1, hole2);
maskGroup.subtractions = [hole1, hole2];
Можно использовать Two.Path:
const path = new Two.Path([
new Two.Anchor(100, 100),
new Two.Anchor(200, 100),
new Two.Anchor(200, 200),
new Two.Anchor(100, 200)
], true);
| Метод | Простота | Гибкость | Производительность |
|---|---|---|---|
| Большая форма + вырез | Средняя | Высокая | Средняя |
| Canvas compositing | Низкая | Очень высокая | Высокая |
| SVG mask | Низкая | Очень высокая | Высокая |
Маска наследует трансформации:
translationrotationscaleВажно:
Инвертированные маски хорошо сочетаются с альфа-каналом:
full.opacity = 0.8;
Эффект:
Типичные сценарии:
Инвертирование масок превращает обычное маскирование в мощный инструмент визуального управления, позволяя строить сложные композиции без изменения самих объектов сцены.