maui-animations について
.NET MAUI アプリ開発者向けのアニメーションスキルです。キャンセルや繰り返しの扱い、アクセシビリティ、性能、イージング選択の注意点をまとめています。
主な機能
- 01重複アニメーションの防止とキャンセル
- 02カスタムアニメーションの繰り返し設定
- 03視覚効果を減らす設定への対応
- 04並列アニメーションと性能の指針
- 05用途に応じたイージング選択
活用シーン
- 01短時間に呼び出されたアニメーションの乱れを修正
- 02視覚効果を減らしたいユーザーへの対応
- 03並列実行する画面アニメーションの計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ davidortinau/ maui-skills --skill maui-animationsインストール後、Claude Code で/maui-animationsを入力して読み込まれたか確認します。
同梱ファイルreferences/animations-api.md
詳細
.NET MAUI アニメーション
よくある間違い
❌ 新しいアニメーションを開始する前にキャンセルし忘れる
同じプロパティで複数のアニメーションを実行すると、視覚的な乱れが生じます。
// ❌ If called rapidly, animations queue and overlap
async void OnButtonClicked()
{
await view.FadeTo(0, 500);
await view.FadeTo(1, 500);
}
// ✅ Cancel first, then animate
async void OnButtonClicked()
{
view.CancelAnimations();
await view.FadeTo(0, 500);
await view.FadeTo(1, 500);
}
❌ カスタムアニメーションの繰り返しコールバックに関する誤解
子アニメーションの repeat コールバックから true を返しても、親アニメーションは繰り返されません。親アニメーションの繰り返しを制御するのは、親の Commit に渡す repeat コールバックだけです。
// ❌ This does NOT loop the parent animation
parent.Add(0.0, 1.0, new Animation(v => view.Scale = v, 1, 2));
parent.Commit(view, "MyAnim", length: 1000,
repeat: () => false); // Parent won't loop
// ✅ Loop the parent by passing repeat to Commit
parent.Commit(view, "MyAnim", length: 1000,
repeat: () => true); // This loops the entire animation
❌ AbortAnimation の名前の不一致
AbortAnimation("name") は、Commit に渡した文字列と完全に一致する必要があります。一致しない場合、何も起こりません。
// ❌ Name mismatch — animation keeps running
parent.Commit(view, name: "MyAnimation", length: 1000);
view.AbortAnimation("myAnimation"); // Wrong case!
// ✅ Use a constant for the name
const string AnimName = "MyAnimation";
parent.Commit(view, name: AnimName, length: 1000);
view.AbortAnimation(AnimName);
アクセシビリティ:モーションの低減に配慮する
アニメーションを実行する前に、必ず IsAnimationEnabled を確認してください。OS の省電力モード/モーション低減モードが有効な場合、この値は false になります。
// ❌ Ignores user's accessibility preference
await view.FadeTo(1, 500);
// ✅ Respects reduced-motion settings
if (view.IsAnimationEnabled)
await view.FadeTo(1, 500);
else
view.Opacity = 1; // Jump to final state instantly
パフォーマンスに関するヒント
- アニメーションのコールバックは 16ms 未満に保つ —
Commitのデフォルト値rate: 16は、60fps での 1 フレームに相当します。複雑なコールバックはカクつきの原因になります。 - レイアウトを引き起こすプロパティ(
WidthRequest、HeightRequest)のアニメーションは避ける — 代わりにTranslationX/YとScaleを使用してください。 - 並列アニメーションには
Task.WhenAllを使用する —awaitを連鎖させる方法は、より時間がかかります。
// ❌ Sequential — takes 1500ms total
await view.FadeTo(1, 500);
await view.ScaleTo(1.5, 500);
await view.RotateTo(360, 500);
// ✅ Parallel — takes 500ms total
await Task.WhenAll(
view.FadeTo(1, 500),
view.ScaleTo(1.5, 500),
view.RotateTo(360, 500));
イージングの選び方
| 目的 | イージング | 理由 |
|---|---|---|
| ボタンのフィードバック | CubicOut | すばやく減速するため、応答性よく感じられます |
| ページ遷移 | CubicInOut | 開始と終了が滑らかです |
| バウンドする要素 | BounceOut | 遊び心があり、目を引きます |
| バネ効果 | SpringOut | 自然で弾力のある動きになります |
| ローディングインジケーター | Linear | 継続的な動きに適した一定速度です |
| 表示/非表示 | SinIn / SinOut | 控えめで、注意をそらしません |
コメント
Markdown 対応