第二十二章:動畫(十七)

子動畫
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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章