Жестовые анимации в мобильном приложении: реализация и калибровка

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.

Разработка и поддержка любых видов мобильных приложений:

Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Услуги, которые мы предлагаем
Показано 1 из 1Все 1734 услуг
Жестовые анимации в мобильном приложении: реализация и калибровка
Сложный
~2-3 дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    858
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    743
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1160
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    1034
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    968
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    562

Реализация жестовых анимаций (Interactive Gesture Animations) в мобильном приложении

Мы создаем жестовые анимации, которые не тормозят и не выглядят дешево. Наш опыт — 5+ лет в мобильной разработке, более 20 проектов с кастомными анимациями. Разница между жестовой анимацией и обычной в том, что она прерываема. Пользователь тянет карточку, передумывает на середине, и она должна вернуться обратно с физически достоверным поведением — не просто прыгнуть в исходное положение, а «отпружинить» с учётом накопленной скорости. Это и есть интерактивная жестовая анимация — анимация, управляемая пальцем в реальном времени. Средняя стоимость реализации одного такого паттерна — $2500, а экономия на доработках в долгосрочной перспективе может составить до $1500 в месяц.

Если вы не уверены в сроках разработки, свяжитесь с нами — оценим срок и стоимость бесплатно.

Почему синхронизация скорости — главный вызов?

Ключевой параметр любой жестовой анимации — связь между скоростью жеста в момент отпускания (gestureRecognizer.velocity) и параметрами анимации завершения. Если их не синхронизировать, получается «прыжок»: палец движется с одной скоростью, а объект заканчивает движение с другой.

На iOS UIViewPropertyAnimator решает это нативно через continueAnimation(withTimingParameters:durationFactor:):

@objc func handlePan(_ gesture: UIPanGestureRecognizer) {
    let translation = gesture.translation(in: view)
    switch gesture.state {
    case .changed:
        animator?.fractionComplete = translation.y / totalDistance
    case .ended:
        let velocity = gesture.velocity(in: view)
        let springVelocity = abs(velocity.y) / (totalDistance - translation.y)
        let timing = UISpringTimingParameters(dampingRatio: 0.8,
                                              initialVelocity: CGVector(dx: 0, dy: springVelocity))
        animator?.continueAnimation(withTimingParameters: timing, durationFactor: 0)
    default: break
    }
}

fractionComplete — это прямое управление прогрессом анимации жестом. Значение 0.0 — начало, 1.0 — конец. Пользователь буквально «тащит» анимацию за собой. Для глубокого понимания рекомендую официальную документацию UIKit.

Как реализовать свайп для отклонения карточки?

Классический паттерн в стиле Tinder или списков задач: карточка следует за пальцем, при достижении порога — улетает, при недостаточном смещении — возвращается.

Три параметра, которые нужно откалибровать:

  • Порог отпускания — обычно 30-40% ширины экрана или скорость > 800 pt/s
  • Угол вращения — transform = CGAffineTransform(rotationAngle: translation.x / screenWidth * 0.3) — создаёт ощущение физики
  • Скорость анимации улёта — должна соответствовать скорости жеста, иначе карточка «тормозит» в воздухе

На Android реализуем через ViewDragHelper или ItemTouchHelper (для RecyclerView). ItemTouchHelper хорош для списков, но ограничен: кастомный feedback рисунок требует переопределения onChildDraw. В Flutter — Dismissible для простых случаев, GestureDetector + AnimationController с fling() для сложных. fling() принимает velocity напрямую из DragEndDetails.velocity.pixelsPerSecond — это именно та синхронизация, о которой говорим.

Сравнение подходов на разных платформах

Параметр iOS Android Flutter
Синхронизация velocity UIViewPropertyAnimator.continueAnimation ViewDragHelper + VelocityTracker fling(velocity)
Свайп карточки fractionComplete + UISpringTimingParameters ItemTouchHelper + RecyclerView Dismissible + DragTarget
Pull-to-refresh кастом ScrollView offset + Lottie Custom SwipeRefreshLayout + Lottie RefreshIndicator + AnimationController

Сравнение времени отклика: жестовые vs обычные анимации

Тип анимации Время отклика на касание Прерывание Физичность
Жестовая < 16 мс Да Высокая
Обычная 100-200 мс Нет Низкая

Pull-to-refresh с кастомной анимацией

Стандартный UIRefreshControl и SwipeRefreshLayout не поддерживают кастомную анимацию индикатора. Реализуем через ScrollView с отрицательным offset: когда contentOffset.y < -threshold, включаем кастомный индикатор с параметром прогресса = abs(offset.y) / threshold. Lottie-анимация, привязанная к setProgress(), даёт произвольный дизайн. Для Lottie-анимаций используем LottieAnimationView.setProgress() на iOS и LottieDrawable.setProgress() на Android, что позволяет точно привязать прогресс анимации к смещению.

Drag & Drop с физическим поведением

На iOS — UIDragInteraction + UIDropInteraction для cross-app DnD, UILongPressGestureRecognizer + UIViewPropertyAnimator для внутриэкранного. Важно: при поднятии элемента добавляем scale-анимацию (1.05) и тень — визуальный сигнал «я держу объект». При возврате — UISpringTimingParameters с высоким dampingRatio (0.9) для эффекта «мягкой посадки».

Тестирование и калибровка

  1. Настройте Slow Animations в симуляторе для визуальной отладки.
  2. Запустите Xcode Instruments — Animation Hitches на физическом устройстве, добейтесь GPU frame time не более 16ms (60fps).
  3. Проверьте все состояния: удержание, быстрый свайп, повторное касание во время анимации.
  4. Убедитесь, что параметры анимации (damping, stiffness) согласованы с дизайном.
Примечание Для глубокой отладки используйте Xcode Instruments и Profile GPU Rendering на Android.

Жестовые анимации обязательно тестируем на физическом устройстве — эмулятор не воспроизводит точную сенсорную физику. Slow Animations в симуляторе помогает поймать артефакты, но реальное ощущение — только на железе. На Android используйте ViewPropertyAnimator и проверяйте gpu frame time через Profile GPU Rendering. В релизной сборке удостоверьтесь, что ProGuard не вырезал классы Lottie: добавьте -keep class com.airbnb.lottie.** { *; }.

Для калибровки анимаций под ваш дизайн свяжитесь с нами — мы учтём все нюансы.

Что входит в реализацию

  • Разработка прототипа анимации с калибровкой параметров
  • Интеграция с вашим дизайном (Lottie, Rive или Core Animation)
  • Тестирование на 5+ физических устройствах
  • Передача исходного кода с комментариями
  • Поддержка в течение 2 недель после релиза

Срок реализации: 2–3 дня на один паттерн жестовой анимации, включая интеграцию и калибровку под конкретный дизайн. В среднем стоимость одного паттерна составляет $2500, что в 1.5 раза быстрее и дешевле, чем разработка с нуля без готовых наработок. Гарантируем плавность 60fps на всех устройствах. Получите консультацию по вашему проекту — свяжитесь с нами для оценки.

Анимации в мобильных приложениях: 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:) из iOS 17.

Как 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.

Lottie vs 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 — стандарт для размеченной векторной анимации, Rive — более гибкий инструмент с физикой и state machine.

Spring-физика и Hero transitions: как добиться естественности

Spring-анимация ощущается естественно потому что имитирует физику — массу, жёсткость и демпфирование. В SwiftUI: Animation.spring(response:dampingFraction:). В Android Compose: spring(dampingRatio = Spring.DampingRatioMediumBouncy).

Для Hero-переходов (элемент «перелетает» между экранами) на iOS используем UIViewControllerTransitioningDelegate + UIViewControllerAnimatedTransitioning. В SwiftUI с iOS 17 — matchedTransitionSource + navigationTransition(.zoom). На Flutter — Hero виджет, который работает из коробки.

Как избежать типичных ошибок в Hero transitions?

Анимация начинается нормально, но на целевом экране элемент «прыгает» в финальную позицию. Причина — AutoLayout constraints применяются до завершения анимации. Решение: layoutIfNeeded() в блоке анимации или использование transform вместо frame-изменений.

Что входит в работу: анимационный слой под ключ

  • Интеграция Lottie/Rive-файлов в дизайн-систему
  • Код gesture-driven переходов (bottom sheets, drawers, карусели)
  • Тестирование на реальных устройствах (iOS 15–17, Android 10–14)
  • Документация по анимациям (архитектура, ключи состояний)
  • Поддержка при обновлении дизайна (гарантия 30 дней)

У нас 5+ лет опыта в мобильной разработке, более 30 проектов с анимациями, сертифицированные iOS/Android разработчики.

Сроки выполнения

  • Базовые экранные переходы и микроинтеракции — 1 неделя.
  • Lottie/Rive интеграция с дизайн-системой — 3-5 дней после получения финальных файлов.
  • Кастомная gesture-driven интерактивность (sheet, drawer, карусель с физикой) — 1-2 недели.

Напишите нам — добавим анимации под ключ за 2 недели. Первая консультация бесплатно.