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版を発表しています
そちらは以下の記事から確認できます

FlutterのPathのアニメーションの仕組み
上記のアニメーションの仕組みについて、簡単に確認します
手順としては以下の4つのステップになっています
- アニメーションしたいShapeのPathを用意する
- シンプルなPathの場合は自分で作成するか、AIツールを使用
- 複雑な形状の場合は、SVGファイルを作成してFlutter Pathオブジェクトに変換することを推奨
- SVGファイルの作成にはFigmaをよく使用
- 重要なポイント:SVGパスはアウトライン化や閉じた状態にしないこと
- Pathを表示するWidgetを実装する
- Step 1のFlutter Pathオブジェクトを準備
- CustomPainterでcanvas.drawPathを使用してPathを描画
- CustomPainterをCustomPaintウィジェットに設定
- 進捗に基づいてPathを部分的に表示する
- computeMetricsを使用してPathからPathMetricを取得。PathMetricは長さとセグメント情報を提供
- PathMetricのextractPathを使用して、進捗(0.0から1.0)に応じて部分的なパスを生成
- addPathを使用してそれらのPathを結合
- CustomPainterでcanvas.drawPathを使用してパスを描画
- 進捗に応じてアニメーションを有効にする
- AnimationControllerと進捗値を準備
- 今回の実装では、flutter_hooksパッケージのuseAnimationControllerを使用
- 進捗値(0.0から1.0)に応じて描画範囲を変更
- AnimationControllerのforwardまたはrepeatメソッドを実行
- アニメーションが進行するにつれて、Pathが徐々に描画される
SVGからFlutter Pathへのカスタム変換ロジック
SVGをFlutter Pathに変換する方法は以下の通りです:
- xmlパッケージを使用してSVGファイルを読み込み、解析する
- path要素を抽出し、パスデータを含むd属性を取得する
- path_drawingパッケージを使用してd属性をFlutter Pathオブジェクトに変換する
- 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アニメーション
固定長パスアニメーションには、異なるアプローチが必要です
まず、パス全体の長さを計算し、進捗に基づいて表示すべき部分を決定します
次に、各パスセグメントをループし、表示範囲内にあるかどうかをチェックします
現在表示されているセグメントのみを追加し、滑らかな移動効果を作成します
テキスト描画アニメーション
テキストアニメーションの場合、プロセスはより複雑になります:
- text_to_path_makerパッケージを使用してシングルパスフォントを読み込み、テキストを解析する
- 各文字のグリフパスを抽出し、その境界を測定する
- Y軸の反転とベースライン調整を行い、グリフパスをピクセル空間に変換する
- 文字間隔を考慮してグリフを水平に配置する
- 結合されたパスをスケールし、中央に配置する
Path上でのコンテンツ移動アニメーション
パス自体を描画するだけでなく、パスに沿ってコンテンツを移動させることもできます
移動させたいウィジェットを渡し、getTangentForOffset関数を使用してパスに沿った座標を取得します
アニメーションが進行するにつれて、変化する座標にコンテンツを配置します
これにより、任意のウィジェットがパスに従う滑らかな移動アニメーションが作成されます
必要に応じて回転を調整し、オフセットで位置を微調整することもできます
このような仕様が要求されることはないと思いますが、Pathさえ用意できれば、その軌道に任意のWidgetを移動させることができます
アイコン移動タブサンプル
このアプローチを活用することで、一部のアプリで実装されているように、画面からボトムタブにアイコンが移動するようなアニメーションの実装にも応用できるかもしれません
まとめ
今回はFlutterのPathのアニメーションについて、FlutterNinjas2025で話した内容についてまとめました
技術的にものすごいdeepな話題ではないですが、Japan Symbol Quizを含めて色々な応用が効く面白いテーマだなと思いました
またまだ色々と発展させていく余地もあるかなと思います
今回の実装により、SwiftUIで実現していたPathアニメーションがFlutterでもほぼ同様に実現できることが確認できました
4つのステップという簡単なアプローチですが、実際のアプリでも多くの応用が可能だと思います
詳細なソースコードはGitHubで確認できます
興味のある方はぜひチェックしてみてください