Skip to content
PПромтбук
RUEN
02Motion

Easing и тайминг анимаций

Кривые easing для разных случаев, длительности, ритм — почему «всё ease-in-out 300ms» это плохо.

Спроектируй систему easing и timing.

Основа: классические кривые

--linear:       linear;
--ease:         cubic-bezier(0.25, 0.1, 0.25, 1.0);  /* CSS default */
--ease-in:      cubic-bezier(0.4, 0, 1, 1);
--ease-out:     cubic-bezier(0, 0, 0.2, 1);
--ease-in-out:  cubic-bezier(0.4, 0, 0.2, 1);

Когда что

ДействиеEasingПочему
Появление UIease-outСтарт быстро → замедление к финалу. Чувствуется как "прилёт"
Исчезновение UIease-inСтарт медленно → ускорение к финалу. Чувствуется как "ушло"
Continuous (drag, scroll)linearЕстественное движение под палец
Циклическая (loading spinner)linearПостоянная скорость
Прыжок акцентаease-in-outСимметрично, для маятниковых движений

Премиум-кривые (для специальных случаев)

/* Expo out — мощный appear effect */
--ease-expo-out: cubic-bezier(0.16, 1, 0.3, 1);

/* Back out — лёгкий "overshoot" перед остановкой */
--ease-back-out: cubic-bezier(0.34, 1.56, 0.64, 1);

/* Circ out — мягкое плавное замедление */
--ease-circ-out: cubic-bezier(0, 0.55, 0.45, 1);

Длительности (шкала)

--duration-instant:  100ms;   /* Hover, focus */
--duration-fast:     150ms;   /* Small UI changes */
--duration-normal:   200ms;   /* Default */
--duration-medium:   300ms;   /* Modal, dialog */
--duration-slow:     500ms;   /* Page transitions */
--duration-spacious: 700ms;   /* Hero animations */

Правила

  • ≤ 100ms — мозг не воспринимает как "анимацию"
  • 200ms — natural reaction time
  • 500ms — пользователь начинает ждать

  • 1000ms — почти всегда слишком долго

Размер влияет на длительность

Чем больше расстояние — тем дольше анимация (естественно):

Tooltip (10px движения):  150ms
Dropdown (50px):           200ms
Modal (центр экрана):      300ms
Page transition:           400-500ms

Stagger (каскад)

Когда анимируется группа — добавь задержку между элементами:

.item:nth-child(1) { animation-delay: 0ms; }
.item:nth-child(2) { animation-delay: 50ms; }
.item:nth-child(3) { animation-delay: 100ms; }

Stagger ≈ 50-80ms. Слишком мало — кажется одновременным. Слишком много — кажется ленивым.

Лимит: 6-8 элементов. Дальше — без stagger.

Spring physics

Альтернатива duration/easing. Параметры:

  • stiffness — насколько "тугая" пружина
  • damping — насколько "гасится" колебание
  • mass — "вес" элемента
// Framer Motion
<motion.div animate={{x: 100}} transition={{type: "spring", stiffness: 300, damping: 30}} />
  • Хорошо для интерактивных элементов (drag, swipe)
  • Естественнее duration для физических метафор
  • Сложнее предсказать (длительность зависит от расстояния)

Чёрный список

ease-in-out для всего ❌ Bounce на UI кнопках ❌ Анимация width или height без will-change ❌ Анимация на transform: scale от 0 (создаётся нулевая bounding box) ❌ Длительности кратные 500ms — это "robotic"

Тест системы

Анимация хорошо настроена если:

  1. Пользователь не замечает её — только эффект
  2. Без неё интерфейс кажется "сломанным"
  3. Все анимации на сайте чувствуются одной семьёй

Принципы

  • Меньше уникальных кривых — больше консистентность
  • 3-4 easing'а + 4-5 длительностей — достаточно
  • Симметричный enter/exit = ленивая работа. Asymmetric = professional
К подразделу «Motion»
Похожие промты