🎥

Flutterで簡単にアニメーションを実装する。

2023/10/31に公開

今回はflutter_animateというライブラリを使用し、アニメーションを実装するために勉強した内容を共有します。

flutter_animateとは?

https://pub.dev/packages/flutter_animate

Flutterアプリケーションでさまざまなアニメーションエフェクトを簡単に実装できるライブラリです。
フェード、スケール、スライド、フリップ、ブラー、シェイク、シマー、シャドウ、クロスフェードなどのエフェクトがライブラリの中で事前に構築されています。
例えばフェードインをwidgetに実装したい場合は、下記のように1行追加するだけでOKです!

.animate().fadeIn(duration: 500.ms),

こんな感じでアニメーションを使用したいwidgetに実装したいものを複数追加することもできます。

Text("Hello World!").animate().fade().scale()

wonderousというFluter公式が公開しているアプリでは実際にflutter_animateを使用し、アニメーションを実装しています。githubに公開もされているんですが、自分はこちらを見てすごくモチベーションが上がりました!みんな見てください!!
https://www.youtube.com/watch?v=6Hb3QiH_yps
https://flutter.gskinner.com/wonderous/
https://github.com/gskinnerTeam/flutter-wonderous-app

使用方法

ここからは実際の使用方法を簡単に説明します。

  1. flutter_animateをpubspec.yamlに追加する
dependencies:
  flutter:
    sdk: flutter
  flutter_animate:
  1. flutter pub get を行う
  2. パッケージを使用するdartファイルに下記のimport文を追加する
import 'package:flutter_animate/flutter_animate.dart';
  1. アニメーションを実装したいwidgetに使用したいエフェクトを設定する
Text("Hello World!").animate()fadeIn(duration: 500.ms),

これだけでTextWidgetにアニメーションを実装することができました。

基本的なアニメーションのエフェクト

fadeIn:オブジェクトを徐々に表示する
fadeOut:オブジェクトを徐々に非表示にする
show:オブジェクトを表示する。
hide: オブジェクトを非表示にする。
shader:砂絵のような感じで徐々に表示する
tint:オブジェクトに色のオーバーレイを追加する。例:.tint(color: Colors.red, end: 0.6)→オブジェクトに赤をオーバーレイする
untint:オブジェクトから色の色合いを除去する。例:.untint(color: Colors.white)→オブジェクトから白い色合いを取り除く。
saturate:オブジェクトの色の彩度を増やす。
desaturate:オブジェクトの色の彩度を減らす。
shimmer:オブジェクトにをキラキラさせる。blendMode、angle、size、curveなどプロパティを調整してカスタマイズできる。
move(XY):x軸・y軸に沿ってオブジェクトを移動する。
blur(XY): x軸とy軸の両方に沿ってオブジェクトをぼかす。
slideX:オブジェクトをx軸に沿って移動(スライド)する。
scale(xy): x軸とy軸の両方の次元でオブジェクトを徐々に表示させる
elevation:オブジェクトのエレベーションを変更することで、影の効果を作成する。
boxShadow: オブジェクトに影を追加する。blurRadius、color、spreadRadiusなどのプロパティを使用してカスタマイズできる。
flip:オブジェクトを反転する。水平反転のためのflipHと垂直反転のためのflipVがある。
shake(XY):オブジェクトを振る。カーブや周波数(hz)などのプロパティを指定できる。
followPath:オブジェクトを指定したパスに沿ってアニメーションする。
.quadraticBezierTo:パスにオブジェクトが従うための曲線を定義するために使用する。
rotate:指定した角度でオブジェクトを回転させる。
swap一つのウィジェットを別のウィジェットに交換(スワップ)する。
crossfade:二つのウィジェット間でクロスフェードのアニメーションを適用する。一つのウィジェットが徐々に消えていき、同時に別のウィジェットが徐々に表示される。
togle:ウィジェットの状態や属性を切り替える。特定の条件やパラメータに基づいてウィジェットの表示状態やその他の属性を変更する。

実際の動いているイメージはFlutter_animateのリポジトリにあるサンプルをビルドして見るのがわかりやすかったです!
https://github.com/gskinner/flutter_animate

アニメーションのタイミング調整

エフェクトにはオプションとしてdelaydurationcurve パラメータが存在し、これらを用いてアニメーションのタイミングを調整できます。
delay: アニメーションを開始する前に一定の時間待機させる(開始を遅らせる)設定する。
duration: アニメーションが開始から終了までにかかる時間を設定する。
curve: アニメーションの始点と終点の間の変化をどのように進行させるかを設定する。カーブの種類はlinear(一定のペース)、easeIn(ゆっくり始まり、徐々に速くなる)、easeOut(速く始まり、徐々に遅くなる)、easeInOut(ゆっくり始まり、中盤で速く、再びゆっくりと終わる)などがある

アニメーションの位置調整

アニメーションの開始値beginと終了値endを指定できます。

begin: Alignment.topLeft,//左上からアニメーションを開始
end: Alignment.bottomRight,//右下でアニメーションを終了

アニメーションのライフサイクル

onInitonStartonCompleteコールバックを使用することで、アニメーションの特定のタイミングで任意のアクションを実行することができます。
onInit: アニメーションが初期化されるときに実行される。
onStart: アニメーションの再生が開始されるときに実行される。
onComplete: アニメーションの再生が完了すると実行される。

Animate(
  onInit: () {
    print("アニメーションが初期化されました。");
  },
  onStart: () {
    print("アニメーションが開始されました。");
  },
  onComplete: () {
    print("アニメーションが完了しました。");
  },
)
.fade(end: 0.8)
.scaleXY(end: 1.1)

アニメーションの繰り返し

onPlayを使用することでアニメーションを繰り返すことができます。

.animate(onPlay: (controller) => controller.repeat())

状態の変更に応じてアニメーションを行う

targetを使用することでtargetの値が変わると自動的にアニメーションが新しいターゲット位置に遷移します。0 はアニメーションの開始位置、1 はアニメーションの終了位置を示します。

MyButton().animate(target: _over ? 1 : 0)
  .fade(end: 0.8).scaleXY(end: 1.1)
  1. 状態変数 _over を持つ Widgetを作成する。
  2. ボタンや他のウィジェットに onTap や onHover などのジェスチャを設定して、_over の値を変更する。
  3. setStateなどを使用して _over の値を変更すると、自動的に新しいtarget値に合わせてアニメーションを行う。

アニメーションの値の変更を監視・取得する

ListenEffectを使用すると、指定した期間、カーブ、開始、終了のアニメーション値(double)を受け取るためのコールバックを設定することができます。
コールバックを設定すると、アニメーションが進行するにつれて変更する値を監視したり、取得することができます。

Text("Hello").animate().fadeIn(curve: Curves.easeOutExpo)
  .listen(callback: (value) => print('current opacity: $value'))

上記の例では、TextウィジェットにfadeInを設定、アニメーションの進行に従って透明度(opacity)の変更を監視し、fadeInの進行に応じてその透明度の値をprintしています。

まとめ

Flutter_animateは、Flutterのアニメーション実装を簡単にすることができるライブラリです。
少ないコードでさまざまなアニメーションを簡単に導入することができて楽しかったです!
アニメーションのタイミングや位置の調整、ライフサイクルの監視、繰り返し再生や動的な状態変更に対応したアニメーションの実装や、アニメーションの進行をリアルタイムで監視・取得する機能を使用することでwonderousで実装されているような高度なアニメーション制御も行うことができます。
アニメーションを効果的に取り入れることでユーザーにより良いUX・UI体験をしてもらえますし、しっかりキャッチアップして自在に動かせるようになりたいなとおもいました!

Arsaga Developers Blog

Discussion