Rive là công cụ tạo và phát hoạt ảnh vector tương tác, kết hợp trình chỉnh sửa hoạt ảnh và thư viện runtime cho các nền tảng di động. Không giống các định dạng thụ động, Rive hỗ trợ State Machine — logic chuyển đổi giữa các hoạt ảnh dựa trên hành động của người dùng. Theo Rive Blog (2026), công cụ này được sử dụng trong hơn 10.000 dự án, bao gồm Duolingo và Bumble. Tìm hiểu thêm về các loại hoạt ảnh khác trong hướng dẫn hoạt ảnh chung.
Các điểm chính
Rive (trước đây là Rive.app, thành lập năm 2016) là trình chỉnh sửa đồ họa và runtime đa nền tảng cho hoạt ảnh vector tương tác. Không giống After Effects + Bodymovin (Lottie), Rive cung cấp môi trường thống nhất: nhà thiết kế vẽ, tạo hoạt ảnh và cấu hình logic chuyển đổi trực tiếp trong trình chỉnh sửa. Kết quả được xuất sang tệp nhị phân .riv nặng từ 2 đến 50 KB tùy theo độ phức tạp.
Sự khác biệt chính của Rive so với các giải pháp khác là State Machine. Đó là một đồ thị trực quan nơi các nút là hoạt ảnh (Idle, Hover, Press, Active) và các chuyển đổi giữa chúng được kích hoạt bởi các trình kích hoạt (Touch, Drag, Boolean). Nhà phát triển chỉ cần gửi các trình kích hoạt trong mã, và RiveRuntime quyết định hoạt ảnh nào sẽ phát và cách chuyển đổi mượt mà giữa chúng. Theo Rive Engineering (2026), hoạt ảnh .riv trung bình với State Machine chiếm 15 KB — nhỏ hơn 5–10 lần so với tệp video tương đương.
Rive Runtime có sẵn cho Flutter, iOS (Swift), Android (Kotlin/Java), Web (WASM) và React. Kết xuất được thực hiện qua Skia (Flutter/Web), Core Graphics (iOS) hoặc Canvas (Android). Rive hỗ trợ hoạt ảnh hình dạng (Knob, Slider, Button với hình học tùy chỉnh), cho phép tạo các thành phần giao diện người dùng hoạt ảnh đầy đủ, không chỉ các hoạt ảnh trang trí.
Rive và Lottie giải quyết các nhiệm vụ khác nhau. Lottie là trình phát cho hoạt ảnh có sẵn từ After Effects, tối ưu cho các hiệu ứng trang trí thụ động. Rive là công cụ tạo hoạt ảnh tương tác với logic riêng, nơi hoạt ảnh phản ứng với hành động của người dùng. Lựa chọn phụ thuộc vào mức độ tương tác yêu cầu.
| Tiêu chí | Rive | Lottie |
|---|---|---|
| Trình chỉnh sửa | Riêng (Rive Editor) | Adobe After Effects + Bodymovin |
| Tương tác | State Machine, trình kích hoạt, Boolean, Number | Chỉ play/pause/seek |
| Định dạng | .riv (nhị phân) | .json hoặc .lottie (protobuf) |
| Kết xuất | Skia / Core Graphics / Canvas | Canvas / Core Animation / Skia |
| UI hoạt ảnh | Knob, Slider, Button, Input (tích hợp sẵn) | Không có (chỉ lớp trang trí) |
Khi nào chọn Rive: nút tương tác với phản hồi nhấn, yếu tố trò chơi (nhân vật với trạng thái), công tắc hoạt ảnh, biểu tượng động phản ứng theo trạng thái. Khi nào chọn Lottie: bộ tải trước, lượt thích, màn hình chào mừng, hoạt ảnh nhấn mạnh không có logic. Đối với các dự án Flutter, Rive là lựa chọn ưu tiên nhờ tích hợp gốc với Skia và pipeline kết xuất của Flutter.
Trong Flutter, RiveAnimation là widget chính để nhúng tệp .riv. Nó có sẵn qua gói rive (chính thức). RiveAnimation hỗ trợ các đối số: artboard (chọn bảng), animation (tên hoạt ảnh), fit, alignment, controllers (cho State Machine). Cho các cảnh tương tác, StateMachineController được sử dụng.
import 'package:rive/rive.dart';
// Phát hoạt ảnh đơn giản
RiveAnimation.asset(
'assets/animations/button.riv',
artboard: 'Button',
animations: const ['idle'],
fit: BoxFit.contain,
)
// StateMachineController với trình kích hoạt
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');
}
},
),
);
}
}
Thực tiễn tốt nhất Flutter: tải tệp .riv bất đồng bộ qua RiveAnimation.asset (AssetBundle tích hợp sẵn). Cho danh sách (ListView), sử dụng một StateMachineController duy nhất tái sử dụng giữa các mục. Rive không còn yêu cầu import riêng — rive v0.12+ bao gồm tất cả tính năng. Cho hoạt ảnh tùy chỉnh, điều khiển RiveAnimationController trực tiếp — nó cung cấp quyền truy cập vào hoạt ảnh, pha trộn (blend) và tốc độ.
Trên iOS, RiveRuntime được đại diện bởi lớp RiveView (UIKit) và RiveViewModel (SwiftUI). Thư viện được kết nối qua Swift Package Manager. RiveView kết xuất tệp .riv qua Core Graphics và Metal, hỗ trợ 120 FPS trên màn hình ProMotion. Cho State Machine, RiveStateMachineLayer được sử dụng với ràng buộc trình kích hoạt.
import RiveRuntime
// SwiftUI: RiveViewModel với hoạt ảnh
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
// Trình kích hoạt qua State Machine
}
}
.onEnded { _ in
isPressed = false
}
)
}
}
// UIKit: RiveView với điều khiển thủ công
let riveView = RiveView()
riveView.configure(fileName: "loading", extension: "riv")
riveView.fit = .contain
riveView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(riveView)
// Quản lý State Machine
riveView.triggerInput(named: "startAnimation")
Thực tiễn tốt nhất iOS: sử dụng RiveViewModel cho SwiftUI — nó tự động quản lý vòng đời. Cho UIKit, đăng ký RiveViewDelegate để theo dõi sự kiện. Rive tiêu thụ ít CPU hơn Lottie trên iOS nhờ kết xuất qua Core Graphics. Cho hoạt ảnh trong NavigationView/UICollectionView, sử dụng tải trước qua RiveFile.preload().
Trên Android, RiveAnimationView là View chính để nhúng hoạt ảnh .riv. Thư viện app.rive:rive-android được kết nối qua Gradle. RiveAnimationView kế thừa từ View và kết xuất qua Canvas với hỗ trợ tăng tốc phần cứng. State Machine được quản lý qua setTriggers và 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: quản lý State Machine
import app.rive.riveandroid.RiveAnimationView
import app.rive.riveandroid.StateMachineInput
val riveView = findViewById<RiveAnimationView>(R.id.riveView)
riveView.post {
riveView.setTriggers("hover") "> Gửi trigger vào State Machine
riveView.setInput("speed", 1.5f)
riveView.setInput("isActive", true)
riveView.play()
}
// Xử lý hoàn thành hoạt ảnh
riveView.addListener(object : RiveAnimationView.RiveListener() {
override fun onAnimationCompleted(animationName: String) {
Log.d("Rive", "Animation $animationName completed")
}
})
Thực tiễn tốt nhất Android: tải tệp .riv qua res/raw (tài nguyên tích hợp sẵn) hoặc assets (tải qua mạng). RiveAnimationView tự động xử lý vòng đời — không gọi play/pause thủ công trong onResume/onPause. Cho hoạt ảnh trong RecyclerView, sử dụng setOnScrollListener để tạm dừng phát khi cuộn. Theo tài liệu Rive (2026), tệp .riv lên tới 100 KB được phân tích trong 5–10 ms trên thiết bị tầm trung.
State Machine là tính năng chính của Rive giúp phân biệt nó với các định dạng hoạt ảnh thụ động. Đó là một đồ thị trực quan nơi các đỉnh là trạng thái (hoạt ảnh) và các cạnh là chuyển đổi được kích hoạt bởi trình kích hoạt. State Machine được tạo trong Rive Editor: nhà thiết kế thêm nút hoạt ảnh, kết nối chúng bằng đường và gán trình kích hoạt (Touch, Boolean, Number). Nhà phát triển chỉ cần gửi các trình kích hoạt này từ mã.
// Flutter: kiểm soát hoàn toàn 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');
},
),
);
}
}
// Gửi giá trị số
SMIInput<double> speedInput = controller.findInput('speed');
speedInput?.value = scrollPosition;
Loại trình kích hoạt: Boolean — công tắc (true/false), Number — giá trị số (0.0–1.0 hoặc phạm vi tùy ý), Trigger — xung một lần (nhấn nút). Trong Rive Editor, có thể cấu hình làm mịn chuyển đổi (Transition Duration) — giá trị khuyến nghị 100–300 ms để mượt. Cho trạng thái UI phức tạp, sử dụng State Machines lồng nhau (Nested State Machines) — mỗi phần hoạt ảnh được quản lý độc lập. State Machine Rive hoạt động trên tất cả nền tảng mà không thay đổi tệp .riv — logic chuyển đổi được nhúng trong tệp, không phải trong mã ứng dụng.
Các câu hỏi thường gặp
Rive là hoạt ảnh tương tác với State Machine, trình kích hoạt và trình chỉnh sửa riêng. Lottie là phát thụ động hoạt ảnh JSON từ After Effects. Rive phù hợp cho nút, trò chơi và phần tử UI có phản ứng người dùng. Lottie dành cho hiệu ứng trang trí (bộ tải trước, lượt thích). Rive sử dụng định dạng .riv, Lottie sử dụng JSON hoặc .lottie.
Có. Rive hỗ trợ phát hoạt ảnh đơn giản không cần State Machine — chỉ định animationName trong RiveAnimation.asset hoặc RiveView. Trong trường hợp này, Rive hoạt động như Lottie: hoạt ảnh lặp hoặc một lần. State Machine là lớp tùy chọn cho tương tác. Cho các dự án chỉ cần hoạt ảnh trang trí, State Machine là không cần thiết.
Có, qua AndroidView để nhúng RiveAnimationView vào Compose. Từ rive-android 0.9.0, có sẵn trình bao bọc Compose RiveAnimation compose() với hỗ trợ bổ từ. Cho quản lý State Machine, sử dụng remember { StateMachineHolder() }. Rive cũng hỗ trợ Compose Multiplatform trên iOS qua Compose Runtime chia sẻ.
Có, Rive hỗ trợ Flutter Web qua Skia Wasm (CanvasKit) hoặc trình kết xuất HTML. CanvasKit được khuyến nghị cho hiệu suất tối đa. Các tệp Rive được tải qua yêu cầu HTTP (RiveAnimation.network) hoặc đóng gói dưới dạng tài sản. Flutter Web với Rive hoạt động chính xác trên mọi trình duyệt hiện đại (Chrome 90+, Safari 15+, Firefox 90+).
Giới hạn số lớp hoạt động đồng thời ở mức 20–30. Sử dụng Flat shading thay vì Gradient cho hình dạng đơn giản. Cho hoạt ảnh có văn bản, sử dụng System Text (không phải văn bản vector trong Rive Editor). Giảm thiểu số lượng hoạt ảnh Bone cho nhân vật — chúng không cần thiết cho phần tử UI. Trên thiết bị cũ, tắt bộ đệm kép: riveView.enableDoubleBuffering = false trên Android.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm