Rive est un outil de création et de lecture d'animations vectorielles interactives qui combine un éditeur d'animation et des bibliothèques runtime pour les plateformes mobiles. Contrairement aux formats passifs, Rive prend en charge State Machine — la logique des transitions entre les animations en fonction des actions de l'utilisateur. Selon le Rive Blog (2026), l'outil est utilisé dans plus de 10 000 projets, dont Duolingo et Bumble. En savoir plus sur les autres types d'animations dans le guide général de l'animation.
Points clés
Rive (anciennement Rive.app, fondée en 2016) est un éditeur graphique et un runtime multiplateforme pour l'animation vectorielle interactive. Contrairement à After Effects + Bodymovin (Lottie), Rive fournit un environnement unifié : le dessinateur dessine, anime et configure la logique des transitions directement dans l'éditeur. Le résultat est exporté dans un fichier binaire .riv pesant de 2 à 50 Ko selon la complexité.
La principale différence de Rive par rapport aux autres solutions est la State Machine. C'est un graphe visuel où les nœuds sont des animations (Idle, Hover, Press, Active), et les transitions entre eux sont activées par des déclencheurs (Touch, Drag, Boolean). Le développeur envoie simplement des déclencheurs dans le code, et RiveRuntime décide quelle animation lire et comment basculer en douceur entre elles. Selon Rive Engineering (2026), l'animation .riv moyenne avec State Machine prend 15 Ko — 5 à 10 fois moins qu'un fichier vidéo équivalent.
Rive Runtime est disponible pour Flutter, iOS (Swift), Android (Kotlin/Java), Web (WASM) et React. Le rendu est effectué via Skia (Flutter/Web), Core Graphics (iOS) ou Canvas (Android). Rive prend en charge l'animation de formes (Knob, Slider, Button avec géométrie personnalisée), permettant de créer des composants d'interface utilisateur entièrement animés, pas seulement des animations décoratives.
Rive et Lottie résolvent des tâches différentes. Lottie est un lecteur d'animations prêtes à l'emploi d'After Effects, optimal pour les effets décoratifs passifs. Rive est un outil pour créer des animations interactives avec sa propre logique, où l'animation répond aux actions de l'utilisateur. Le choix dépend du niveau d'interactivité requis.
| Critère | Rive | Lottie |
|---|---|---|
| Éditeur | Propre (Rive Editor) | Adobe After Effects + Bodymovin |
| Interactivité | State Machine, déclencheurs, Boolean, Number | Uniquement play/pause/seek |
| Format | .riv (binaire) | .json ou .lottie (protobuf) |
| Rendu | Skia / Core Graphics / Canvas | Canvas / Core Animation / Skia |
| UI animée | Knob, Slider, Button, Input (intégrés) | Aucun (couches décoratives uniquement) |
Quand choisir Rive : boutons interactifs avec retour de pression, éléments de jeu (personnages avec états), interrupteurs animés, icônes dynamiques réagissant au statut. Quand choisir Lottie : préchargeurs, likes, écrans d'accueil, animations d'accent sans logique. Pour les projets Flutter, Rive est le choix préféré grâce à l'intégration native avec Skia et le pipeline de rendu de Flutter.
Dans Flutter, RiveAnimation est le widget principal pour intégrer des fichiers .riv. Il est disponible via le package rive (officiel). RiveAnimation prend en charge les arguments : artboard (sélection de la planche), animation (nom de l'animation), fit, alignment, controllers (pour State Machine). Pour les scènes interactives, StateMachineController est utilisé.
import 'package:rive/rive.dart';
// Lecture simple d'animation
RiveAnimation.asset(
'assets/animations/button.riv',
artboard: 'Button',
animations: const ['idle'],
fit: BoxFit.contain,
)
// StateMachineController avec déclencheurs
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');
}
},
),
);
}
}
Meilleures pratiques Flutter : chargez les fichiers .riv de manière asynchrone via RiveAnimation.asset (AssetBundle intégré). Pour les listes (ListView), utilisez un seul StateMachineController réutilisé entre les éléments. Rive ne nécessite plus d'importations séparées — rive v0.12+ inclut toutes les fonctionnalités. Pour une animation personnalisée, contrôlez RiveAnimationController directement — il fournit un accès aux animations, au mélange (blend) et à la vitesse.
Sur iOS, RiveRuntime est représenté par la classe RiveView (UIKit) et RiveViewModel (SwiftUI). La bibliothèque est connectée via Swift Package Manager. RiveView rend les fichiers .riv via Core Graphics et Metal, prenant en charge 120 FPS sur les écrans ProMotion. Pour State Machine, RiveStateMachineLayer est utilisé avec liaison de déclencheur.
import RiveRuntime
// SwiftUI : RiveViewModel avec animation
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
// Déclencheur via State Machine
}
}
.onEnded { _ in
isPressed = false
}
)
}
}
// UIKit : RiveView avec contrôle manuel
let riveView = RiveView()
riveView.configure(fileName: "loading", extension: "riv")
riveView.fit = .contain
riveView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(riveView)
// Gestion de State Machine
riveView.triggerInput(named: "startAnimation")
Meilleures pratiques iOS : utilisez RiveViewModel pour SwiftUI — il gère automatiquement le cycle de vie. Pour UIKit, abonnez-vous à RiveViewDelegate pour le suivi des événements. Rive consomme moins de CPU que Lottie sur iOS grâce au rendu via Core Graphics. Pour les animations dans NavigationView/UICollectionView, utilisez le préchargement via RiveFile.preload().
Sur Android, RiveAnimationView est la vue principale pour intégrer des animations .riv. La bibliothèque app.rive:rive-android est connectée via Gradle. RiveAnimationView hérite de View et rend via Canvas avec prise en charge de l'accélération matérielle. State Machine est gérée via setTriggers et 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 : gestion de State Machine
import app.rive.riveandroid.RiveAnimationView
import app.rive.riveandroid.StateMachineInput
val riveView = findViewById<RiveAnimationView>(R.id.riveView)
riveView.post {
riveView.setTriggers("hover") "> Envoi du déclencheur à la State Machine
riveView.setInput("speed", 1.5f)
riveView.setInput("isActive", true)
riveView.play()
}
// Gestion de fin d'animation
riveView.addListener(object : RiveAnimationView.RiveListener() {
override fun onAnimationCompleted(animationName: String) {
Log.d("Rive", "Animation $animationName completed")
}
})
Meilleures pratiques Android : chargez les fichiers .riv via res/raw (ressources intégrées) ou assets (chargement réseau). RiveAnimationView gère automatiquement le cycle de vie — n'appelez pas play/pause manuellement dans onResume/onPause. Pour les animations dans RecyclerView, utilisez setOnScrollListener pour mettre en pause la lecture pendant le défilement. Selon la documentation Rive (2026), les fichiers .riv jusqu'à 100 Ko sont analysés en 5 à 10 ms sur les appareils de milieu de gamme.
State Machine est une fonctionnalité clé de Rive qui le distingue des formats d'animation passifs. C'est un graphe visuel dont les sommets sont des états (animations) et les arêtes sont des transitions activées par des déclencheurs. La State Machine est créée dans Rive Editor : le concepteur ajoute des nœuds d'animation, les relie avec des lignes et attribue des déclencheurs (Touch, Boolean, Number). Le développeur n'a qu'à envoyer ces déclencheurs depuis le code.
// Flutter : contrôle total sur 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');
},
),
);
}
}
// Envoi de valeur numérique
SMIInput<double> speedInput = controller.findInput('speed');
speedInput?.value = scrollPosition;
Types de déclencheurs : Boolean — interrupteur (true/false), Number — valeur numérique (0,0–1,0 ou plage arbitraire), Trigger — impulsion unique (pression de bouton). Dans Rive Editor, vous pouvez configurer le lissage des transitions (Transition Duration) — valeur recommandée 100–300 ms pour la fluidité. Pour les états d'interface utilisateur complexes, utilisez des State Machines imbriquées (Nested State Machines) — chaque partie de l'animation est gérée indépendamment. La State Machine Rive fonctionne sur toutes les plateformes sans modification du fichier .riv — la logique de transition est intégrée dans le fichier, pas dans le code de l'application.
Foire aux questions
Rive est une animation interactive avec State Machine, déclencheurs et son propre éditeur. Lottie est une lecture passive d'animations JSON d'After Effects. Rive convient aux boutons, jeux et éléments d'interface utilisateur avec réaction de l'utilisateur. Lottie est pour les effets décoratifs (préchargeurs, likes). Rive utilise le format .riv, Lottie utilise JSON ou .lottie.
Oui. Rive prend en charge la lecture simple d'animations sans State Machine — spécifiez animationName dans RiveAnimation.asset ou RiveView. Dans ce cas, Rive fonctionne comme Lottie : animation en boucle ou unique. La State Machine est une couche optionnelle pour l'interactivité. Pour les projets qui n'ont besoin que d'animations décoratives, la State Machine est superflue.
Oui, via AndroidView pour intégrer RiveAnimationView dans Compose. Depuis rive-android 0.9.0, un wrapper Compose RiveAnimation compose() avec prise en charge des modificateurs est disponible. Pour la gestion de State Machine, utilisez remember { StateMachineHolder() }. Rive prend également en charge Compose Multiplatform sur iOS via le runtime Compose partagé.
Oui, Rive prend en charge Flutter Web via Skia Wasm (CanvasKit) ou le rendu HTML. CanvasKit est recommandé pour des performances maximales. Les fichiers Rive sont chargés via requête HTTP (RiveAnimation.network) ou emballés comme assets. Flutter Web avec Rive fonctionne correctement dans tous les navigateurs modernes (Chrome 90+, Safari 15+, Firefox 90+).
Limitez le nombre de couches actives simultanées à 20–30. Utilisez Flat shading au lieu de Gradient pour les formes simples. Pour les animations avec texte, utilisez System Text (pas de texte vectoriel dans Rive Editor). Minimisez le nombre d'animations Bone pour les personnages — elles sont inutiles pour les éléments d'interface utilisateur. Sur les anciens appareils, désactivez le double tampon : riveView.enableDoubleBuffering = false sur Android.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi