Rive: co to jest, narzędzie animacji dla Flutter i iOS

Autor: IT Sectr Opublikowano: 2026-03-01 Czas czytania: 11 min

Rive — narzędzie do tworzenia i odtwarzania interaktywnej animacji wektorowej, które łączy edytor animacji i biblioteki wykonawcze dla platform mobilnych. W przeciwieństwie do pasywnych formatów, Rive obsługuje State Machine — logikę przejść między animacjami w zależności od działań użytkownika. Według Rive Blog (2026), narzędzie jest używane w ponad 10 000 projektach, w tym Duolingo i Bumble. Więcej o innych rodzajach animacji przeczytasz w ogólnym przewodniku po animacji.

Najważniejsze

  • Rive — narzędzie do interaktywnej animacji wektorowej z własnym edytorem.
  • State Machine — wizualna logika przejść między animacjami za pomocą wyzwalaczy.
  • RiveRuntime — biblioteka odtwarzania dla iOS, Android, Flutter i Web.
  • RiveAnimation — widżet Dart dla Flutter do osadzania plików .riv w aplikacji.
  • Format .riv — kontener binarny zawierający animację i State Machine.

Czym jest Rive?

Rive (dawniej Rive.app, założona w 2016) — to edytor graficzny i wieloplatformowe środowisko uruchomieniowe do interaktywnej animacji wektorowej. W przeciwieństwie do After Effects + Bodymovin (Lottie), Rive zapewnia jedno środowisko: projektant rysuje, animuje i konfiguruje logikę przejść bezpośrednio w edytorze. Wynik jest eksportowany do pliku binarnego .riv, który waży od 2 do 50 KB w zależności od złożoności.

Główna różnica Rive od innych rozwiązań — State Machine. To wizualny graf, gdzie węzły to animacje (Idle, Hover, Press, Active), a przejścia między nimi są wyzwalane przez triggery (Touch, Drag, Boolean). Deweloper w kodzie po prostu wysyła wyzwalacze, a RiveRuntime sam decyduje, którą animację odtworzyć i jak płynnie przełączyć się między nimi. Według Rive Engineering (2026), średnia animacja .riv z State Machine zajmuje 15 KB — 5–10 razy mniej niż równoważny plik wideo.

Rive Runtime jest dostępny dla Flutter, iOS (Swift), Android (Kotlin/Java), Web (WASM) i React. Renderowanie odbywa się przez Skia (Flutter/Web), Core Graphics (iOS) lub Canvas (Android). Rive obsługuje animację kształtów (Knob, Slider, Button z niestandardową geometrią), co pozwala tworzyć w pełni animowane komponenty UI, a nie tylko dekoracyjne animacje.

Rive vs Lottie: porównanie podejść

Rive i Lottie rozwiązują różne zadania. Lottie — to odtwarzacz gotowych animacji z After Effects, optymalny do pasywnych efektów dekoracyjnych. Rive — to narzędzie do tworzenia interaktywnych animacji z własną logiką, gdzie animacja reaguje na działania użytkownika. Wybór zależy od wymaganego stopnia interaktywności.

KryteriumRiveLottie
EdytorWłasny (Rive Editor)Adobe After Effects + Bodymovin
InteraktywnośćState Machine, wyzwalacze, Boolean, NumberTylko play/pause/seek
Format.riv (binarny).json lub .lottie (protobuf)
RenderowanieSkia / Core Graphics / CanvasCanvas / Core Animation / Skia
Animowane UIKnob, Slider, Button, Input (wbudowane)Nie (tylko warstwy dekoracyjne)

Kiedy wybrać Rive: interaktywne przyciski z reakcją na kliknięcie, elementy gier (postacie ze stanami), przełączniki z animacją, dynamiczne ikony reagujące na stan. Kiedy wybrać Lottie: preloadery, polubienia, ekrany powitalne, animacje akcentowe bez logiki. Dla projektów na Flutter Rive — preferowany wybór dzięki natywnej integracji z Skia i potokiem renderowania Flutter.

Integracja Rive w Flutter (Dart)

Na Flutter RiveAnimation — główny widżet do osadzania plików .riv. Jest dostępny przez pakiet rive (oficjalny). RiveAnimation obsługuje argumenty: artboard (wybór planszy), animation (nazwa animacji), fit, alignment, controllers (dla State Machine). Dla scen interaktywnych używany jest StateMachineController.

dart
import 'package:rive/rive.dart';

// Proste odtwarzanie animacji
RiveAnimation.asset(
  'assets/animations/button.riv',
  artboard: 'Button',
  animations: const ['idle'],
  fit: BoxFit.contain,
)

// StateMachineController z wyzwalaczami
class InteractiveButton extends StatefulWidget {
  @override
  State<InteractiveButton> createState() => _InteractiveButtonState();
}

class _InteractiveButtonState extends State<InteractiveButton> {
  StateMachineController? _controller;
  SMIInput<bool>? _isPressed;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTapDown: (_) => _isPressed?.value = true,
      onTapUp: (_) => _isPressed?.value = false,
      child: RiveAnimation.asset(
        'assets/animations/button.riv',
        fit: BoxFit.contain,
        onInit: (artboard) {
          _controller = StateMachineController.fromArtboard(
            artboard, 'State Machine 1',
          );
          if (_controller != null) {
            artboard.addController(_controller!);
            _isPressed = _controller!.findInput<bool>('isPressed');
          }
        },
      ),
    );
  }
}

Najlepsze praktyki Flutter: ładuj pliki .riv asynchronicznie przez RiveAnimation.asset (wbudowany AssetBundle). Dla list (ListView) używaj jednego StateMachineController współdzielonego między elementami. Rive nie wymaga już osobnego importu — rive v0.12+ zawiera wszystkie funkcje. Dla niestandardowej animacji kontroluj RiveAnimationController bezpośrednio — zapewnia dostęp do animacji, mieszania (blend) i prędkości.

Integracja Rive w iOS (Swift)

Na iOS RiveRuntime jest reprezentowany przez klasę RiveView (UIKit) i RiveViewModel (SwiftUI). Biblioteka jest podłączana przez Swift Package Manager. RiveView renderuje pliki .riv przez Core Graphics i Metal, obsługując 120 FPS na wyświetlaczach ProMotion. Dla State Machine używany jest RiveStateMachineLayer z powiązaniem z wyzwalaczami.

swift
import RiveRuntime

// SwiftUI: RiveViewModel z animacją
struct RiveAnimationView: View {
    @State private var isPressed = false

    var body: some View {
        RiveViewModel(fileName: "button").view()
            .frame(width: 200, height: 60)
            .gesture(
                DragGesture(minimumDistance: 0)
                    .onChanged { _ in
                        if !isPressed {
                            isPressed = true
                            // Wyzwalacz przez State Machine
                        }
                    }
                    .onEnded { _ in
                        isPressed = false
                    }
            )
    }
}

// UIKit: RiveView z ręcznym sterowaniem
let riveView = RiveView()
riveView.configure(fileName: "loading", extension: "riv")
riveView.fit = .contain
riveView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(riveView)

// Sterowanie State Machine
riveView.triggerInput(named: "startAnimation")

Najlepsze praktyki iOS: używaj RiveViewModel dla SwiftUI — automatycznie zarządza cyklem życia. Dla UIKit subskrybuj RiveViewDelegate do śledzenia zdarzeń. Rive zużywa mniej CPU niż Lottie na iOS dzięki renderowaniu przez Core Graphics. Dla animacji w NavigationView/UICollectionView używaj prefetchingu przez RiveFile.preload().

Integracja Rive w Android (Kotlin)

Na Android RiveAnimationView — główny View do osadzania animacji .riv. Biblioteka app.rive:rive-android jest podłączana przez Gradle. RiveAnimationView dziedziczy po View i renderuje przez Canvas z obsługą Hardware Acceleration. State Machine jest zarządzany przez setTriggers i setInputs.

kotlin
// build.gradle.kts
implementation("app.rive:rive-android:0.9.0")

// XML layout
<app.rive.RiveAnimationView
    android:id="@+id/riveView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:rive_file="@raw/mascot"
    app:rive_artboard="Mascot"
    app:rive_animation="idle" />

// Kotlin: sterowanie State Machine
import app.rive.riveandroid.RiveAnimationView
import app.rive.riveandroid.StateMachineInput

val riveView = findViewById<RiveAnimationView>(R.id.riveView)
riveView.post {
    riveView.setTriggers("hover") "> Wysyłanie trigera do State Machine
    riveView.setInput("speed", 1.5f)
    riveView.setInput("isActive", true)
    riveView.play()
}

// Obsługa zakończenia animacji
riveView.addListener(object : RiveAnimationView.RiveListener() {
    override fun onAnimationCompleted(animationName: String) {
        Log.d("Rive", "Animation $animationName completed")
    }
})

Najlepsze praktyki Android: ładuj pliki .riv przez res/raw (wbudowane zasoby) lub assets (ładowanie przez sieć). RiveAnimationView automatycznie obsługuje lifecycle — nie wywołuj play/pause w onResume/onPause ręcznie. Dla animacji w RecyclerView używaj setOnScrollListener do wstrzymania odtwarzania podczas przewijania. Według dokumentacji Rive (2026), pliki .riv do 100 KB są parsowane w 5–10 ms na urządzeniach średniej klasy.

State Machine: logika przejść w Rive

State Machine — kluczowa możliwość Rive, która odróżnia go od pasywnych formatów animacji. To wizualny graf, gdzie wierzchołki to stany (animacje), a krawędzie to przejścia aktywowane przez wyzwalacze. State Machine jest tworzony w Rive Editor: projektant dodaje węzły animacji, łączy je liniami i przypisuje wyzwalacze (Touch, Boolean, Number). Deweloperowi pozostaje tylko wysyłać te wyzwalacze z kodu.

dart
// Flutter: pełna kontrola nad State Machine
import 'package:rive/rive.dart';

class RiveStateMachineWidget extends StatefulWidget {
  @override
  State<RiveStateMachineWidget> createState() => _RiveStateMachineWidgetState();
}

class _RiveStateMachineWidgetState extends State<RiveStateMachineWidget> {
  Artboard? _artboard;
  StateMachineController? _controller;
  SMIInput<bool>? _isHovered;
  SMIInput<double>? _progress;

  @override
  Widget build(BuildContext context) {
    return MouseRegion(
      onEnter: (_) => _isHovered?.value = true,
      onExit: (_) => _isHovered?.value = false,
      child: RiveAnimation.asset(
        'assets/interactive_icon.riv',
        onInit: (artboard) {
          _controller = StateMachineController.fromArtboard(
            artboard, 'State Machine 1',
          );
          artboard.addController(_controller!);
          _isHovered = _controller!.findInput<bool>('isHovered');
          _progress = _controller!.findInput<double>('progress');
        },
      ),
    );
  }
}

// Wysyłanie wartości numerycznej
SMIInput<double> speedInput = controller.findInput('speed');
speedInput?.value = scrollPosition;

Typy wyzwalaczy: Boolean — przełącznik (true/false), Number — wartość numeryczna (0.0–1.0 lub dowolny zakres), Trigger — jednorazowy impuls (naciśnięcie przycisku). W Rive Editor można skonfigurować wygładzanie przejść (Transition Duration) — zalecana wartość 100–300 ms dla płynności. Dla złożonych stanów UI używaj zagnieżdżonych State Machine (Nested State Machines) — każda część animacji jest zarządzana niezależnie. State Machine Rive działa na wszystkich platformach bez zmian w pliku .riv — logika przejść jest osadzona w pliku, a nie w kodzie aplikacji.

Często zadawane pytania

Czym różni się Rive od Lottie?

Rive — interaktywna animacja z State Machine, wyzwalaczami i własnym edytorem. Lottie — pasywne odtwarzanie animacji JSON z After Effects. Rive nadaje się do przycisków, gier i elementów UI reagujących na użytkownika. Lottie — do efektów dekoracyjnych (preloadery, polubienia). Rive używa formatu .riv, Lottie — JSON lub .lottie.

Czy można używać Rive bez State Machine?

Tak. Rive obsługuje proste odtwarzanie animacji bez State Machine — określ animationName w RiveAnimation.asset lub RiveView. W tym przypadku Rive działa jak Lottie: zapętlona lub jednorazowa animacja. State Machine — opcjonalna warstwa dla interaktywności. Dla projektów, które potrzebują tylko dekoracyjnej animacji, State Machine jest zbędna.

Czy Rive jest kompatybilny z Android Jetpack Compose?

Tak, przez AndroidView do osadzania RiveAnimationView w Compose. Od rive-android 0.9.0 dostępna jest otoczka Compose RiveAnimation compose() z obsługą modyfikatorów. Do zarządzania State Machine używaj remember { StateMachineHolder() }. Rive obsługuje również Compose Multiplatform na iOS przez wspólne środowisko wykonawcze Compose.

Czy Rive działa na Flutter Web?

Tak, Rive obsługuje Flutter Web przez Skia Wasm (CanvasKit) lub HTML-renderer. Zalecany jest CanvasKit dla maksymalnej wydajności. Pliki Rive są ładowane przez zapytanie HTTP (RiveAnimation.network) lub pakowane w assets. Flutter Web z Rive działa poprawnie we wszystkich nowoczesnych przeglądarkach (Chrome 90+, Safari 15+, Firefox 90+).

Jak zoptymalizować wydajność Rive na urządzeniach mobilnych?

Ogranicz liczbę jednocześnie aktywnych warstw do 20–30. Używaj Flat shading zamiast Gradient dla prostych kształtów. Do animacji z tekstem używaj System Text (nie tekstu wektorowego w Rive Editor). Minimalizuj liczbę animacji Bone dla postaci — dla elementów UI nie są potrzebne. Na starszych urządzeniach wyłączaj podwójne buforowanie riveView.enableDoubleBuffering = false na Android.

Podsumowanie

  • Rive — interaktywna animacja wektorowa z własnym edytorem i środowiskiem uruchomieniowym dla 5+ platform.
  • State Machine — wbudowana logika przejść między animacjami za pomocą wyzwalaczy (Touch, Boolean, Number).
  • RiveRuntime — biblioteki dla Flutter, iOS, Android, Web i React z renderowaniem przez Skia/Core Graphics.
  • Format .riv — kontener binarny o wadze 2–50 KB zawierający animację i State Machine.
  • RiveAnimation (Flutter), RiveViewModel (SwiftUI), RiveAnimationView (Android) — główne komponenty.
  • Rive nadaje się do interaktywnych elementów UI, Lottie — do pasywnych animacji dekoracyjnych.
  • Typy wyzwalaczy: Boolean (przełącznik), Number (liczba), Trigger (impuls). Zalecany czas przejścia — 100–300 ms.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również