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 (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 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.
| Kryterium | Rive | Lottie |
|---|---|---|
| Edytor | Własny (Rive Editor) | Adobe After Effects + Bodymovin |
| Interaktywność | State Machine, wyzwalacze, Boolean, Number | Tylko play/pause/seek |
| Format | .riv (binarny) | .json lub .lottie (protobuf) |
| Renderowanie | Skia / Core Graphics / Canvas | Canvas / Core Animation / Skia |
| Animowane UI | Knob, 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.
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.
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.
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.
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().
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.
// 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 — 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.
// 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
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.
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.
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.
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+).
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
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.
Przeczytaj również