Event

FlutterNinjas2025 Exploring Flutter Path Animations

FlutterNinjas2025 Exploring Flutter Path Animations

この記事はFlutterNinjas2025で発表した「Exploring Flutter Path Animations」の内容をまとめたものです
今回の発表ではFlutterのPathのアニメーションの仕組みやその活用案についてトークしました
具体的にはまず冒頭で以下のアニメーションをFlutterでどのように実現するかを確認しました

このようなアニメーションをどのように実現しているのか、そしてその後のJapan Symbol Quizの話についてまとめています

スライドはTestFlightで配布しているので、iOS/macOSアプリとしてダウンロードして、確認することができます(もちろんこのアプリはSlideKitに依存しています)
またこのスライドアプリのソースコードはGitHubで確認できます
そしてFlutterのPathアニメーション実装もGitHubで確認できます

この発表テーマについては以前try!SwiftTokyo2025で、Swift版を発表しています
そちらは以下の記事から確認できます

#try!SwiftTokyo2025 Exploring SwiftUI Path Animations featuring Japan Symbol Quiztry!SwiftTokyo2025でLTした「Exploring SwiftUI Path Animations featuring Japan Symbol Quiz」のトーク内容についてまとめました!...

FlutterのPathのアニメーションの仕組み

上記のアニメーションの仕組みについて、簡単に確認します
手順としては以下の4つのステップになっています

  1. アニメーションしたいShapeのPathを用意する
    • シンプルなPathの場合は自分で作成するか、AIツールを使用
    • 複雑な形状の場合は、SVGファイルを作成してFlutter Pathオブジェクトに変換することを推奨
    • SVGファイルの作成にはFigmaをよく使用
    • 重要なポイント:SVGパスはアウトライン化や閉じた状態にしないこと
  2. Pathを表示するWidgetを実装する
    • Step 1のFlutter Pathオブジェクトを準備
    • CustomPainterでcanvas.drawPathを使用してPathを描画
    • CustomPainterをCustomPaintウィジェットに設定
  3. 進捗に基づいてPathを部分的に表示する
    • computeMetricsを使用してPathからPathMetricを取得。PathMetricは長さとセグメント情報を提供
    • PathMetricのextractPathを使用して、進捗(0.0から1.0)に応じて部分的なパスを生成
    • addPathを使用してそれらのPathを結合
    • CustomPainterでcanvas.drawPathを使用してパスを描画
  4. 進捗に応じてアニメーションを有効にする
    • AnimationControllerと進捗値を準備
    • 今回の実装では、flutter_hooksパッケージのuseAnimationControllerを使用
    • 進捗値(0.0から1.0)に応じて描画範囲を変更
    • AnimationControllerのforwardまたはrepeatメソッドを実行
    • アニメーションが進行するにつれて、Pathが徐々に描画される

SVGからFlutter Pathへのカスタム変換ロジック

SVGをFlutter Pathに変換する方法は以下の通りです:

  1. xmlパッケージを使用してSVGファイルを読み込み、解析する
  2. path要素を抽出し、パスデータを含むd属性を取得する
  3. path_drawingパッケージを使用してd属性をFlutter Pathオブジェクトに変換する
  4. SVGファイルには複数のパスが含まれる場合があるため、addPath関数を使用して複数のPathを結合する

上記の実装はGitHubに記述されています
基本的にFlutterのPathさえ用意できれば、この仕組みでどのような形もアニメーションさせることができます
また同様な仕組みで他のプラットフォーム、例えばSwiftUIなどでも同様の機能を実現することができます

Japan Symbol Quiz – FlutterのPathのアニメーションの活用

ではこのPathのアニメーションはどのような場面で活用できるでしょうか?
もしかすると今までmp4やLottieなどで実現していた機能の一部をそのようなリソースファイルやライブラリを用いずに、Flutterのコードだけで実現できるかもしれません
私はそのような実用的な面ではなく、少しエンタメ的な活用方法を考えてみました

最近日本ではJapan-(region).swiftというSwiftの地域イベントが実施されています
これらのイベントでSwiftUIのPathアニメーションを使ったシンボルクイズを実施してきました
今回のFlutterNinjas2025の発表は、SwiftUIで実装したこれらの機能がFlutterでも同様に実現できるかどうかの挑戦でした

SwiftUIとFlutterアニメーションの比較

左側がSwiftUIアニメーション、右側が今回のプレゼンテーション用に実装したFlutterアニメーションで、両方とも実際のアプリとして動作しています
ほぼ同じ動きが再現できていることがわかります

固定長Pathアニメーション

固定長パスアニメーションには、異なるアプローチが必要です
まず、パス全体の長さを計算し、進捗に基づいて表示すべき部分を決定します
次に、各パスセグメントをループし、表示範囲内にあるかどうかをチェックします
現在表示されているセグメントのみを追加し、滑らかな移動効果を作成します

テキスト描画アニメーション

テキストアニメーションの場合、プロセスはより複雑になります:

  1. text_to_path_makerパッケージを使用してシングルパスフォントを読み込み、テキストを解析する
  2. 各文字のグリフパスを抽出し、その境界を測定する
  3. Y軸の反転とベースライン調整を行い、グリフパスをピクセル空間に変換する
  4. 文字間隔を考慮してグリフを水平に配置する
  5. 結合されたパスをスケールし、中央に配置する

Path上でのコンテンツ移動アニメーション

パス自体を描画するだけでなく、パスに沿ってコンテンツを移動させることもできます
移動させたいウィジェットを渡し、getTangentForOffset関数を使用してパスに沿った座標を取得します
アニメーションが進行するにつれて、変化する座標にコンテンツを配置します
これにより、任意のウィジェットがパスに従う滑らかな移動アニメーションが作成されます
必要に応じて回転を調整し、オフセットで位置を微調整することもできます

このような仕様が要求されることはないと思いますが、Pathさえ用意できれば、その軌道に任意のWidgetを移動させることができます

アイコン移動タブサンプル

このアプローチを活用することで、一部のアプリで実装されているように、画面からボトムタブにアイコンが移動するようなアニメーションの実装にも応用できるかもしれません

まとめ

今回はFlutterのPathのアニメーションについて、FlutterNinjas2025で話した内容についてまとめました
技術的にものすごいdeepな話題ではないですが、Japan Symbol Quizを含めて色々な応用が効く面白いテーマだなと思いました
またまだ色々と発展させていく余地もあるかなと思います

今回の実装により、SwiftUIで実現していたPathアニメーションがFlutterでもほぼ同様に実現できることが確認できました
4つのステップという簡単なアプローチですが、実際のアプリでも多くの応用が可能だと思います

詳細なソースコードはGitHubで確認できます
興味のある方はぜひチェックしてみてください

参考資料

  1. 【Flutter】TextをPathに追従させて動かす
0

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA