第二十二章:动画(十七)

简介: 子动画ConcurrentAnimations中的前两个示例是单个动画。 Animation类还支持子动画,这就是标记为“Animation 3”的Button的处理程序。 它首先使用无参数构造函数创建父动画对象。

子动画
ConcurrentAnimations中的前两个示例是单个动画。 Animation类还支持子动画,这就是标记为“Animation 3”的Button的处理程序。 它首先使用无参数构造函数创建父动画对象。 然后它创建两个额外的Animation对象,并使用Add和Insert方法将它们添加到父Animation对象:

public partial class ConcurrentAnimationsPage : ContentPage
{
    __
    void OnButton3Clicked(object sender, EventArgs args)
    {
        Button button = (Button)sender;
        // Create parent animation object.
        Animation parentAnimation = new Animation();
        // Create "up" animation and add to parent.
        Animation upAnimation = new Animation(
            v => button.Scale = v,
            1, 5, Easing.SpringIn, 
            () => Debug.WriteLine("up finished"));
        parentAnimation.Add(0, 0.5, upAnimation);
        // Create "down" animation and add to parent.
        Animation downAnimation = new Animation(
            v => button.Scale = v,
            5, 1, Easing.SpringOut, 
            () => Debug.WriteLine("down finished"));
        parentAnimation.Insert(0.5, 1, downAnimation);
        // Commit parent animation.
        parentAnimation.Commit(
            this, "Animation3", 16, 5000, null, 
            (v, c) => Debug.WriteLine("parent finished: {0} {1}", v, c));
        }
    __
}

这些Add和Insert方法基本相同,在实际使用中是可以互换的。唯一的区别是Insert返回父动画对象而Add不返回。
这两种方法都需要两个类型为double的参数,名称为beginAt和finishAt。这两个参数必须介于0和1之间,而finishAt必须大于beginAt。这两个参数表示这些特定子动画活动的总动画中的相对时间段。
总动画长达五秒钟。这是Commit方法中5000的参数。第一个子动画将Scale属性从1设置为5. beginAt和finishAt参数分别为0和0.5,这意味着此子动画在整个动画的前半部分处于活动状态 - 即在前2.5秒内处于活动状态。第二个子动画将Scale属性从5返回到1. beginAt和finishAt参数分别为0.5和1,这意味着此动画发生在整个五秒动画的后半部分。
结果是Button在2.5秒内缩放到其大小的五倍,然后在最后的2.5秒内缩小到1。 但请注意两个子动画上设置的两个缓动函数。 Easing.SpringIn对象导致Button在变大之前最初缩小,而Easing.SpringOut函数也会导致Button在完整动画结束时变得小于其实际大小。
正如您在单击按钮以运行此代码时所看到的,现在调用所有已完成的回调。 这是将Animation类用于单个动画并使用它的一个区别
儿童动画。 子动画的完成回调指示该特定子项何时完成,并且传递给Commit方法的完成回调指示整个动画何时完成。
使用儿童动画时还有两个不同之处:

  • 使用子动画时,从Commit方法的重复回调返回true不会导致动画重复,但动画将继续运行而没有新值。
  • 如果在Commit方法中包含Easing函数,并且Easing函数返回大于1的值,则动画将在该点终止。 如果Easing函数返回小于0的值,则该值被钳制为等于0。

如果要使用返回小于0或大于1的值的Easing函数(例如,Easing.SpringIn或Easing.SpringOut函数),请在一个或多个子动画中指定它,如示例所示, 而不是Commit方法。
C#编译器将实现IEnumerable的类的Add方法识别为集合初始值设定项。 若要将动画语法保持最小,可以使用一对花括号跟随父动画对象上的new运算符,以使用子项初始化内容。 这些外部花括号内的每对花括号都包含Add方法的参数。 这是一个有三个孩子的动画:

public partial class ConcurrentAnimationsPage : ContentPage
{
    __
    void OnButton4Clicked(object sender, EventArgs args)
    {
        Button button = (Button)sender;
        new Animation
        {
            { 0, 0.5, new Animation(v => button.Scale = v, 1, 5) },
            { 0.25, 0.75, new Animation(v => button.Rotation = v, 0, 360) },
            { 0.5, 1, new Animation(v => button.Scale = v, 5, 1) }
        }.Commit(this, "Animation4", 16, 5000);
    }
    __
}

另请注意,Commit直接在Animation构造函数上调用。这和您编写此代码一样简洁。
这些隐式Add方法的前两个参数指示子项处于活动状态的整个父动画中的位置。第一个子项为“缩放”属性设置动画,并在父动画的前半部分处于活动状态,最后一个子项也为“缩放”属性设置动画,并在父动画的后半部分处于活动状态。这与前一个例子相同。但现在还有一个Rotation属性的动画,其开始和结束值分别为0.25和0.75。此旋转动画在第一个“缩放”动画的中间开始,并在第二个“缩放”动画的中途结束。这就是儿童动画可以重叠的方式。
Animation类还包括两个名为WithConcurrent的方法,用于将子动画添加到父动画对象。 这些类似于Add和Insert方法,除了beginAt和finishAt参数(或者在其中一个WithConcurrent方法中调用它们的开始和结束)不限制在0到1的范围内。但是,只有那个部分 对应于0到1范围的子动画将处于活动状态。
例如,假设您调用WithConcurrent来定义一个子动画,该动画将Scale属性从1到4,但是beginAt参数为-1,finishAt参数为2。
beginAt值-1对应Scale值1,finishAt值2对应Scale值4,但0和1范围之外的值不在动画中起作用,因此Scale属性 只会动画从2到3。

目录
相关文章
|
7月前
|
存储 开发工具 索引
游戏编程之十七 生成简单的动画
游戏编程之十七 生成简单的动画
31 0
|
JavaScript Android开发
第二十二章:动画(二十一)
使用AnimationExtensions为什么ViewExtensions不包含ColorTo动画? 这种方法没有你最初假设的那么明显有三个可能的原因:首先,VisualElement定义的唯一Color属性是BackgroundColor,但通常不是要设置动画的Color属性。
545 0
|
JavaScript Android开发
第二十二章:动画(二十)
实现贝塞尔动画一些图形系统实现动画,该动画沿着贝塞尔曲线移动视觉对象,甚至(可选地)旋转视觉对象,使其保持与曲线相切。Bezier曲线以法国工程师兼数学家PierreBézier的名字命名,他在雷诺工作期间开发了用于汽车车身交互式计算机辅助设计的曲线。
617 0
|
JavaScript Android开发
第二十二章:动画(十九)
更多你自己的等待方法之前,您已经了解了如何将TaskCompletionSource与Device.StartTimer一起使用来编写自己的异步动画方法。 您还可以将TaskCompletionSource与Animation类结合使用,编写自己的异步动画方法,类似于ViewExtensions类中的方法。
630 0
|
Android开发
第二十二章:动画(十八)
超越高级动画方法你到目前为止看到的ConcurrentAnimations中的例子仅限于Scale和Rotate属性的动画,因此它们没有显示任何你无法做的事情。ViewExtensions类中的方法。
702 0
|
JavaScript Android开发
第二十二章:动画(十六)
使用Animation类让我们对Animation类进行一些实验。 这涉及实例化Animation类型的对象,然后调用Commit,它实际上开始动画。 Commit方法不返回Task对象; 相反,Animation类完全通过回调提供通知。
705 0
|
JavaScript Android开发
第二十二章:动画(十五)
深入动画 在第一次遇到时,完整的Xamarin.Forms动画系统可能会有点混乱。 让我们从可用于定义动画的三个公共类的全局视图开始。整理课程除了Easing类之外,Xamarin.Forms动画系统还包含三个公共类。
823 0
|
JavaScript Android开发
第二十二章:动画(十四)
你自己的等待动画在本章的下一节中,您将看到Xamarin.Forms实现的基础动画基础结构。这些底层方法允许您定义自己的动画函数,这些函数返回Task对象,并且可以与await一起使用。在第20章“异步和文件I / O”中,您了解了如何使用静态Task.Run方法创建执行的辅助线程,以执行像Mandelbrot计算这样的密集后台作业。
711 0
|
JavaScript Android开发 iOS开发
第二十二章:动画(十二)
永远的动画在入口动画的相反极端是永远的动画。 应用程序可以实现“永远”或至少在程序结束之前进行的动画。 这种动画的唯一目的通常是展示动画系统的功能,但最好是以令人愉快或有趣的方式。第一个示例称为FadingTextAnimation,并使用FadeTo淡入和淡出两个Label元素。
644 0
|
JavaScript Android开发
第二十二章:动画(十一)
入口动画实际编程中的一种常见类型的动画是在页面首次可见时发生的。 页面上的各种元素可以在进入最终状态之前进行简要动画处理。 这通常被称为入口动画,可能涉及: 翻译,将元素移动到最终位置。 缩放,将元素放大或缩小到最终尺寸。
845 0