Rive: その概要、FlutterとiOSのためのアニメーションツール

著者: IT Sectr 公開日: 2026-03-01 読了時間: 11 分

Riveは、インタラクティブなベクターアニメーションを作成および再生するためのツールで、アニメーションエディターとモバイルプラットフォーム向けランタイムライブラリを統合しています。パッシブフォーマットとは異なり、RiveはState Machineをサポートしています — ユーザーのアクションに基づいてアニメーション間の遷移を行うロジックです。Rive Blog(2026)によると、このツールはDuolingoやBumbleを含む10,000以上のプロジェクトで使用されています。他の種類のアニメーションの詳細については、アニメーションの一般ガイドをご覧ください。

重要なポイント

  • Rive — 独自のエディターを備えたインタラクティブなベクターアニメーションツール。
  • State Machine — トリガーによるアニメーション間の遷移のビジュアルロジック。
  • RiveRuntime — iOS、Android、Flutter、Web向けの再生ライブラリ。
  • RiveAnimation — アプリケーションに.rivファイルを埋め込むためのFlutterのDartウィジェット。
  • フォーマット .riv — アニメーションとState Machineを含むバイナリコンテナ。

Riveとは?

Rive(旧Rive.app、2016年設立)は、インタラクティブなベクターアニメーションのためのグラフィカルエディターおよびクロスプラットフォームランタイムです。After Effects + Bodymovin(Lottie)とは異なり、Riveは統一された環境を提供します。デザイナーはエディター内で直接描画、アニメーション化、遷移ロジックの設定を行います。結果はバイナリの.rivファイルにエクスポートされ、複雑さに応じて2〜50 KBになります。

他のソリューションとRiveの主な違いはState Machineです。これは、ノードがアニメーション(Idle、Hover、Press、Active)であり、ノード間の遷移がトリガー(Touch、Drag、Boolean)によってアクティブになるビジュアルグラフです。開発者はコードでトリガーを送信するだけで、RiveRuntimeがどのアニメーションを再生するか、およびそれらの間をスムーズに切り替える方法を決定します。Rive Engineering(2026)によると、State Machineを備えた平均的な.rivアニメーションは15 KBで、同等のビデオファイルの5〜10分の1です。

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 vs Lottie:アプローチの比較

RiveとLottieは異なるタスクを解決します。LottieはAfter Effectsの既製アニメーション用のプレーヤーで、パッシブな装飾効果に最適です。Riveは独自のロジックでインタラクティブなアニメーションを作成するツールで、アニメーションがユーザーのアクションに応答します。選択は必要なインタラクティブ性のレベルによって異なります。

基準RiveLottie
エディター独自(Rive Editor)Adobe After Effects + Bodymovin
インタラクティブ性State Machine、トリガー、Boolean、Numberplay/pause/seekのみ
フォーマット.riv(バイナリ).jsonまたは.lottie(protobuf)
レンダリングSkia / Core Graphics / CanvasCanvas / Core Animation / Skia
アニメーションUIKnob、Slider、Button、Input(組み込み)なし(装飾レイヤーのみ)

Riveを選ぶべき場合:押下応答のあるインタラクティブボタン、ゲーム要素(状態を持つキャラクター)、アニメーションスイッチ、ステータスに反応する動的アイコン。Lottieを選ぶべき場合:プリローダー、いいね、ウェルカム画面、ロジックのないアクセントアニメーション。Flutterプロジェクトの場合、SkiaおよびFlutterのレンダリングパイプラインとのネイティブ統合により、Riveが推奨される選択肢です。

Flutter(Dart)へのRiveの統合

Flutterでは、RiveAnimationが.rivファイルを埋め込むための主要なウィジェットです。riveパッケージ(公式)を介して利用できます。RiveAnimationは引数をサポートしています:artboard(ボード選択)、animation(アニメーション名)、fit、alignment、controllers(State Machine用)。インタラクティブシーンにはStateMachineControllerが使用されます。

dart
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(Swift)へのRiveの統合

iOSでは、RiveRuntimeはRiveViewクラス(UIKit)とRiveViewModel(SwiftUI)で表されます。ライブラリはSwift Package Managerを介して接続されます。RiveViewはCore GraphicsとMetalを介して.rivファイルをレンダリングし、ProMotionディスプレイで120 FPSをサポートします。State Machineには、トリガーバインディングを使用したRiveStateMachineLayerが使用されます。

swift
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(Kotlin)へのRiveの統合

Androidでは、RiveAnimationViewが.rivアニメーションを埋め込むためのメインViewです。app.rive:rive-androidライブラリはGradleを介して接続されます。RiveAnimationViewはViewを継承し、ハードウェアアクセラレーションをサポートしてCanvasを介してレンダリングします。State MachineはsetTriggersと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: 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)によると、100 KBまでの.rivファイルはミッドレンジデバイスで5〜10ミリ秒で解析されます。

State Machine:Riveにおける遷移ロジック

State Machineは、Riveをパッシブアニメーションフォーマットと区別する主要な機能です。頂点が状態(アニメーション)であり、エッジがトリガーによってアクティブ化される遷移であるビジュアルグラフです。State MachineはRive Editorで作成されます。デザイナーがアニメーションノードを追加し、線で接続し、トリガー(Touch、Boolean、Number)を割り当てます。開発者はコードからこれらのトリガーを送信するだけです。

dart
// 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 — 1回限りのインパルス(ボタン押下)。Rive Editorでは遷移のスムージング(Transition Duration)を設定できます — スムーズさのために推奨値は100〜300ミリ秒です。複雑なUI状態の場合は、ネステッドState Machine(Nested State Machines)を使用します — アニメーションの各部分が独立して管理されます。Rive State Machineは.rivファイルを変更せずにすべてのプラットフォームで動作します — 遷移ロジックはファイルに埋め込まれており、アプリケーションコードにはありません。

よくある質問

RiveとLottieの違いは何ですか?

RiveはState Machine、トリガー、独自のエディターを備えたインタラクティブアニメーションです。LottieはAfter EffectsのJSONアニメーションのパッシブ再生です。Riveはボタン、ゲーム、ユーザー応答のあるUI要素に適しています。Lottieは装飾効果(プリローダー、いいね)に適しています。Riveは.riv形式を使用し、LottieはJSONまたは.lottieを使用します。

State MachineなしでRiveを使用できますか?

はい。RiveはState Machineなしでシンプルなアニメーション再生をサポートしています — RiveAnimation.assetまたはRiveViewでanimationNameを指定します。この場合、RiveはLottieのように動作します:ループまたは1回限りのアニメーションです。State Machineはインタラクティブ性のためのオプショナルなレイヤーです。装飾アニメーションのみが必要なプロジェクトでは、State Machineは不要です。

RiveはAndroid Jetpack Composeと互換性がありますか?

はい、ComposeにRiveAnimationViewを埋め込むためのAndroidViewを介して対応しています。rive-android 0.9.0以降、修飾子をサポートするComposeラッパーRiveAnimation compose()が利用可能です。State Machine管理には、remember { StateMachineHolder() }を使用します。Riveは共有Compose Runtimeを介してiOS上のCompose Multiplatformもサポートしています。

RiveはFlutter Webで動作しますか?

はい、RiveはSkia Wasm(CanvasKit)またはHTMLレンダラーを介してFlutter Webをサポートしています。最大のパフォーマンスを得るにはCanvasKitが推奨されます。RiveファイルはHTTPリクエスト(RiveAnimation.network)を介してロードされるか、アセットとしてパッケージ化されます。Flutter WebとRiveは、すべての最新ブラウザ(Chrome 90+、Safari 15+、Firefox 90+)で正しく動作します。

モバイルデバイスでRiveのパフォーマンスを最適化するには?

同時にアクティブなレイヤーの数を20〜30に制限します。単純な形状にはGradientの代わりにFlat shadingを使用します。テキストを含むアニメーションには、System Textを使用します(Rive Editorのベクターテキストではなく)。キャラクターのボーンアニメーションの数を最小限に抑えます — UI要素には不要です。古いデバイスでは、Androidでダブルバッファリングを無効にします:riveView.enableDoubleBuffering = false。

まとめ

  • Rive — 独自のエディターと5つ以上のプラットフォーム向けランタイムを備えたインタラクティブなベクターアニメーション。
  • State Machine — トリガー(Touch、Boolean、Number)によるアニメーション間の組み込み遷移ロジック。
  • RiveRuntime — Skia/Core Graphicsを介したレンダリングを備えたFlutter、iOS、Android、Web、React向けライブラリ。
  • フォーマット .riv — アニメーションとState Machineを含む2〜50 KBのバイナリコンテナ。
  • RiveAnimation(Flutter)、RiveViewModel(SwiftUI)、RiveAnimationView(Android) — 主要コンポーネント。
  • RiveはインタラクティブなUI要素に適し、Lottieはパッシブな装飾アニメーションに適しています。
  • トリガーの種類:Boolean(スイッチ)、Number(数値)、Trigger(インパルス)。推奨遷移時間 — 100〜300ミリ秒。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください