通常、アニメーションはアプリや Web サイトの視覚的な魅力を高め、ユーザーの全体的なエンゲージメントを向上させます。 Forrester Research の調査によると、適切に実行されたアニメーションを備えた Web サイトでは、ユーザー エンゲージメントが最大 400% 増加します。魅力的なアニメーションはユーザーの注意を引き、プラットフォームとの対話を促すことができます。ただし、特により高度なアニメーション ツールやテクニックを使用する場合、開発者がアニメーションを習得するには学習曲線が必要です。 アニメーションの経験がない開発者でも、他のアニメーション ツールやフレームワークに比べて、Rive を理解するのは比較的簡単です。 Rive (以前は Flare として知られていました) は、アニメーションの経験がほとんどまたはまったくない開発者でも、ユーザーフレンドリーでアクセスしやすいように設計されています。この記事では、シンプルで美しい Rive アニメーションを簡単に作成し、Flutter アプリで管理する方法を学びます。 目次 Rive の紹介🧙♂️ Rive の基本概念🧗 シンプルなインタラクティブなログインアニメーション🚀 アートボードに要素を設定します📃 アニメーションの時間!🕶️ ステートマシンをセットアップします🏍️ Flutter アプリにアニメーションを実装します👨🚒 結論🏋️♀️ 参考文献🧶 Rive の紹介🧙♂️ Rive は、 でユーザーフレンドリーなアニメーション ツールおよびランタイム エンジンであり、開発者やデザイナーがモバイル アプリ、Web アプリケーション、ゲームなどのさまざまなプラットフォーム向けに魅力的でインタラクティブなアニメーションを作成できるようにします。 強力 Rive の基本概念🧗 主要な概念は次のとおりです。 アートボードは、アニメーションを作成するキャンバスです。これは、グループ、コンストレイント、ボーンなどのアニメーション要素を作成および整理するための主な場所です。 アートボード: タイムラインはアニメーションが定義される場所です。これにより、キーフレームを設定し、時間の経過とともにオブジェクトがどのように変化するかを指定できます。キーフレームは、オブジェクトのプロパティが明示的に定義されている特定の時点を表します。アニメーション システムはキーフレーム間を補間して、スムーズなトランジションを作成します。 タイムライン: Rive には、アニメーションにさまざまな状態を指定できるステート マシン機能があります。ユーザー入力やその他の条件に基づいて状態遷移をトリガーでき、現在の状態に基づいてさまざまな動作を行うインタラクティブなアニメーションを作成できます。 ステート マシン: Rive ではアニメーションをコードとしてエクスポートできるため、アニメーションをアプリケーションに簡単に統合できます。 Flutter 開発者向けに、Rive は Flutter プロジェクトでの Rive アニメーションの使用を容易にする Flutter ランタイムと統合パッケージを提供します。 コードのエクスポート: シンプルなインタラクティブなログインアニメーション🚀 簡単なログイン アニメーションを作成し、それを Flutter アプリにエクスポートするプロセスを実行します。 StateMachine を使用して、アプリ内でのこのアニメーションの対話性を管理します。最終的にはこんな感じになるはずです👇🏽 アートボードに要素を設定します📃 Rive アートボードに要素を設定するには、以下の手順に従ってください。 まず、要素自体を取得する必要があります。 Figma の から入手しました。要素を SVG ファイルとしてエクスポートします。 ユーザーペルソナイラストテンプレート に移動します。 ボタンをクリックして下書きを開きます。 Rive 「GetStarted」 下書きで新しいファイルを作成し、空のアートボードを選択します。 要素をアートボードにドラッグ アンド ドロップすると、自動的にアセット フォルダーに追加され、アートボード上に配置されたことが確認できます。次のようになります 👇🏽 サイドバーで、この要素を構成するさまざまな形状 、それに応じて名前を付けます。 使用して、グループ化するすべてを選択します。選択したら、 使用してグループ化します。このように見えるはずです 👇🏽 をグループ化し Ctrl または Ctrl + Shift を Ctrl + G を 次に、この要素にボーンを追加します。ボーンは、よりダイナミックでリアルなアニメーションの作成に役立ちます。このアニメーションをどのように仕上げるかを考慮して、首と胸にボーンを追加して、呼吸しているかのような錯覚を作成します。髪も少し動かしたいので、髪にボーンを追加します。 左上隅にあるボーンツールを選択するか、 を使用します。ボーンを追加すると、次のようになります 👇🏽 Ctrl + B 次に、識別しやすいようにボーンの名前を変更します。また、顔のすべての要素をグループ化し、この新しいグループに という名前を付けます。階層関係を使用して、影響または変形する必要があるこの要素の部分にボーンを接続できます。これを行うには、ボーンを直接影響するシェイプに移動します。グループまたはボーンを移動するには、マウスを使用して選択して移動します。こんな感じになります👇🏽 face 次に骨を縛って重さを量ります。バインドにより、ボーンが動くと、それに応じてキャラクタのサーフェスの対応する部分が動き、変形しているかのような錯覚が生まれます。頂点の重み付けとも呼ばれる重み付けには、特定のボーンへの近接性に基づいてキャラクタのメッシュの各頂点に影響値 (重み) を割り当てることが含まれます。バインドするシェイプのパスに移動します。首の場合は、このようにして首の骨にバインドします。 ボーンをバインドした後、ウェイトを割り当てて頂点を設定します。ここで、2 つのボーンに 50% の効果を持たせたいため、最後の頂点セットに 50% を設定していることに注意してください。特に、設定された頂点が 2 つのボーンに影響するセクションをカバーする場合は、50% を使用する必要があります。ここで、髪の毛のパスについても同じことを行います。また、髪の毛に流れるような動きを実現するために、左右のボーンを 1 つから 2 つに変更します。 このアニメーションでは点滅効果を持たせたいと考えています。これを実現するには、次のように 2 つの目の形にクリップ機能を使用します 👇🏽 次に、アニメーション中に頭を動かしたいので、移動制約を使用してヘッド トラッキングをこの要素に追加します。これは 2D 要素であるため、移動制約を追加すると、奥行きと何らかの形の 3D 効果が与えられます。すべてを選択してグループ化します。これで 1 つのグループができました。 次に、左上隅でグループ ツールを選択し、頭の中心 (鼻の部分) にグループを作成します。右側のツールバーで、スタイルをグループからターゲットに変更し、 という名前を付けて複製し、複製したものに ctrl_front ctrl_back という名前を付けます。 右側のツールバーから制約オプションを選択します。利用可能な制約オプションのリストから変換制約を選択します。選択した制約オプションの前のアイコンをクリックして、そのプロパティを設定します。 ターゲット ctrl_back については、 強度を -100 に設定し、ターゲットを 動かすと反対方向に動きます。これは、耳など、反対方向に動く必要がある顔の部分に制約を設定するのに役立ちます。このように見えるはずです 👇🏽 Ctrl Front に設定します。 Ctrl キーを前に動かすと、 Ctrl キーを後ろに 次に、顔の残りの部分に制約を設定します。また、目 (左と右) と耳 (左と右) をグループ化して、より適切に管理できるようにします。こんな感じで目にコンストレイントを設定していきます👇🏽 最初に目のグループの原点を の原点と同じに設定する方法に注目してください。そのため、 ターゲットを移動すると、このターゲットに拘束されている目のグループも、ぎこちなく飛び回ることなく一緒に移動します。以下についても同じことを行います。 ctrl_front ctrl_front グループ 拘束強度 原点位置 目標 眼鏡 5% ctrl_front の原点と同じ ctrl_front 眉毛 10% ctrl_front の原点と同じ ctrl_front 耳 5% 原点を設定する必要はありません ctrl_back 鼻 5% ctrl_front の原点と同じ ctrl_front 顔 5% ctrl_front の原点と同じ ctrl_front 唇に制約を設定する必要はありません。 すべての制約を追加し終えた後の様子です 👇🏽 💃🏽 🥳 おめでとうございます。達成したい種類のアニメーションに対応する要素の準備が完了しました。ふぅ!! アニメーションの時間!🕶️ 右側のツールバーで ボタンをクリックして、アニメーション インターフェイスに切り替えます。 6 つのアニメーション タイムラインを作成し、すべてをステート マシンと結び付けます。タイムラインでは、ボーンとコンストレイントで以前に設定したものを使用して、キーフレームを設定して、実現したいアニメーションを作成できます。 「アニメーション」 最初のタイムライン アニメーションはアイドル アニメーションです。アニメーションのIdle状態になります。アニメーション要素が関与していない場合にこれを使用します。 まず、アニメーション プロセスを開始する前に、要素のすべての部分をグループ化し、character という名前を付けます。 次に、継続時間を 4 分に設定します。 ワークエリアを設定し、タイムラインのタイプをループに設定します。アイドルアニメに最適です。 このアイドル アニメーションでは、呼吸、髪のわずかな動き、まばたきのイリュージョンを作成します。首のボーン、髪のボーン、右目/左目の要素を使用して、さまざまなポーズで必要なキーフレームを設定します。これは、タイムライン上のポイントで選択したアイテムの特定のプロパティを設定できることを意味します。あるキーフレームから次のキーフレームへの遷移スタイルを考慮して、必要な補間の種類を選択します。これは、「タイムライン」セクションの右下にあります。あるキーフレームから次のキーフレームにどのように移動するかに応じて、補間はホールド、リニア、またはカーブのいずれかになります。こんな感じになります👇🏽 上の GIF から、タイムライン上のさまざまなキーフレームで、選択したアイテムにさまざまなポーズを設定していることがわかります。あるキーフレームから別のキーフレームへのこの移行により、アニメーションが形成されます。これと同じ手順を使用して、他の 5 つのタイムラインを作成します。 すると、このアニメーションが表示され、さまざまなタイムラインを詳しく確認できます。こんな感じです👇🏽 ここをクリック ステートマシンをセットアップします🏍️ このアニメーションプロセスの最終部分に来ました。ステート マシンは、アニメーションを視覚的に接続する方法です。ステート マシンを使用すると、設定した入力に基づいてどのアニメーションを再生するかを制御できます。 2 つ以上のタイムライン アニメーションを混合またはブレンドして、同時に再生することができます。ステート マシンで適切な種類の入力を選択する必要があります。これは、アプリでアニメーションを制御するために使用するものだからです。 ステート マシンには 3 種類の入力があります。 数値: 数値入力は、定量的データを表現および制御するためにステート マシンで使用される数値です。入力された数値に応じて特定の状態に遷移するようにステート マシンを設定できます。 ブール値: ブール入力は、true または false のバイナリ値です。ここで、ステート マシンは、入力値 (true または false) に応じて特定の状態に遷移します。 トリガー: トリガー入力は、イベントを通知するために使用される入力です。明示的に変更されるまで状態を維持するブール入力とは異なり、トリガーはトリガーされた後にデフォルトの状態にリセットされます。 [アニメーション] パネルで、プラス ボタンをクリックし、ステート マシンを作成します。これを という名前にします。この名前は、コードの後半でステート マシンを識別するために必要になるため、重要です。 Login State Machine ステート マシンをセットアップするには、次の手順に従います。 ステート マシンに 2 つのレイヤーを作成し、1 つの名前を に変更します。複数のレイヤーは、複数の状態を同時にプレイするのに役立ちます。ステート マシンに別のレイヤーを取得するには、StateMachine グラフの上部にあるプラス アイコンをクリックします。 Type [入力] セクションでは、ステート マシンのすぐ横にラベルが付いているのがわかります。プラス アイコンをクリックし、数値入力を選択し、 という名前を付けます。 と タイムライン アニメーションをブレンド (混合) するときにこの入力を使用し、数値が増加するにつれてキャラクターが左から右を見ているように見えるようにします。 look look_left look_right の 別の入力 (今回はブール値) を作成し、 という名前を付けます。アニメーションをいつ表示するかを制御します。 2 つのトリガー入力を作成し、1 つの名前を 、もう 1 つを 変更します。これは、成功状態と失敗状態をトリガーするために必要になります。 check failed success に 次に、 アニメーションと アニメーションを レイヤー グラフにドラッグ アンド ドロップします。このグラフには、いくつかのデフォルトの状態が表示されます。 look_idle look_left タイプ エントリ - これは、このステートに接続されているアニメーション ステートのエントリ ポイントです。 Exit - これは、このステートに接続されているアニメーション ステートの終了ポイントです。 Anystate - これに接続されているアニメーション ステートは、トランジションの条件を満たす限り再生されます。 遷移は、2 つ以上の状態を結ぶ線と矢印です。矢印の方向を見ると、状態がどのように接続されているかがわかります。これをクリックすると、トランジションのプロパティが表示されます。プロパティで 以前に作成した入力のいずれかを使用して、遷移の次の状態の前に必要な が満たされる必要があることを定義できます。 条件を作成できます。 条件 層で、transition を使用して直線的に 、 、および 状態を接続します。 状態の場合は、 アニメーションと アニメーションを組み合わせたものにする必要があります。これを行うには、グラフ上で 状態を選択し、パネルの左側で Blend 1d を選択します。入力オプションとして、 入力を選択します。この入力はブレンドを制御します。次に、Timelines セクションで、 および タイムライン 選択し、それらを 0 と 100 に設定します。look 入力 Figure を増やすと、2 つのアニメーションがブレンドされます。 タイプ Entry look_Idle look_left look_left look_left look_right look_left look look_left look_right を 遷移線と矢印を使用して、ブレンド状態を に接続します。ここで矢印をクリックし、条件をチェック入力が false の場合に設定します。これは、アニメーションを制御し、チェック ブール値が false のときに 状態を表示するように StateMachine に指示するのに役立ちます。 からブレンド状態に戻る遷移矢印に対しても同じことを行いますが、今度は boolean が true に設定されていること 。 look_idle look_idle look_idle を確認します 入力のチェックボックスをクリックすると、それを true または false に設定できるようになります。ステート マシンを再生すると、 ブール値を true に変更するまで 状態が表示され続け、その後 アニメーションが開始されます。 と をブレンドするには、Look 入力数値を増やします。 チェック チェック look_Idle look_left look_left look_right 次に、Layer1 で、 トリガーと トリガーを追加します。 状態から 状態に接続します。 状態から、 と 状態の両方を接続します。 状態から 状態への遷移に この で トリガー入力を追加します。これは、ステート マシンが 入力がトリガーされた場合にのみ アニメーションを再生する必要があることを示しています。 成功 失敗 エントリー アイドル アイドル 成功状態 失敗 アイドル 成功 条件を追加します。 状態 成功 成功 成功 状態遷移に対しても同じことを行いますが、代わりに に トリガーを追加します。次に、 から ここで を選択し、100% に設定します。これは、アイドル アニメーションは、 アニメーションの再生が終了したときにのみ再生されることを意味します。 状態への 移行でも同じことを行います。 失敗 条件 失敗 成功 アイドルに戻る遷移ラインを作成します。 [終了時間] 成功 アイドル フェイルバック これで、ステートマシンの完全なアニメーションは次のようになります 👇🏽 完全なアニメーションとステート マシンを確認してください。 ここで おめでとうございます 🥳、要素をアニメーション化し、ステート マシンで設定することに成功しました。ただし、rive ファイルをエクスポートする前に、背景とキャラクターのシャツの色を変更します。こんな感じになります👇🏽 背景色は(#B581EB)、キャラクターのシャツ色は(#BD08D7)です。 すべての詳細を確認するには、ここにアニメーションへの があります リンク Flutter アプリにアニメーションを実装します👨🚒 このアニメーションをログイン ページで使用します。 Flutter アプリ プロジェクトを作成し、Rive 依存関係を に追加します。 pubspec.yaml dependencies: rive: ^0.11.12 また、エクスポートした Rive ファイルをプロジェクト アセットに追加します。これで、デザインに基づいて UI の作成に進むことができます。アニメーションで次のことを行うことを目的としています。 電子メール/パスワードが正しい場合、成功アニメーションが表示されます。 メールアドレス/パスワードが間違っている場合、失敗アニメーションで反応します テキストフィールド内のカーソルの方向で応答します Widget Build 関数の前に、まずいくつかのことを定義します。 ///Login details String emailCred = "nikki@gmail.com"; String passwordCred = "123456"; /// input form controller FocusNode emailFocusNode = FocusNode(); TextEditingController emailCtr = TextEditingController(); FocusNode passwordFocusNode = FocusNode(); TextEditingController passwordCtr = TextEditingController(); /// rive controller and input values StateMachineController? controller; SMIInput<bool>? check; SMIInput<double>? look; SMIInput<bool>? success; SMIInput<bool>? fail; bool isLoading = false; bool isError = false; @override void initState() { emailFocusNode.addListener(emailFocus); passwordFocusNode.addListener(passwordFocus); super.initState(); } @override void dispose() { emailFocusNode.removeListener(emailFocus); passwordFocusNode.removeListener(passwordFocus); super.dispose(); } void emailFocus() { check?.change(emailFocusNode.hasFocus); } void passwordFocus() { check?.change(passwordFocusNode.hasFocus); } ここで、次のことに注意してください。 正しい電子メールとパスワードが定義されています。 電子メールとパスワードのフォーカス ノードとテキスト編集コントローラーも定義されます。 ここでは、Rive コントローラーと入力が null 許容として定義されています。入力は、ステート マシンで使用される正確な名前を使用して定義されていることがわかります。 ロードおよびエラーのブール値が定義されます。 関数と 関数では、チェック入力はブール値 に基づいて変更されます。 emailFocus passwordFocus FocusNode.hasFocus 次に、 関数と 関数で、リスナーが追加および削除されることがわかります。リスナーはフォーカスの変化を聞くために使用されます。 initState dispose UI のコードと残りのコードは 確認できます。このコードは、RiveAsset を追加する方法を示しています。 ここで SizedBox( height: 250, width: 250, child: RiveAnimation.asset( "assets/login_screen.riv", fit: BoxFit.fitHeight, stateMachines: const ["Login State Machine"], onInit: (artboard) { controller = StateMachineController.fromArtboard( artboard, "Login State Machine", ); if (controller == null) return; artboard.addController(controller!); check = controller?.findInput("check"); look = controller?.findInput("look"); success = controller?.findInput("success"); fail = controller?.findInput("fail"); }, ), ), 上記のコードから、次のことがわかります。 StateMachine には、Rive エディタで付けた名前と同じ名前が付けられます。 コントローラーと入力が定義されている ログイン関数のコードは次のとおりです。 void login()async{ //extract the text coming from the text fields final email = emailCtr.text; final password = passwordCtr.text; //Set loading boolean to true and delay to give an illusion of loading setState(() { isLoading = true; }); await Future.delayed( const Duration(milliseconds: 2000), ); // check if details entered is the same as the correct creditials defined if (email == emailCred && password == passwordCred) { //if correct trigger the success input and set error boolean to false success?.change(true); setState(() { isError = false; }); if(context.mounted){ // delay and navigate to home screen await Future.delayed( const Duration(seconds: 2),(){ Navigator.push(context, MaterialPageRoute(builder: (context) =>const HomeScreen())); }); } } else { // if details don't match defined credentials // set error boolean to true and trigger the fail input // set loading boolean to false setState(() { isError = true; }); fail?.change(true); } setState(() { isLoading = false; }); } 完全なコードは 確認してください。 ここで これにより、ログイン アニメーション コードが完成しました。すべては次のようになります。 結論🏋️♀️ おめでとう!このシンプルなインタラクティブなログイン アニメーションが完成しました。私たちが達成できたすべての概要は次のとおりです。 Rive アートボードに要素を設定します。 この要素のさまざまなアニメーション状態を作成します。 ステートマシンの助けを借りてこれらすべての状態をまとめます エクスポートして Flutter アプリに追加します このチュートリアルを段階的に実行すると、いくつかのボトルネックに直面する可能性がありますが、練習すれば簡単になるでしょう。このチュートリアルを進める際にサポートが必要な場合は、 で私に連絡するか、コメントしてください。 Twitter Rive アニメーションをよりよく理解するには、これらのビデオ チュートリアルをチェックしてください。 基本的なリギングテクニック ステートマシン ヘッドトラッキング用リグアートワーク Rive アニメーションに関するいくつかのビデオ チュートリアルをチェックすることもできます。 Rive チャンネルでは、 参考文献🧶 アニメーションログインキャラクター でも公開されています。 ここ