关于 maui-animations
.NET MAUI 动画技能,面向开发 .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。当操作系统启用了省电或减少动态效果模式时,该属性为 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 下的一帧。复杂的回调会导致卡顿。 - 避免为会触发布局计算的属性设置动画(
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