Работа с границами в анимациях на основе Popmotion строится вокруг управления значением во времени с учётом ограничений пространства движения. Границы выступают не просто пределами, а активными условиями поведения: объект либо останавливается на краю, либо отражается, либо переходит на противоположную сторону, либо ведёт себя как физическое тело с инерцией и упругостью.
Любое движение в Popmotion можно свести к изменению числового значения во времени. Граница в этом контексте — это функция постобработки значения:
Основные стратегии обработки границ:
Эти модели применяются как к простым значениям, так и к физическим анимациям (inertia, spring).
Clamping — базовая стратегия, при которой значение не может выйти за заданные пределы.
import { animate } from "popmotion";
animate({
from: 0,
to: 300,
onUpdate: v => {
const clamped = Math.max(50, Math.min(v, 250));
console.log(clamped);
}
});
В терминах поведения:
Clamping часто используется в интерфейсах, где выход за границы недопустим: ползунки, скролл-ограничения, drag within container.
Bounce-модель имитирует упругое столкновение с границей. При достижении предела скорость инвертируется с коэффициентом потерь энергии.
Базовая идея:
Упрощённая реализация:
function bounce(value, min, max, velocity, damping = 0.7) {
if (value < min) {
return {
value: min + (min - value) * damping,
velocity: -velocity * damping
};
}
if (value > max) {
return {
value: max - (value - max) * damping,
velocity: -velocity * damping
};
}
return { value, velocity };
}
Такая логика часто применяется в связке с
inertia-анимацией Popmotion, где движение продолжается
после завершения пользовательского взаимодействия.
Инерционная модель основана на начальной скорости и постепенном замедлении. Добавление границ превращает её в систему с коллизиями.
import { inertia } from "popmotion";
inertia({
velocity: 1000,
min: 0,
max: 300,
bounceStiffness: 200,
bounceDamping: 10,
onUpdate: v => console.log(v)
});
Поведение:
Физически это аналогично движению шарика в ограниченном контейнере с сопротивлением среды.
Spring-модель описывает движение к целевой точке через упругую систему. Границы в этом случае становятся дополнительными целями, активируемыми при выходе за пределы.
import { spring } from "popmotion";
spring({
from: 0,
to: 400,
stiffness: 200,
damping: 20,
min: 50,
max: 350
});
Поведение:
Такой подход используется для UI-компонентов, где важно ощущение физической связанности с контейнером.
Гибкость Popmotion позволяет внедрять произвольные стратегии поведения через функции трансформации.
Пример динамического отскока с изменяемой упругостью:
function boundaryBounce(min, max, elasticity) {
return (v, velocity) => {
let nextValue = v;
let nextVelocity = velocity;
if (v < min) {
nextValue = min;
nextVelocity = Math.abs(velocity) * elasticity;
}
if (v > max) {
nextValue = max;
nextVelocity = -Math.abs(velocity) * elasticity;
}
return { nextValue, nextVelocity };
};
}
Использование:
const resolve = boundaryBounce(0, 300, 0.6);
Такой уровень абстракции позволяет:
Наиболее частый сценарий — перемещение объекта с ограничением области и эффектом упругого возврата.
import { pointer, inertia } from "popmotion";
let x = 0;
let velocity = 0;
pointer({
onMove: (e) => {
velocity = e.velocity.x;
x = e.x;
},
onEnd: () => {
inertia({
from: x,
velocity,
min: 0,
max: 500,
bounceStiffness: 300,
bounceDamping: 15,
onUpdate: v => {
x = v;
}
});
}
});
Поведение системы:
Реалистичное поведение требует моделирования потерь:
Модель:
v' = -v * elasticity - friction
Где:
elasticity ∈ [0, 1]friction — постоянное замедлениеВ сложных сценах применяются несколько уровней контроля:
Пример композиции:
function applyBounds(v, min, max) {
if (v < min) return min;
if (v > max) return max;
return v;
}
В сочетании с инерцией это создаёт многослойную систему управления движением.
Иногда требуется не отскок, а мягкое затухание за пределами диапазона.
function softClamp(v, min, max, strength = 0.2) {
if (v < min) {
return min + (v - min) * strength;
}
if (v > max) {
return max + (v - max) * strength;
}
return v;
}
Такой подход даёт эффект:
При работе с границами в реальном времени критично:
Особенно важно в сценариях с:
Границы часто применяются после других преобразований:
Порядок вычислений:
Нарушение порядка приводит к нестабильному поведению, особенно в bounce-моделях.
При построении сложных интерфейсов границы могут быть:
Пример сегментированных границ:
Такая модель позволяет создавать нелинейные пространства движения, где ощущение физики становится частью интерфейсной логики.