Motion-дизайн та анімації інтерфейсів
1) Навіщо анімація в продукті
Анімація - це навігація в часі. Вона:- пояснює причинно-наслідкові зв'язки (куди зник, звідки з'явився елемент),
- спрямовує увагу на головну дію,
- підтверджує результат (feedback) і зменшує когнітивне навантаження,
- робить переходи передбачуваними і «відчутними».
Правило № 1: сенс> стиль. Будь-яка анімація відповідає на питання "що сталося і як це пов'язано зі мною? ».
2) Базові принципи
1. Ієрархія руху: першими рухаються контейнери, потім вміст, потім деталі.
2. Постійність: однакові патерни для однакових дій.
3. Економія: мінімум властивостей, мінімум кадрів; краще коротше і ясніше.
4. Реалістична фізика: прискорення на початку, уповільнення в кінці; відсутні «ривки».
5. Оборотність: «назад» відчувається дзеркально «вперед».
6. Доступність: поважайте системні налаштування зниження анімації.
3) Тривалості та криві (рекомендації)
3. 1 Тривалості (desktop/mobile)
Hover: 120-180 мс
Focus/Pressed: 80-120 мс
Tooltip/Toast: вхід 180-240 мс, вихід 120-160 мс
Модалки/дроуери: 200-320 мс
Переходи екранів: 240-360 мс
Скролл-прив'язки/паралакс: ≤ 200 мс на сегмент, уникати нескінченних циклів
3. 2 Криві
Основна: `cubic-bezier(0. 2, 0. 0, 0. 2, 1)'- природний «матеріальний» темп
Вхід швидше, вихід м'якше: `cubic-bezier(0. 05, 0. 7, 0. 1, 1)`
Пружність (рідко, акцент): `cubic-bezier(0. 2, 0. 8, 0. 2, 1. 2)'з обмеженням overshoot ≤ 8px/8 °
Правило: не використовуйте лінійну інтерполяцію для переміщень і opacity одночасно - відчуття «механічності».
4) Хореографія переходів
Поява: легкий масштаб 0. 98→1. 0 + fade-in, зміщення 8-16 px по осі виникнення.
Зникнення: зворотний порядок, швидше входу (−20 -30%).
Перегортання/зміна вкладок: загальна «основа» (контейнер) зсувається на 16-24 px; активна вкладка підсвічується до початку руху.
Списки: послаблюйте каскад (stagger 20-40 мс/елемент, не більше 6-8 елементів).
5) Мікро-взаємодії (patterns)
Кнопка (hover/press): тінь + легкий підкрол/scale 0. 98; pressed відскакує ≤ 80 мс.
Фокус: контрастне кільце без blur; анімуйте товщину/прозорість, а не glow.
Інпути: каретка/підсвічування поля на focus; помилки - струшування ≤ 6 px, ≤ 140 мс, 1 цикл.
Toggle/Checkbox: снап до кінцевого положення, затримка кліка не більше 60-80 мс.
Скелетон/завантаження: shimmer 1200-1600 мс, амплітуда яскравості ≤ 20%, без різких спалахів.
6) Стану контенту
Loading → Success/Empty/Error: один «канал» руху; не змішуйте різні напрямки.
Toast/Alerts: прилітають з боку джерела події (наприклад, знизу-праворуч для дій користувача).
Pull to refresh: розтягнення з пружним відпружинюванням; час повернення ≤ 250 мс.
7) Доступність (A11y) і безпека
Підтримуйте'prefers-reduced-motion: reduce`: замінюйте переміщення на fade/scale ≤ 1% або статичний перехід.
Уникайте спалахів> 3 в секунду і великих контрастних миготінь (фотосенситивна епілепсія).
Не використовуйте сильний паралакс/зум у користувачів з історією заколисування; робіть опцію відключення.
Фокус-стилі завжди видимі без анімації (не тільки колір/рух).
8) Продуктивність (60 FPS як мета)
Анімуйте тільки opacity і transform (translate/scale/rotate); уникайте'top/left/width/height'.
Включайте композитинг: `transform: translateZ(0)` или `will-change: transform, opacity'( помірно).
Мінімізуйте repaint: не анімуйте тіні з великим blur і фільтри на безлічі елементів.
Розбивайте великі переходи на батчі; використовуйте requestAnimationFrame.
Для списків - віртуалізація/перерозмітка поза екраном.
9) Токени motion в дизайн-системі
json
{
"motion": {
"duration": { "xs": 100, "sm": 160, "md": 220, "lg": 280, "xl": 340 },
"easing": {
"standard": "cubic-bezier(0. 2, 0. 0, 0. 2, 1)",
"emphasis": "cubic-bezier(0. 05, 0. 7, 0. 1, 1)",
"decelerate": "cubic-bezier(0. 0, 0. 0, 0. 2, 1)",
"accelerate": "cubic-bezier(0. 4, 0. 0, 1, 1)"
},
"stagger": { "listItem": 30, "maxItems": 8 }
}
}
Іменування: `motion.{duration|easing|stagger}.{role}` — `hover`, `focus`, `overlayIn`, `pageTransition`, `listItem`.
10) Реалізація (CSS/JS/React)
CSS-змінні:css
:root {
--motion-dur-sm: 160ms;
--motion-dur-md: 220ms;
--motion-ease: cubic-bezier(0. 2, 0, 0. 2, 1);
}
@media (prefers-reduced-motion: reduce) {
{ animation: none! important; transition-duration: 0. 01ms! important; }
}
Компонент (Framer Motion, приклад):
tsx import { motion, AnimatePresence } from "framer-motion";
export function Modal({ open, children }) {
return (
<AnimatePresence>
{open && (
<motion. div initial={{ opacity: 0 }}
animate={{ opacity: 1, transition: { duration: 0. 22 } }}
exit={{ opacity: 0, transition: { duration: 0. 16 } }}
className="fixed inset-0 bg-black/50"
>
<motion. div initial={{ y: 16, scale: 0. 98, opacity: 0 }}
animate={{ y: 0, scale: 1, opacity: 1, transition: { duration: 0. 24, ease: [0. 2,0,0. 2,1] } }}
exit={{ y: 8, scale: 0. 99, opacity: 0, transition: { duration: 0. 18 } }}
className="m-auto max-w-lg rounded-2xl bg-white p-6"
>
{children}
</motion. div>
</motion. div>
)}
</AnimatePresence>
);
}
Lottie/SVG: використовуйте для ілюстративних порожніх станів і onboarding; не для критичних контролів. Оптимізуйте та кешуйте.
11) Патерни завантаження
Skeleton замість спінера там, де відома структура контенту.
Progress: детермінований бар, якщо відомий прогрес; індетермінований - з рівномірним темпом, без «ривків».
Уникайте «плаваючих» skeleton при перестроюванні - закріплюйте розміри.
12) Переходи між сторінками/екранами
Зберігайте точку уваги (shared element transitions) - картка «розкривається» в деталь.
Навігація «вглиб» йде вперед/вправо/вгору, «назад» - назад; напрямок єдиний для платформи.
Фонова підкладка затемнюється до 40-60% при оверлеях.
13) Специфіка iGaming
Spin / Reveal: один короткий розгін (≤ 200 мс) + рівномірне обертання + м'яке загасання; заборона на нескінченні цикли без дії.
Win/Jackpot: сплеск світла ≤ 500 мс, без строба; дубль звуком на низькій гучності; текст перемоги читабельний (AAA за контрастом).
Турніри/рейтинги: інкремент рахунку - лічильник з табличними цифрами і легким кроком 40-60 мс/одиницю (батчами), без «стрибків» layout.
Відповідальна гра: повідомлення та ліміти без відволікаючих ефектів; анімація мінімальна, акцент на читабельність.
14) Анти-патерни
Затримки> 120 мс до відгуку на клік.
«Ліфт» з opacity + scale 0. 9→1. 05→1. 0 з overshoot на кожну дрібницю.
Паралакс фону, що конфліктує зі скроллом.
Нескінченні мерехтіння/пульсації.
Анімація властивостей layout/paint ('height','left','filter: blur ()') на безлічі елементів.
Непостійні криві і тривалості у однакових дій.
15) Процес і QA
У дизайні:- Прототипи з таймінгами/кривими; хореографія на рівні фреймів.
- Каталог motion-токенів і приклади для компонентів.
- Юніт-тести видимості/станів (переходи завершуються як очікується).
- Візуальні тести (снапшоти кінця анімацій).
- Профілювання (Performance/Timeline) на сценах з максимальним навантаженням.
- Підтриманий'prefers-reduced-motion'.
- Тільки transform/opacity.
- Тривалості і криві відповідають токенам.
- Немає спалахів> 3/сек і сильного стробу.
- Skeleton замість спінера, де можливо.
- Переходи оборотні і передбачувані.
16) Документація в дизайн-системі
«Motion-токени»: duration/easing/stagger з прикладами.
«Патерни переходів»: модалки, списки, вкладки, сторінки.
«A11y & Performance»: гайд по reduce-motion і композитингу.
«Do/Don’t»: короткі кліпи з вдалими/невдалими прикладами.
Коротке резюме
Motion-дизайн - це мова причин і наслідків. Тримайте таймінги короткими, криві узгодженими, а властивості - дешевими для рендера. Поважайте доступність, документуйте токени і перевіряйте продуктивність. Тоді анімація посилить UX і не завадить швидкості і ясності інтерфейсу.