В интерфейсной анимации маскирование и клиппинг используются для
управления видимостью элементов без изменения их состояния в
DOM-структуре. В контексте Popmotion это достигается не встроенной
абстракцией, а комбинацией анимации свойств DOM, CSS и SVG через
styler, tween, spring,
keyframes и функциональные утилиты управления
значениями.
Самый простой механизм ограничения видимой области строится на
свойстве overflow: hidden. Оно превращает любой контейнер в
маску прямоугольной формы, внутри которой можно анимировать
содержимое.
import { styler, tween, easing } from 'popmotion';
const container = styler(document.querySelector('.container'));
const content = styler(document.querySelector('.content'));
tween({
from: { y: 100 },
to: { y: 0 },
duration: 600,
ease: easing.cubicBezier(0.2, 0.8, 0.2, 1)
}).start(v => {
content.set('y', v.y);
});
При фиксированной высоте контейнера и overflow: hidden
создаётся эффект появления снизу вверх. Такой подход применяется в
раскрывающихся списках, карточках и базовых переходах.
Ключевая особенность — отсутствие вычислительной нагрузки на сложные графические операции. Клиппинг происходит на уровне рендеринга браузера.
clip-path позволяет задавать произвольные области
видимости, включая анимацию геометрических форм.
Часто используется прямоугольное раскрытие:
import { tween, easing } from 'popmotion';
const element = document.querySelector('.panel');
tween({
from: { progress: 0 },
to: { progress: 1 },
duration: 700,
ease: easing.easeOut
}).start(v => {
element.style.clipPath = `
inset(${(1 - v.progress) * 100}% 0 0 0)
`;
});
При изменении inset создаётся эффект вертикального или
горизонтального «разворачивания».
Более сложный вариант — радиальный клиппинг:
tween({
from: 0,
to: 100,
duration: 800
}).start(v => {
element.style.clipPath = `circle(${v}% at 50% 50%)`;
});
Такой тип маски используется для эффектов «вспышки», раскрытия карточек и акцентных переходов.
SVG предоставляет более точный контроль над формой маски. В Popmotion
удобно анимировать атрибуты элементов <clipPath>.
<svg width="0" height="0">
<clipPath id="reveal">
<rect id="mask-rect" x="0" y="0" width="0" height="100" />
</clipPath>
</svg>
<div class="box"></div>
import { tween } from 'popmotion';
const rect = document.querySelector('#mask-rect');
const box = document.querySelector('.box');
box.style.clipPath = 'url(#reveal)';
tween({
from: 0,
to: 300,
duration: 900
}).start(v => {
rect.setAttribute('width', v);
});
SVG-клиппинг даёт точность пиксельного уровня и позволяет создавать сложные формы раскрытия, включая диагонали, волны и составные фигуры.
CSS-маски позволяют использовать изображения или градиенты для управления прозрачностью. Popmotion применяется для анимации параметров маски.
import { tween } from 'popmotion';
const element = document.querySelector('.photo');
tween({
from: 0,
to: 1,
duration: 1000
}).start(v => {
element.style.webkitMaskImage = `
linear-gradient(to right, rgba(0,0,0,${v}) 0%, rgba(0,0,0,1) 100%)
`;
});
Такой подход используется для плавного проявления изображений с мягкими краями.
Градиентная маска позволяет управлять не только видимостью, но и плотностью появления, создавая эффект растворения.
Распространённая техника — использование отдельного DOM-слоя в роли маски. Этот слой анимируется Popmotion и физически перекрывает контент.
<div class="wrapper">
<div class="mask"></div>
<div class="content"></div>
</div>
import { styler, spring } from 'popmotion';
const mask = styler(document.querySelector('.mask'));
spring({
from: { scaleX: 1 },
to: { scaleX: 0 },
stiffness: 120,
damping: 20
}).start(v => {
mask.set(v);
});
При transform-origin: left создаётся эффект
«сдвигающейся шторки». Такой способ часто оказывается быстрее, чем
clip-path, так как использует GPU-трансформации.
Семантически это не маска, но визуально эквивалентный эффект достигается через масштабирование.
import { tween } from 'popmotion';
const panel = document.querySelector('.panel');
tween({
from: 0,
to: 1,
duration: 500
}).start(v => {
panel.style.transform = `scaleY(${v})`;
});
При установке transform-origin: top элемент раскрывается
сверху вниз, имитируя клиппинг.
Этот подход часто используется в интерфейсах с высокой частотой анимаций, где критична производительность.
Сложные интерфейсы используют комбинации нескольких техник:
overflow: hidden для контейнеровtransform для GPU-анимацииclip-path для геометрической точностиПример комбинированного раскрытия карточки:
import { timeline, tween } from 'popmotion';
const card = document.querySelector('.card');
const image = document.querySelector('.card__image');
timeline([
tween({
from: { y: 40, opacity: 0 },
to: { y: 0, opacity: 1 },
duration: 300
}),
tween({
from: 0,
to: 1,
duration: 600
})
]).start(v => {
card.style.transform = `translateY(${v[0].y}px)`;
card.style.opacity = v[0].opacity;
image.style.clipPath = `inset(${(1 - v[1]) * 100}% 0 0 0)`;
});
Такая композиция позволяет разделять движение контейнера и раскрытие содержимого.
Popmotion позволяет связывать значения с геометрией интерфейса, создавая динамические маски, реагирующие на положение курсора или касания.
import { value, pointer } from 'popmotion';
const mask = document.querySelector('.mask');
const pointerTracker = pointer({
x: 0,
y: 0
}).start(v => {
mask.style.clipPath = `circle(120px at ${v.x}px ${v.y}px)`;
});
Подобные эффекты применяются в интерактивных подсветках и локальных reveal-анимациях.
Маскирование имеет разную стоимость вычислений:
transform и opacity — минимальная
нагрузка, оптимальны для частых анимацийoverflow: hidden — практически нулевая стоимость,
ограничена прямоугольной формойclip-path — средняя нагрузка, зависит от сложности
формыmask-image — высокая нагрузка при сложных градиентах и
больших элементахПри построении анимационных систем на Popmotion выбор техники маски напрямую влияет на стабильность FPS.
Распространённый паттерн — движение маски как отдельного слоя, перекрывающего контент:
import { tween, easing } from 'popmotion';
const curtain = document.querySelector('.curtain');
tween({
from: { x: 0 },
to: { x: 100 },
duration: 800,
ease: easing.easeInOut
}).start(v => {
curtain.style.transform = `translateX(${v.x}%)`;
});
При фиксированном контейнере создаётся эффект горизонтального открытия интерфейса.
Popmotion spring-движок позволяет связывать маскирование с инерцией движения, что делает раскрытия менее механическими.
import { spring } from 'popmotion';
const panel = document.querySelector('.panel');
spring({
from: 0,
to: 1,
stiffness: 180,
damping: 18
}).start(v => {
panel.style.clipPath = `inset(${(1 - v) * 100}% 0 0 0)`;
});
Физическая модель сглаживает ускорение и создаёт более естественное раскрытие маски.
При переходах между экранами маска часто используется как связующее звено между состояниями:
Такой подход позволяет скрывать резкие изменения DOM и создавать непрерывность визуального потока без дополнительных библиотек маршрутизации анимаций.