Уявіть: користувач проводить пальцем по екрану, і за ним тягнеться шлейф із 500 частинок, кожна з яких реагує на швидкість і напрямок із затримкою 100 мс. Або фоновий патерн плавно деформується, уникаючи повторень, із частотою кадрів 120 FPS. Keyframes для таких задач не підходять — потрібен інший підхід. Ми спеціалізуємося на алгоритмічно генерованих анімаціях, що працюють на GPU і не гальмують UI. Гарантуємо плавні 60 FPS навіть на пристроях п'ятирічної давності. Використовуємо Metal та OpenGL ES, на Flutter — Impeller. Наш досвід включає понад 50 успішних проєктів із процедурними анімаціями — від ігор до освітніх додатків. Такі анімації економлять до 40% бюджету на розробку ефектів порівняно з покадровими. Наші рішення охоплюють iOS анімації, Android анімації та Flutter анімації, а також GPU анімації на всіх платформах. Якщо вам потрібна консультація щодо впровадження, зв'яжіться з нашими інженерами.
Коли потрібні процедурні анімації?
Вони виправдані, коли:
- Анімація реагує на input у реальному часі (дотик, акселерометр, мікрофон)
- Анімація залежить від даних, які невідомі заздалегідь (графік погоди, пульс)
- Варіативність нескінченна — keyframe-підхід нереальний
- Потрібен ефект «живого» фону або ambient animation
Як процедурні анімації вирішують проблему динамічного контенту?
Процедурні анімації обчислюються алгоритмом у реальному часі, а не відтворюють заздалегідь записані кадри. Це дає нескінченну варіативність без збільшення розміру додатка. Наприклад, Verlet integration дозволяє симулювати інерцію та пружини для «тягучих» елементів, що слідують за пальцем із затримкою. А Perlin noise створює органічні патерни без явних повторень.
Системи частинок на різних платформах: порівняння
| Платформа |
Вбудовані інструменти |
Кастомна реалізація |
Продуктивність |
| iOS (Swift) |
CAEmitterLayer + CAEmitterCell |
Metal compute shader |
Відмінна: GPU прискорення, 120 FPS |
| Android (Kotlin) |
немає вбудованого particle engine |
OpenGL ES GLSurfaceView, Canvas + Choreographer |
Хороша: вимагає ручної оптимізації |
| Flutter (Dart) |
particles_flutter, flame |
CustomPainter + AnimationController |
Хороша: підтримує Impeller GPU |
| React Native (TS) |
react-native-confetti |
react-native-skia (Skia Canvas) |
Середня: залежить від bridge |
На iOS Apple Documentation відзначає CAEmitterLayer як найпродуктивніший варіант для простих емітерів: він вдвічі швидший за SpriteKit по CPU. Але кожна частинка ідентична; для унікальної поведінки пишемо Metal-шейдер. На Android для складних систем використовуємо OpenGL ES. У Flutter починаючи з останніх версій доступний GPU API, що прискорює шумові анімації на 30%. На старих пристроях, таких як iPhone 6s, frame time не перевищує 8 мс.
Фізичне моделювання: пружини та інерція
Процедурна анімація на основі фізики — це не spring(dampingRatio:). Це чисельне інтегрування рівнянь руху на кожному кадрі.
Найпростіша пружинна система (Verlet integration):
// Оновлюємо кожен кадр через CADisplayLink
func update(dt: Double) {
let springForce = (targetPosition - currentPosition) * stiffness
let dampingForce = velocity * -damping
let acceleration = (springForce + dampingForce) / mass
velocity += acceleration * dt
currentPosition += velocity * dt
}
Це дає поведінку, не обмежену бібліотечними параметрами: можна задати будь-яку масу, жорсткість, затухання. Використовується для «тягучих» елементів, що слідують за пальцем із затримкою, анімації волосся/хвостів, прапорів.
Деталі реалізації на Android
На Android використовуємо `ValueAnimator` з кастомним `TypeEvaluator` для чисельного інтегрування. Для складних систем застосовуємо `RenderScript` або OpenGL ES compute shaders. Приклад налаштування пружини: `stiffness = 100`, `damping = 10`, `mass = 1`.
Шумові алгоритми для органічного руху
Perlin noise та Simplex noise — основа для органічних ambient-анімацій. Фон, що «дихає» без повторюваних патернів; форма, що повільно деформується; колір, що плавно змінюється.
| Алгоритм |
Розмірність |
Продуктивність |
Застосування |
| Perlin noise |
2D/3D |
Середня (CPU > GPU) |
Текстури, ландшафти |
| Simplex noise |
2D/3D/4D |
Висока (GPU friendly) |
Органічний рух, рідини |
Приклад розрахунку шуму на iOS через simd:
// Simplex noise функція → значення float в діапазоні [-1, 1]
let noiseValue = simplexNoise2D(x: Float(time * 0.3), y: Float(index) * 0.5)
let yOffset = noiseValue * amplitude
У Flutter — пакет noise або написання на Dart. У шейдерах Flutter (з підтримкою GPU) — float noise(vec2 p) прямо в GLSL.
Що входить в роботу
- Опрацьовуємо алгоритм анімації за ТЗ або референсами.
- Реалізуємо з оптимізацією під цільовий FPS. Ціль: frame time < 8 мс для 120 Гц, < 12 мс для 60 Гц.
- Інтегруємо з системою подій додатка (input, data updates).
- Профілюємо через Instruments або Android Studio Profiler.
- На iOS — GPU utilization < 60% при idle.
Хочете такі анімації? Отримайте консультацію щодо вашого проєкту.
Процес роботи
- Аналітика: уточнюємо вимоги, референси, цільові пристрої. На етапі аналітики визначаємо цільовий FPS — зазвичай 60 або 120 Гц.
- Проєктування алгоритму: вибір методу (частинки, фізика, шум) та оцінка продуктивності.
- Реалізація з використанням нативного стеку (Metal, OpenGL ES, Skia).
- Тестування на реальних пристроях з профілюванням.
- Деплой з інтеграцією в CI/CD.
Терміни: від 3 до 5 днів залежно від складності фізичної моделі та кількості платформ. Вартість розраховується індивідуально — зв'яжіться для оцінки вашого проєкту.
Наша команда має 10+ років досвіду в мобільній розробці, реалізувала понад 50 проєктів з процедурними анімаціями. Ми працюємо на ринку більше 5 років. Наші інженери мають досвід роботи з StoreKit 2, App Store Connect, Google Play Console, TestFlight. Ми гарантуємо дотримання App Store Review Guidelines та високу якість коду.
Замовте процедурні анімації для вашого додатка — отримайте консультацію щодо вашого проєкту вже сьогодні. Ми допоможемо реалізувати динамічні ефекти без втрати продуктивності.
Анімації в мобільних додатках: 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 використовується як базова специфікація.