Rive는 인터랙티브 벡터 애니메이션을 만들고 재생하기 위한 도구로, 애니메이션 편집기와 모바일 플랫폼용 런타임 라이브러리를 결합합니다. 수동적 형식과 달리 Rive는 State Machine을 지원합니다 — 사용자 작업에 따라 애니메이션 간 전환 로직입니다. Rive Blog(2026)에 따르면, 이 도구는 Duolingo와 Bumble을 포함한 10,000개 이상의 프로젝트에서 사용됩니다. 다른 유형의 애니메이션에 대한 자세한 내용은 일반 애니메이션 가이드를 참조하세요.
주요 포인트
Rive(이전 Rive.app, 2016년 설립)는 인터랙티브 벡터 애니메이션을 위한 그래픽 편집기이자 크로스 플랫폼 런타임입니다. After Effects + Bodymovin(Lottie)와 달리 Rive는 통합 환경을 제공합니다: 디자이너가 편집기에서 직접 그리고, 애니메이션화하고, 전환 로직을 구성합니다. 결과는 복잡성에 따라 2~50KB의 바이너리 .riv 파일로 내보내집니다.
다른 솔루션과 Rive의 주요 차이점은 State Machine입니다. 노드가 애니메이션(Idle, Hover, Press, Active)이고 노드 간 전환이 트리거(Touch, Drag, Boolean)에 의해 활성화되는 시각적 그래프입니다. 개발자는 코드에서 트리거를 보내기만 하면 RiveRuntime이 어떤 애니메이션을 재생할지 그리고 어떻게 부드럽게 전환할지 결정합니다. Rive Engineering(2026)에 따르면, State Machine이 있는 평균 .riv 애니메이션은 15KB로, 동등한 비디오 파일보다 5~10배 작습니다.
Rive Runtime은 Flutter, iOS(Swift), Android(Kotlin/Java), Web(WASM) 및 React에서 사용할 수 있습니다. 렌더링은 Skia(Flutter/Web), Core Graphics(iOS) 또는 Canvas(Android)를 통해 수행됩니다. Rive는 형상 애니메이션(사용자 정의 지오메트리를 가진 Knob, Slider, Button)을 지원하여 장식적 애니메이션뿐만 아니라 완전히 애니메이션된 UI 구성 요소를 만들 수 있습니다.
Rive와 Lottie는 다른 작업을 해결합니다. Lottie는 After Effects의 기성 애니메이션을 위한 플레이어로, 수동적 장식 효과에 최적입니다. Rive는 자체 로직으로 인터랙티브 애니메이션을 만드는 도구로, 애니메이션이 사용자 작업에 반응합니다. 선택은 필요한 인터랙티브 수준에 따라 달라집니다.
| 기준 | Rive | Lottie |
|---|---|---|
| 편집기 | 자체(Rive Editor) | Adobe After Effects + Bodymovin |
| 인터랙티브 | State Machine, 트리거, Boolean, Number | play/pause/seek만 |
| 형식 | .riv(바이너리) | .json 또는 .lottie(protobuf) |
| 렌더링 | Skia / Core Graphics / Canvas | Canvas / Core Animation / Skia |
| 애니메이션 UI | Knob, Slider, Button, Input(내장) | 없음(장식 레이어만) |
Rive를 선택해야 하는 경우: 누름 피드백이 있는 인터랙티브 버튼, 게임 요소(상태가 있는 캐릭터), 애니메이션 스위치, 상태에 반응하는 동적 아이콘. Lottie를 선택해야 하는 경우: 프리로더, 좋아요, 환영 화면, 로직이 없는 악센트 애니메이션. Flutter 프로젝트의 경우 Skia 및 Flutter의 렌더링 파이프라인과의 네이티브 통합으로 인해 Rive가 선호되는 선택입니다.
Flutter에서 RiveAnimation은 .riv 파일을 임베드하기 위한 기본 위젯입니다. rive 패키지(공식)를 통해 사용할 수 있습니다. RiveAnimation은 인수를 지원합니다: artboard(보드 선택), animation(애니메이션 이름), fit, alignment, controllers(State Machine용). 인터랙티브 장면에는 StateMachineController가 사용됩니다.
import 'package:rive/rive.dart';
// 간단한 애니메이션 재생
RiveAnimation.asset(
'assets/animations/button.riv',
artboard: 'Button',
animations: const ['idle'],
fit: BoxFit.contain,
)
// 트리거가 있는 StateMachineController
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');
}
},
),
);
}
}
Flutter 모범 사례: .riv 파일을 RiveAnimation.asset(내장 AssetBundle)을 통해 비동기적으로 로드합니다. 목록(ListView)의 경우 항목 간에 재사용 가능한 단일 StateMachineController를 사용합니다. Rive는 더 이상 별도의 가져오기가 필요하지 않습니다 — rive v0.12+에는 모든 기능이 포함되어 있습니다. 사용자 정의 애니메이션의 경우 RiveAnimationController를 직접 제어합니다 — 애니메이션, 블렌드 및 속도에 대한 액세스를 제공합니다.
iOS에서 RiveRuntime은 RiveView 클래스(UIKit)와 RiveViewModel(SwiftUI)로 표현됩니다. 라이브러리는 Swift Package Manager를 통해 연결됩니다. RiveView는 Core Graphics와 Metal을 통해 .riv 파일을 렌더링하며 ProMotion 디스플레이에서 120FPS를 지원합니다. State Machine에는 트리거 바인딩과 함께 RiveStateMachineLayer가 사용됩니다.
import RiveRuntime
// SwiftUI: 애니메이션이 있는 RiveViewModel
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
// State Machine을 통한 트리거
}
}
.onEnded { _ in
isPressed = false
}
)
}
}
// UIKit: 수동 제어가 있는 RiveView
let riveView = RiveView()
riveView.configure(fileName: "loading", extension: "riv")
riveView.fit = .contain
riveView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(riveView)
// State Machine 관리
riveView.triggerInput(named: "startAnimation")
iOS 모범 사례: SwiftUI에는 RiveViewModel을 사용합니다 — 라이프사이클을 자동으로 관리합니다. UIKit의 경우 RiveViewDelegate를 구독하여 이벤트를 추적합니다. Rive는 Core Graphics 렌더링 덕분에 iOS에서 Lottie보다 CPU를 적게 소비합니다. NavigationView/UICollectionView의 애니메이션에는 RiveFile.preload()를 통한 프리페칭을 사용합니다.
Android에서 RiveAnimationView는 .riv 애니메이션을 임베드하기 위한 기본 View입니다. app.rive:rive-android 라이브러리는 Gradle을 통해 연결됩니다. RiveAnimationView는 View를 상속하며 하드웨어 가속을 지원하여 Canvas를 통해 렌더링합니다. State Machine은 setTriggers와 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: State Machine 관리
import app.rive.riveandroid.RiveAnimationView
import app.rive.riveandroid.StateMachineInput
val riveView = findViewById<RiveAnimationView>(R.id.riveView)
riveView.post {
riveView.setTriggers("hover") "> State Machine으로 트리거 전송
riveView.setInput("speed", 1.5f)
riveView.setInput("isActive", true)
riveView.play()
}
// 애니메이션 완료 처리
riveView.addListener(object : RiveAnimationView.RiveListener() {
override fun onAnimationCompleted(animationName: String) {
Log.d("Rive", "Animation $animationName completed")
}
})
Android 모범 사례: .riv 파일을 res/raw(내장 리소스) 또는 assets(네트워크 로딩)을 통해 로드합니다. RiveAnimationView는 라이프사이클을 자동으로 처리합니다 — onResume/onPause에서 수동으로 play/pause를 호출하지 마세요. RecyclerView의 애니메이션에는 스크롤 중 재생을 일시 중지하기 위해 setOnScrollListener를 사용합니다. Rive 문서(2026)에 따르면 최대 100KB의 .riv 파일은 중간급 기기에서 5~10ms 내에 파싱됩니다.
State Machine은 Rive를 수동적 애니메이션 형식과 구분짓는 핵심 기능입니다. 정점이 상태(애니메이션)이고 가장자리가 트리거에 의해 활성화되는 전환인 시각적 그래프입니다. State Machine은 Rive Editor에서 생성됩니다: 디자이너가 애니메이션 노드를 추가하고, 선으로 연결하고, 트리거(Touch, Boolean, Number)를 할당합니다. 개발자는 코드에서 이러한 트리거만 보내면 됩니다.
// Flutter: 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');
},
),
);
}
}
// 숫자 값 보내기
SMIInput<double> speedInput = controller.findInput('speed');
speedInput?.value = scrollPosition;
트리거 유형: Boolean — 스위치(true/false), Number — 숫자 값(0.0~1.0 또는 임의 범위), Trigger — 일회성 임펄스(버튼 누름). Rive Editor에서 전환 스무딩(Transition Duration)을 구성할 수 있습니다 — 부드러움을 위한 권장 값은 100~300ms입니다. 복잡한 UI 상태의 경우 중첩된 State Machine(Nested State Machines)을 사용합니다 — 애니메이션의 각 부분이 독립적으로 관리됩니다. Rive State Machine은 .riv 파일을 변경하지 않고 모든 플랫폼에서 작동합니다 — 전환 로직은 파일에 내장되어 있으며 애플리케이션 코드에 있지 않습니다.
자주 묻는 질문
Rive는 State Machine, 트리거 및 자체 편집기를 갖춘 인터랙티브 애니메이션입니다. Lottie는 After Effects의 JSON 애니메이션을 수동적으로 재생합니다. Rive는 버튼, 게임 및 사용자 반응이 있는 UI 요소에 적합합니다. Lottie는 장식 효과(프리로더, 좋아요)에 적합합니다. Rive는 .riv 형식을 사용하고 Lottie는 JSON 또는 .lottie를 사용합니다.
네. Rive는 State Machine 없이 간단한 애니메이션 재생을 지원합니다 — RiveAnimation.asset 또는 RiveView에서 animationName을 지정하세요. 이 경우 Rive는 Lottie처럼 작동합니다: 루프 또는 일회성 애니메이션입니다. State Machine은 인터랙티브를 위한 선택적 레이어입니다. 장식 애니메이션만 필요한 프로젝트의 경우 State Machine은 불필요합니다.
네, Compose에 RiveAnimationView를 임베드하기 위한 AndroidView를 통해 가능합니다. rive-android 0.9.0부터 수정자 지원이 포함된 Compose 래퍼 RiveAnimation compose()를 사용할 수 있습니다. State Machine 관리를 위해 remember { StateMachineHolder() }를 사용하세요. Rive는 공유 Compose Runtime을 통해 iOS에서 Compose Multiplatform도 지원합니다.
네, Rive는 Skia Wasm(CanvasKit) 또는 HTML 렌더러를 통해 Flutter Web을 지원합니다. 최대 성능을 위해 CanvasKit이 권장됩니다. Rive 파일은 HTTP 요청(RiveAnimation.network)을 통해 로드되거나 assets으로 패키징됩니다. Flutter Web with Rive는 모든 최신 브라우저(Chrome 90+, Safari 15+, Firefox 90+)에서 올바르게 작동합니다.
동시 활성 레이어 수를 20~30개로 제한하세요. 단순한 모양에는 Gradient 대신 Flat shading을 사용하세요. 텍스트가 있는 애니메이션의 경우 System Text를 사용하세요(Rive Editor의 벡터 텍스트 대신). 캐릭터의 Bone 애니메이션 수를 최소화하세요 — UI 요소에는 필요하지 않습니다. 오래된 기기에서는 Android에서 riveView.enableDoubleBuffering = false로 이중 버퍼링을 비활성화하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.