MAUI新生6.9-控件辅助功能①:动画Animation

Posted functionMC

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MAUI新生6.9-控件辅助功能①:动画Animation相关的知识,希望对你有一定的参考价值。

一、基本使用

1、MAUI为所有VisualElement对象,定义了一系列动画扩展方法,所以控制动画的原理很简单,在UI层通过x:Name定义视觉对象的变量名(或在后台代码中直接创建视觉对象),然后再后台代码中通过“扩展方法”执行动画。

//UI层:MainPage.xaml
<ContentPage ......>
    <ScrollView>
        <VerticalStackLayout Padding="20">
            <!--定义图像类型的视觉对象-->
            <Image x:Name="img"
                   Source="animation.png"
                   Aspect="Center" />
            <!--通过按钮事件,执行动画代码-->
            <Button x:Name="btn" Text="执行动画" Clicked="btn_Clicked"/>
        </VerticalStackLayout>
    </ScrollView>
</ContentPage>

//后台代码:MainPage.xaml.cs
public partial class MainPage : ContentPage

    ......private async void btn_Clicked(object sender, EventArgs e)
    
        await img.RotateTo(360, 5000); //RotateTo扩展方法,控制img对象在5秒内旋转360度,扩展方法即可以使用异步,也可以使用同步
        img.Rotation = 0; //旋转结束后,将img的旋转属性恢复为0度
    

 

2、内置的动画扩展方法

  • RotateTo/RelRotateTo:旋转/相对旋转。
  • RotateXTo:延X轴旋转。
  • RotateYTo:延Y轴旋转。
  • ScaleTo/RelScaleTo:缩放/相对缩放。
  • ScaleXTo:延X轴缩放。
  • ScaleYTo:延Y轴缩放。
  • TranslateTo:延X轴和Y轴移动。
  • FadeTo:淡入淡出。
  • CancelAnimations:取消动画。

 

3、复合动画,控制多个动画的执行顺序

//动画可以组合
//同步和异步可以组合在一起
//如下FadeTo开始后,其它动画不会等待它结束
//如下TranslateTo开始后,后面的TranslateTo会等待前一个动画结束后才开始
private async void btn_Clicked(object sender, EventArgs e)

    img.FadeTo(0, 8000); 
    await img.TranslateTo(-100, 0, 1000); 
    await img.TranslateTo(-100, -100, 1000);
    await img.TranslateTo(100, 100, 2000);
    await img.TranslateTo(0, 100, 1000);
    await img.TranslateTo(0, 0, 1000);



//Task.WhenAny中的动画,只要其中任何一个动画结束,整体就全部结束
//以下任务执行顺序:
//1-2秒:旋转到180度,第一个ScaleTo扩大到2倍并结束动画
//2-4秒:旋转继续到360度,第二个ScaleTo缩小到1倍
await Task.WhenAny<bool>
(
  image.RotateTo(360, 4000), //任务A
  image.ScaleTo(2, 2000) 
);
await img.ScaleTo(1, 2000);


//Task.WhenAll中的动画,全部完成后,整体才会结束
//以下任务会同步一起执行
await Task.WhenAll
(
    img.RotateTo(307 * 360, 60000),
    img.RotateXTo(251 * 360, 60000),
    img.RotateYTo(199 * 360, 60000)
);

 

 

二、控制动画的缓动

1、基本使用:缓动效果指控制动画变化的速度,在扩展函数的最后一个参数指定,是一个枚举类型,如果未提定,默认为线性变化(即匀速变化)。如【img.RotateTo(360,5000,Easing.SpringIn);】。框架内置的缓动效果包括以下枚举类型:

  • Linear:匀速变化。
  • BounceIn:弹跳进入。
  • BounceOut:弹跳结束。
  • CubicIn:缓慢加速。
  • CubicInOut:缓慢加束后,缓慢减速。
  • CubicOut:缓慢减速。
  • SinIn:平滑加速,和Cubic效果差不多。
  • SinInOut:平滑加速后,平滑减速,和Cubic效果差不多。
  • SinOut:平滑减速,和Cubic效果差不多。
  • SpringIn:开始时有一个回弹效果,然后开始加速。
  • SpringOut:逐渐减速,结束时有一个回弹效果。

 

2、自定义缓动效果:缓动参数实际上是一个回调函数。我们将变化过程分解为从0到1的连续时序点,通过控制返回值来控制缓动效果。比如有一个向右平移100像素的动画,在0.01时序点时,应该平移1像素,如果返回值为0.02,会变成平移2像素,动画会表现为加束。自定义缓动有三种方式,语法上只是三种回调函数的表达区别,主要还是返回值的算法比较复杂,了解一下吧。

1)函数方式:

private async void btn_Clicked(object sender, EventArgs e)

    await img.RotateTo(360,3000, (Easing)CustomEase);
    img.Rotation = 0;

//返回值分别为0,0.2,0.4,0.6,0.8,1
//缓动效果为离散跳跃方式旋转,即一顿顿的旋转
double CustomEase(double t)

    return t == 0 || t == 1 ? t : (int)(5 * t) / 5.0;

 

2)Func<double,double>委托方式

private async void btn_Clicked(object sender, EventArgs e)

    Func<double, double> CustomEaseFunc = t => 9 * t * t * t - 13.5 * t * t + 5.5 * t;
    await img.RotateTo(360,3000, CustomEaseFunc);
    img.Rotation = 0;

 

3)Easing构造函数

private async void btn_Clicked(object sender, EventArgs e)

    await img.RotateTo(360,3000, new Easing(t => 1 - Math.Cos(10 * Math.PI * t) * Math.Exp(-5 * t)));
    img.Rotation = 0;

 

 

三、自定义动画

1、定义一个旋转动画

private void btn_Clicked(object sender, EventArgs e)

    /* ①创建动画:最少需要callback、start、end三个参数。
        * callback:回调函数定义目标对象属性,其中回调参数v指动画值
        * start:属性开始值
        * end:属性结束值
        * easing:缓动效果,默认值为null。一般在执行动画时再指定
        * finished:动画执行完后的回调函数,默认值为null。一般在执行动画时再指定 */
    var animation = new Animation(callback: v => img.Rotation = v, start: 0, end: 360, easing: null, finished: null);

    /* ②执行动画:调用animation的Commit方法。参数如下:
        * owner:持有动画的对象,可以是任意对象。和name组合一起使用,主要用于判断动画是否在执行,以及取消动画
        * name:动画名称,可以是任意名称。和owner一起使用,如取消动画【img.AbortAnimation("MyAnimation");】
        * rate:动画速度,默认值为16,一般保持默认值
        * length:动画持续时间
        * easing:缓动效果
        * finished:动画结束后执行的回调,回调参数v为属性的最终值
        * repeat:指示动画是否重复执行,如果返回true,则重复执行 */
    animation.Commit(owner:img, name:"MyAnimation", rate:16, length:5000, easing:Easing.SpringIn, finished:(v, c) => img.Rotation = 0, repeat:() => true);

 

2、以上案例使用简写的方式

private void btn_Clicked(object sender, EventArgs e)

    //以上动画可以简写为(由于参数比较多,我们都以命名参数的方式来写):
    new Animation(callback: v => img.Rotation = v, start: 0, end: 360)
        .Commit(owner:this, name:"MyAnimation", length:5000, easing:Easing.SpringIn);

 

3、一个动画中可以创建子动画,实现复合动画的效果

private void btn_Clicked(object sender, EventArgs e)

    //Animation对象实际上是一个集合,所以可以在一个Animation对象里添加子动画
    //Animation集合的项目,有三个成员,子动画开始时间、子动画结束时间、子动画对象。开始和结束时间,是相对于父动画而言,从0至1//缓动效果即可以在创建动画对象时指定,也可以在执行时指定,但创建对象时指定的缓动权限更高。
    new Animation
    
        0, 0.5, new Animation(callback:v=>img.Scale=v, start:1, end:2, easing:Easing.BounceIn) ,
        0, 1, new Animation(callback:v=>img.Rotation=v, start:0, end:360, easing:Easing.SinIn) ,
        0.5, 1, new Animation(callback:v=>img.Scale=v, start:2, end:1, easing:Easing.SpringOut) 
    
    .Commit(owner:this, name:"AllAnimation", length:5000);

 

4、为任意值类型的属性创建动画:前述动画都是针对大小、位置、角度和透明度属性等。通过Animation,可以对任意VisualElement的任意值类型属性进行动画控制。

//以下案例,执行Lable字体大小变化的动画
private void btn_Clicked(object sender, EventArgs e)

    new Animation(callback:v=>lable.FontSize=v, start:16, end:80)
        .Commit(owner:this, name:"FontSizeAnimation", length:5000, easing:Easing.BounceIn);

 

5、综合上述,我们可以自定义一个类似【RotateTo】这样的动画扩展方法。可详见文档案例

 

以上是关于MAUI新生6.9-控件辅助功能①:动画Animation的主要内容,如果未能解决你的问题,请参考以下文章

[MAUI]模仿网易云音乐黑胶唱片的交互实现

按钮动画控件----------WinForm控件开发系列

MAUI中构建跨平台原生控件实现

[MAUI 项目实战] 手势控制音乐播放器:圆形进度条

Unity即将内置骨骼动画插件Anima2D

MAUI中Maui.Graphics.Controls绘制控件