GH GambleHub

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 і не завадить швидкості і ясності інтерфейсу.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.