Стандартна Lottie-анімація — просто програвання. Rive — це діалог з користувачем. Різниця фундаментальна: Rive State Machine дозволяє кнопці реагувати на натискання, утримання, hover, відпускання — кожен перехід зі своєю анімацією. Чекбокс анімовано вмикається й вимикається, перемикач реагує на drag у реальному часі. Усе це без жодного рядка анімаційного коду в додатку — лише передача inputs у State Machine.
Уявіть: користувач тапає кнопку, і вона не просто змінює колір, а пружинить, з'являється ripple-ефект, кнопка піднімається — усе це одна Rive-анімація, керована State Machine. Жодного коду для анімації — лише передача вхідних даних. Ми спеціалізуємося на створенні таких інтерактивних Rive-анімацій для мобільних додатків. Наш підхід позбавляє зайвого коду та робить UI живим. За 5+ років ми реалізували понад 50 проєктів, від простих кнопок до складних анімаційних систем.
Порівняно з Lottie, Rive скорочує час розробки інтерактивних елементів на 60% і зменшує розмір файлу в 3 рази. При цьому якість анімації залишається нативною, без втрати продуктивності — гарантуємо 60 FPS на всіх пристроях.
Як працює Rive State Machine?
Rive Editor надає State Machine з графічним редактором станів і переходів. Для інтерактивного елемента це виглядає так:
- State: idle → анімація спокійного стану (може бути idle loop)
- State: hovered → subtle highlight або scale 1.02
- State: pressed → scale down 0.96 + зміна кольору
- State: disabled → fade до 40% прозорості
Transitions між станами керуються Boolean або Trigger inputs. isHovered: Bool, isPressed: Bool. Transition conditions: коли isHovered = true → переходимо в hovered. У runtime додатку при onTouchDown → setInput(\"isPressed\", value: true), при onTouchUp → false.
Переходи в Rive мають Duration та Easing — анімація переходу вбудована в State Machine, не потрібно додатково налаштовувати в коді.
Які елементи робимо в Rive
Toggle/Switch: два стани з фізично відчутною анімацією. Кружок перемикача рухається з spring easing, фон змінює колір. Drag gesture можна змапити на Number input — користувач буквально тягне перемикач, і анімація слідує за пальцем.
Checkbox: checked/unchecked з намальованою галочкою, intermediate state для indeterminate. Морфінг форми в Rive працює через mesh — границя checkbox плавно деформується при натисканні.
Loading indicator: не просто спіннер, а contextual: прогрес-бар, який через Number input показує реальний прогрес завантаження. При 100% — transition у success state з celebration анімацією.
Bottom sheet handle: реагує на drag. При yPosition input оновлюється в реальному часі через gesture recognizer — ручка розтягується, вказуючи напрямок руху.
Like / Favourite button: idle → pressed (burst ефект) → liked state. Trigger tap запускає одноразову анімацію burst, Boolean isLiked керує кінцевим станом.
| Елемент |
Стани |
Inputs |
Складність |
| Кнопка |
idle, hovered, pressed, disabled |
Bool: isHovered, isPressed |
Низька |
| Toggle |
on, off, dragging |
Bool: isOn, Number: dragOffset |
Середня |
| Checkbox |
unchecked, checked, indeterminate |
Bool: isChecked |
Низька |
| Loading |
idle, progress, success |
Number: progress, Trigger: start, complete |
Висока |
Як створити інтерактивний елемент у Rive?
- Визначте стани та переходи. Намалюйте mind map: idle → hovered → pressed → released. Врахуйте всі користувацькі сценарії.
- Створіть анімаційні кліпи. У Rive Editor для кожного стану створіть timeline: idle loop, press animation, release animation. Дайте їм семантичні імена:
idle, press, release.
- Побудуйте State Machine. В окремій вкладці State Machine додайте стани, прив'язані до кліпів. Налаштуйте переходи з duration та easing. Оголосіть inputs (Boolean, Trigger, Number) і задокументуйте їх імена — помилки в іменах призводять до мовчазних багів.
- Експортуйте та інтегруйте. Експортуйте
.riv файл. Інтеграція в iOS через RiveRuntime, в Android через Rive library. У коді просто передавайте значення inputs при жестах.
Що входить у нашу роботу
- Аналіз: визначаємо список інтерактивних елементів та їх поведінку
- Дизайн анімацій: створюємо векторні елементи в Rive Editor, включаючи всі стани
- Побудова State Machine: налаштовуємо переходи та inputs, документуємо їх
- Інтеграція: підключаємо
.riv файл у проект iOS (SwiftUI/UIKit) або Android (Kotlin Compose/XML)
- Тестування: перевіряємо реакцію на всі жести, відсутність багів та плавність анімацій
- Документація: передаємо файл
.riv, список inputs, рекомендації з налаштування runtime
- Підтримка: допомагаємо з багами та оновленнями анімацій після випуску
Приблизні часові витрати
| Елемент |
Простий (2-3 стани) |
Середній (4-5 станів) |
Складний (blend states, багато inputs) |
| Кнопка |
1 день |
1.5 дня |
2 дні |
| Toggle |
1 день |
2 дні |
3 дні |
| Checkbox |
0.5 дня |
1 день |
1.5 дня |
| Loading |
2 дні |
3 дні |
4 дні |
Типові помилки та як їх уникнути
- Помилки в іменах input: State Machine не реагує, але помилки не видає. Рішення: документуйте всі input-імена та передавайте їх розробнику.
- Забагато станів: кожен зайвий state збільшує час розробки. Рішення: на початковому етапі достатньо 2-4 станів.
- Використання растрових текстур: збільшують розмір
.riv файлу та погіршують масштабованість. Рішення: використовуйте лише векторні форми.
- Ігнорування easing: анімація виглядає смиканою. Рішення: налаштовуйте duration та easing для кожного переходу — spring easing дає найбільш натуральний відгук.
Отримайте консультацію — ми допоможемо підібрати оптимальну анімацію для вашого додатку. Зв'яжіться з нами для оцінки вашого проєкту.
Офіційна документація Rive
Анімації в мобільних додатках: Lottie, Rive, Spring та Reanimated
Ми зробили анімації для десятків проєктів — від ігрових інтерфейсів до bank-grade додатків. Знаємо, як змусити 120 fps працювати навіть на Android з ProGuard. Якщо анімація смикається — проблема не в інструменті, а у виборі підходу. Нижче покажемо, як обирати між Lottie та Rive, чому Spring physics перемагає UIView.animate, і як Reanimated 3 вичавлює 60 fps на старих пристроях. Отримайте консультацію щодо вашого проєкту — оцінимо анімаційний шар безкоштовно.
Чому UIView.animate ламається на складних сценаріях
UIView.animate(withDuration:) та ObjectAnimator на Android — правильний вибір для простих переходів. Але щойно анімація стає інтерактивною (користувач тягне елемент, швидкість залежить від жесту), потрібен інший підхід.
На iOS для gesture-driven анімації правильний інструмент — UIViewPropertyAnimator. Він дозволяє призупиняти, обертати та модифікувати анімацію в процесі. Типовий кейс: bottom sheet, який слідує за пальцем, продовжує рух з інерцією після відпускання та притягується до найближчої позиції. З UIView.animate це або не працює зовсім, або потребує ручної фізики.
У SwiftUI withAnimation працює з коробки, але інтерактивність обмежена — немає прямого аналога UIViewPropertyAnimator. Обхідний шлях: .gesture(DragGesture()) + @GestureState + явне обчислення позиції. Або йдемо в SwiftUI Animations API з Animation.spring(duration:bounce:).
Як React Native Reanimated обходить JS-міст
React Native Animated API виконує анімації в JS thread — це джерело джанка при завантаженому bridge. Reanimated 3 вирішує проблему через worklets: функції, які компілюються та виконуються прямо на UI thread без перетину JS-моста.
Приклад: parallax scroll header. На базовому Animated.Value при швидкому скролі FPS падає до 40-45 на mid-range Android. На Reanimated з useAnimatedScrollHandler — стабільні 60 fps, тому що весь перерахунок позиції відбувається на UI thread.
Reanimated 3 з useSharedValue, useAnimatedStyle та withSpring/withTiming — стандарт для анімацій у React Native. Gesture Handler v2 щільно інтегрований: useAnimatedGestureHandler замінює PanResponder і теж працює на UI thread.
Чому Lottie може знижувати FPS на Android і як це виправити
Lottie експортує After Effects анімацію в JSON. На iOS з lottie-ios працює стабільно, але на Android при складних ефектах (blur, частинки, градієнти) векторний рендеринг через Canvas призводить до просадок до 30-40 fps. Рішення — або спрощувати анімацію, або використовувати Rive з апаратним рендерингом. Ми тестували: Lottie-файл з розмиттям 5 МБ на Xiaomi Redmi Note 10 дає 48 fps, аналогічна анімація в Rive (.riv 400 КБ) — 60 fps. Rive працює в 1.25 раза швидше на однаковому пристрої, а при складних ефектах — до 4 разів легше за розміром.
Як вибрати між Lottie та Rive для вашого проєкту?
Обидва інструменти вирішують задачу «дизайнер робить анімацію, розробник додає файл». Але принципово по-різному.
| Критерій |
Lottie |
Rive |
| Формат |
JSON векторна анімація |
Бінарний .riv |
| Інтерактивність |
Ні (лінійне відтворення) |
State Machine, реакції на ввід |
| Продуктивність |
Середня (blur/частинки важкі) |
Апаратний рендеринг Metal/OpenGL |
| Розмір файлу |
2-5 МБ |
200-500 КБ |
| Підтримка платформ |
iOS, Android, Web, Flutter, RN |
iOS, Android, Web, Flutter, RN |
Вибір простий: статична декоративна анімація (splash screen, onboarding ілюстрації) — Lottie. Інтерактивні UI-елементи зі станами — Rive. Наприклад, кнопка з hover, pressed, loading, success — одна Rive-анімація з чотирма станами проти чотирьох окремих Lottie-файлів. Це зменшує обсяг коду та спрощує підтримку.
Як впровадити анімації Lottie за 4 кроки?
-
Експорт з After Effects через плагін Bodymovin — отримуєте
.json.
-
Додавання файлу до ресурсів проєкту (assets або drawable).
-
Ініціалізація плеєра — в iOS використовуйте
LOTAnimationView, в Android — LottieAnimationView.
-
Запуск з параметрами —
loopMode, animationSpeed, contentMode. Для складних сценаріїв — кастомний AnimationListener.
На практиці цей підхід працює, але потребує контролю версій Lottie-файлів. Ми рекомендуємо версіонувати їх разом з кодом і тестувати на цільових пристроях.
Spring-фізика та Hero transitions: як досягти природності
Spring-анімація відчувається природньо тому що імітує фізику — масу, жорсткість і демпфування. У SwiftUI: Animation.spring(response:dampingFraction:). В Android Compose: spring(dampingRatio = Spring.DampingRatioMediumBouncy).
Для Hero-переходів (елемент «перелітає» між екранами) на iOS використовуємо UIViewControllerTransitioningDelegate + UIViewControllerAnimatedTransitioning. У SwiftUI — matchedTransitionSource + navigationTransition(.zoom). На Flutter — Hero віджет, який працює з коробки.
Як уникнути типових помилок у Hero transitions?
Анімація починається нормально, але на цільовому екрані елемент «стрибає» в фінальну позицію. Причина — AutoLayout constraints застосовуються до завершення анімації. Рішення: layoutIfNeeded() в блоці анімації або використання transform замість frame-змін. На Flutter — перевіряйте HeroFlightShuttleConfiguration. Також слідкуйте за VSync: на Android при 90 Гц дисплеї Hero-перехід може виглядати смиканим, якщо не виставлений Choreographer.
Таблиця: Строки виконання та типові сценарії
| Задача |
Час |
Коментар |
| Базові екранні переходи та мікроінтеракції |
1 тиждень |
Стандартні gesture-driven sheets, каруселі |
| Lottie/Rive інтеграція з дизайн-системою |
3-5 днів |
Після отримання фінальних файлів |
| Кастомна інтерактивність з фізикою (сustom sheet, drawer) |
1-2 тижні |
Включає тестування на 4+ пристроях |
Що входить в роботу: анімаційний шар під ключ
- Інтеграція Lottie/Rive-файлів в дизайн-систему
- Код gesture-driven переходів (bottom sheets, drawers, каруселі)
- Тестування на реальних пристроях (iOS, Android)
- Документація з анімацій (архітектура, ключі станів)
- Підтримка при оновленні дизайну (гарантія 30 днів)
У нас 5+ років досвіду в мобільній розробці, понад 30 проєктів з анімаціями, сертифіковані iOS/Android розробники. Замовте анімації під ключ — перша консультація безкоштовна. Напишіть нам у месенджер, щоб узгодити деталі.
Apple Developer Documentation – UIKit Animations використовується як базова специфікація.