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).

Нажимая кнопку, вы соглашаетесь на обработку данных.