追記 2021.3.6
Rive2 が公開されたのに伴い、旧Rive のURLが変わりました。
本記事は、旧Rive について記述してものになりますので、ご了承ください。
概要
起動時にアニメーションがあるアプリって、なんかカッコいいですよねっ。
Flutterアプリケーションには、Riveで作成した2Dアニメーションをスプラッシュスクリーンとして組み込むという選択肢があります。
この記事では、はじめてRiveにふれる方向けの簡単な2Dアニメーションの作り方と、それをスプラッシュスクリーンとしての組み込む手順を紹介します。
ざっくりいうと・・・
- アプリローディング中はAndroid/iOSネイティブのスプラッシュスクリーンの仕掛けを使います。この記事ではflutter_native_splashプラグインを使った方法を紹介します。
- アプリローディング後の初期画面としてRiveで作成した2Dアニメーションを組み込みます。組み込みにはflare_flutterプラグインを使用します。
- 画面遷移の実装は、Navigatorを使用しました。
- ページ遷移のイメージはこんな感じです:
この記事の検証に使ったリソース
Riveの作品。Forkして改変することも含め、自由に使っていただくことができますので、必要に合わせてご利用ください。
Flutterのソースコード。こちらも改変することも含め、自由に使っていただくことができますので、必要に合わせてご利用ください。
環境
バージョン
- Flutter 1.20.1
プロジェクト設定
- この記事では、Flutterプロジェクトの
Use androidx.* artifacts
はON
に設定して検証しました。
本編
1) Riveで2Dアニメーションを作成する
Riveにアクセスます。アカウントがない場合は作成しましょう。無料アカウントの場合、作成した作品の公開レベルがpublicとなりますが、私の場合はそれ以外特に困ることはありませんでした。
サインインすると、Explorerのページが表示され、公開されている作品を見ることができます。また、これら作品は「OPEN IN RIVE」ボタンを押せば『どのように作られているのか』を見ることもできますし、許可されていればForkもできます。
しかし数が多いので、もし参考になる作品を探したいならば、以下のチュートリアルページの動画を順にみていくことをお勧めします。動画に登場するアニメーションもExplorerページで公開されているので、あなたの最初の教科書になるはずです。
Tutorials - Rive
ではさっそくアニメーションを作ってみましょう。
Your Files
ボタンをクリックし、+
アイコンをクリックし、Flare
を選択します。
File Properties
のページで公開範囲を選択(無料ならPublicを選択)し、SAVE
ボタンをクリック。
するとまっさらなArtboard
が表示されます。左上にはNew File 1
との表示と、DESIGN
/ANIMATE
のページを切り替えるスイッチがありますね。
さて、ここからアニメーションを編集していくわけですが、その流れをざくっり説明すると、以下のようになります。
a. DESIGN
ページで、パーツの大きさ、配置、エフェクトなどプロパティ値を編集しデザインする。これがアニメーション編集時の「初期値」になります。
b. ANIMATION
ページで、タイムラインのフレーム毎のパーツのプロパティ値を決める。「初期値」に対する変化をつけていくイメージです。
ではまず左上の作品のタイトルNew File 1
を編集して、そうですね、app_splash
とでもしておきましょう。
次に、アニメーションを作っていきましょう
1-a) アニメーションのパーツをデザインする
DESIGN
ページではArtboardのサイズを決めたり、左上のメニューからパーツの選択動作を切り替えたり、図形を呼び出したりすることができます。なお複雑な動きを行うためのBone
やNode
もここから呼び出せますが、この記事ではそこまでやりません。
ではまずArtboardのサイズを決めます。画面左側のHIERARCHY
に見えているArtboard
を選択すると、画面右側にArtboard
のプロパティが表示されるので、Size
プロパティを変更してみましょう。私はxhdpiに合わせて WIDTH:720, HEIGHT:1280 としました。
次に図形を配置します。コツを少しだけまとめると、、、
- Artboard全体の拡大縮小はマウスホイール。
- Artboard全体の移動はスペースキーを押しながらドラッグ。
- 別途用意した画像を利用する場合は、画面左下のASSETSにファイルをドラッグ&ドロップで登録してから、Artboardに配置する。
星の図形を黄色に塗りつぶし、その周りにCorner Radius
プロパティで角を削った四角を、45度ごとにRotate
して配置したものです。
ではこれを下地にして、アニメーションを作っていきます。
1-b) アニメーションを作る
ANIMATE
ページに切り替えてみましょう。画面左下にANIMATIONS
、画面中央下部に再生ボタンや00:00:00
、その右にはFPS
、00:10:00
が表示されていますね。
最初に、アニメーション全体の設定を行います。
-
ANIMATIONS
のUntitled
を右クリックし、Rename
を行いましょう。今回は1本のアニメーションとしてスプラッシュアニメーションを作るつもりなので、名前はall
としました。 - 画面中央下部のパネルの右上、
FPS
の値を変更しましょう。1秒当たりのフレーム数です。初期値の60は多いかな・・・私は12にしました。 - 次にアニメーション全体の時間の長さを設定します。画面中央下部のパネルの右上、初期値は
00:10:00
(10秒と0フレーム)。私は00:03:00
(3秒と0フレーム)にしました。書式がMM:ss:フレーム数
である点に注意してください。
すると画面中央下部のタイムラインの時間軸が以下のように変わります。
あとはこの時間軸の各フレームごとに、パーツのプロパティ値の変化を作っていく作業になります。ただしパーツのプロパティ値は、例えば「1フレームで0.0, 5フレームで1.0」に固定すると、「2~4フレームでは0.2, 0.4, 0.6, 0.8」というようにプロパティ値が自動計算されるので、作業は「時点毎のプロパティ値を固定していく作業」の繰り返しです。「固定」するためにはプロパティ値の右にある◇
を◆
にします。
例えば私の「星」に対する作業の流れをまとめると・・・
0フレーム: 星のScale: 0, 0
12フレーム: 星のScale: 1.2, 1.2
14フレーム: 星のScale: 1.0, 1.0
です。しかしこれだけだとやや単調な動き・・・。そこでタイムラインの「星」の行を選択し、画面右側のプロパティの一番したKEY INTERPOLATION
のType
をLiner
からCubic
に変えてみましょう。するとどうでしょう・・・生き生きしましたね!(語彙力...
星の周りの四角に対するアニメーションもつけてみました。1~4直角に対して、45度の四角をやや遅れて出しています。えぇ、チュートリアルにあるデザインのパクリ(劣化版)ですね!
他、DESIGN
ページに戻ってEFFECTS
を足し、ぼかしBlur
や影Drop Shaddow
の変化をつけるとそれなりの見た目になっていきますが、本題から逸れるので、これくらいにしておきます。
ではこのアニメーションをFlutterで取り込める形式で保存しましょう。画面右上の出力アイコンからExport
を選択します。Format
はBinary。Duration from Last Keyframe
をONにすると、最後にプロパティを固定したフレーム以降を切り捨てることができます。EXPORT
ボタンをクリックすると、app_splash.flr
ファイルがダウンロードされます。
では次に、Flutterの実装を行いましょう。
2) Navigatorによるページ遷移を実装する
Navigatorの説明は省略します。ページ遷移はmain.dartに定義します。以下のような実装になります。
import 'package:flutter/material.dart';
import 'view/app_splash_page.dart';
import 'view/my_home_page.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Flare Splash-screen Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
routes: <String, WidgetBuilder>{
'/': (_) => AppSplashPage(),
'/home': (_) => MyHomePage(title: 'Flutter Demo'),
},
);
}
}
- AppSplashPageは初期画面であり、アニメーションスプラッシュViewにあたる部分を指します。この後で作ります。
- MyHomePageはホーム画面を指します。ホーム画面はFlutterのサンプル実装でも構いませんが、ホーム画面からスプラッシュ画面への逆行を防ぐため、ホーム画面のルート位置にWidget
WillPopScope
を配置する必要があります。
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: AppBar(
...(省略)...
3) 初期画面を作成し、Riveで作成した2Dアニメーション(*.flr)を組み込む。
pubspec.yamlにflutter_flare
をインストールします。
dependencies:
flutter:
sdk: flutter
flare_flutter: ^2.0.5
pubspec.yamlに、Riveで作成する2Dアニメーション(*.flr)をassetsとして登録するための定義を追加します。
※ここでは/assetsディレクトリに置いたものすべてを認識する例にしています。
flutter:
assets:
- assets/
Riveで作成した2Dアニメーション(*.flr)をassets/
ディレクトリに配置します。
AppSplashPageを実装します。Riveで作成した2Dアニメーション(*.flr)の組み込みは、以下のような実装になります。
import 'package:flare_flutter/flare_actor.dart';
import 'package:flutter/material.dart';
class AppSplashPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => _AppSplashPageState();
}
class _AppSplashPageState extends State<AppSplashPage>{
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Container(
width: double.infinity,
height: double.infinity,
color: Colors.blueAccent,
child: FlareActor(
'assets/app_splash.flr',
alignment: Alignment.center,
fit: BoxFit.contain,
animation: 'all',
callback: (name) {
Navigator.of(context).pushReplacementNamed("/home");
},
)
)
);
}
}
- Riveで作成した2Dアニメーション(*.flr)は、Widget
FlareActor
を使って組み込みます。 - 引数
animation
で、再生するアニメーション名を指定します。 - 引数
callback
で、アニメーション終了後の処理を記述することができます。ここでは、ホーム画面への遷移を指定します。 - ホーム画面への遷移は、メソッド
pushReplacementNamed
を使用して、ホーム画面からスプラッシュ画面への逆行を防ぎます。 - Widget
WillPopScope
を指定することで、AndroidのBackボタンによって画面遷移の逆行が起きる問題を防ぎます。 - FlareActorを囲うContainerは、背景色を指定するためのものです。
ここまでを一度、デバイスで動作させてみましょう。
以下、リリースビルドして動作させた結果です。
flutter run --release
スプラッシュアニメーションからホーム画面への遷移はスムーズにできましたね!
しかしスプラッシュアニメーションの前に白い画面が見えるのがダサいです。この部分が、私がローディング画面と呼んでいる部分。ネイティブスプラッシュスクリーンを設定することで差し替えましょう。
4) ネイティブスプラッシュスクリーンを設定する。
ネイティブスプラッシュスクリーンとして表示する画像を用意し、assets/app_splash.png
に保存します。
私は720*1280のサイズで、中央に白い★がある透過PNGを保存しました。
次に、Flutterアプリケーションにflutter_native_splash
プラグインを組み込みます。
dependencies:
flutter:
sdk: flutter
flare_flutter: ^2.0.5
flutter_native_splash: ^0.1.9
さらにflutter_native_splash
プラグイン用の設定を追記します。
-
image
は表示する画像です。 -
color
は背景色です。私はアニメーションに指定した背景色blueAccent
と同じ色"448AFF"にしてみました。
flutter_native_splash:
image: assets/app_splash.png
color: "448AFF"
pubspec.yaml
を保存したら、次のコマンドを実行。するとiOSとAndroid向けにスプラッシュスクリーンが設定されます。
flutter pub get
flutter pub pub run flutter_native_splash:create
ではデバイスで動作させてみましょう。
以下、リリースビルドして動作させた結果です。
flutter run --release
ダサい白の画面がなくなって、ほら、いい感じ!(語彙力...
あと、デザインが致命的にアレな点はお許しください。。。
最後に
私はプログラマーですが、プログラマーでもそれなりにアニメーションが作れちゃうという点で「Riveは面白いなーっ」て思いました。Flutterはプログラミング経験の浅い人でもクロスプラットフォームに対応するアプリを短期間で作ることができる素晴らしいフレームワークだと感じているので、ぜひそこにRiveで作った2Dアニメーションも導入してもらって、より多くの人にアプリ開発ライフをより楽しんでもらえたらいいな、そんな想いでこの記事をまとめました。
この記事が1人でも多くの方の助けになれば幸いです。
(2020/8/13 追記)
続編の記事を公開しました。