1. 程式人生 > 程式設計 >WPF關鍵幀動畫介紹與實現

WPF關鍵幀動畫介紹與實現

目錄
  • 動畫與關鍵幀的區別
    • 普通動畫
    • 關鍵幀
  • 介紹關鍵幀動畫
    • 關鍵幀動畫型別
      • 關鍵幀的動畫型別列表
      • 幀物件的型別
      • 插值方法
        • 線性內插
        • 離散內插
        • 曲線內插
        • 組合內插
    • Duration與KeyTime
      • TimeSpan
        • 百分比
          • Uniform
            • Paced
            • 關鍵幀時間及順序

              本章介紹關鍵幀動畫之前,首先需要講解一下關於WPF當中基礎動畫與本章所講的關鍵幀動畫的區別。

              動畫與關鍵幀的區別

              普通動畫

              WPF基礎動畫當中,我們熟悉的From/To/By驅動的動畫,主要在兩個值之間建立過渡效果,如下圖所示:

              WPF關鍵幀動畫介紹與實現

              下面是使用普通的ThicknessAnimation建立的愛心跳動的動畫

              WPF關鍵幀動畫介紹與實現

              關鍵幀

              對於關鍵幀動畫而言,關鍵幀動畫沒有From/To/By的屬性,而關鍵幀動畫的值則是使http://www.cppcns.com

              用幀物件來進行描述,故稱之為關鍵幀動畫,如下所示:

              WPF關鍵幀動畫介紹與實現

              下面是使用關鍵幀動畫建立的一個矩形位移的動畫

              WPF關鍵幀動畫介紹與實現

              : 能夠注意到,左下角,描述了整個動畫的過程:
              1.首先5秒內,矩形從位置0 -> 500 : LinearDoubleKeyFrame Value="500" KeyTime="0:0:5"
              2.從5-10秒內,矩形位置500 -> 200 : SplineDoubleKeyFrame KeySpline="0.25,0.5 0.75,1" Value="200" KeyTime="0:0:10"
              3.從10-12秒內,矩形位置200 -> 290 : LinearDoubleKeyFrame Value="290" KeyTime="0:0:12"

              4.從12-13.5秒內,矩形位置290 -> 300 : LinearDoubleKeyFrame Value="300" KeyTime="0:0:13.5"
              5.從13.5-15秒內,矩形位置300 -> 0 : SplineDoubleKeyFrame KeySpline="0.25,1" Value="0" KeyTime="0:0:15"
              注: 關鍵幀物件(Frame) 主要包含兩個引數,Value是目標值, KeyTime 則表達的是時間

              到目前為止,我們應該可以理解普通動畫與關鍵幀動畫的區別,對於幀動畫而言,在於控制每一個幀的表現形式,這一點並不像普通動畫中,對於整個動畫的控制我們只能從開始到結束,而幀動畫可以控制開始到結束的整個過程。

              介紹關鍵幀動畫

              下面,介紹www.cppcns.com瞭如何建立一個簡單的關鍵幀動畫。

              1.如下程式碼,建立了一個矩形,為其添加了一個點選時間觸發動畫,該動畫在Storyboard中定義並且觸發:

              <Border Width="400" BorderBrush="Black">  
                  <Rectangle Fill="Blue" 
                    Width="50" Height="50"
                    HorizontalAlignment="Left">
                    <Rectangle.RenderTransform>
                      <TranslateTransform 
                        x:Name="MyAnimatedTranslateTransform" 
                        X="0" Y="0" />
                    </Rectangle.RenderTransform>
                    <Rectangle.Triggers>
                      <EventTrigger RoutedEvent="Rectangle.MouseLeftButtonDown">
                        <BeginStoryboard>
                          <Storyboard>
                            <DoubleAnimationUsingKeyFrames
                              Storyboard.TargetName="MyAnimatedTranslateTransform"
                              Storyboard.TargetProperty="X"
                              Duration="0:0:10">
                              <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0" />
                              <LinearDoubleKeyFrame Value="350" KeyTime="0:0:2" />
                              <LinearDoubleKeyFrame Value="50" KeyTime="0:0:7" />
                              <LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />                          
                            </DoubleAnimationUsingKeyFrames>
                          </Storyboard>
                        </BeginStoryboard>
                      </EventTrigger>
                    </Rectangle.Triggers> 
                  </Rectangle>
                </Border> 
              

              說明:以上的建立了一個DoubleAnimation型別的幀動畫,為其綁定了一個目標及目標的動畫依賴屬性 "Y",Duration則為其設定了一個幀動畫持續時間,在關鍵幀動畫的集合中,定義了多個線性關鍵幀(LinearDoubleKeyFrame),為其設定了Value目標值和KeyTime持續時間。http://www.cppcns.com

              此處說講到的線性關鍵幀所屬其中的一種型別,在後面將會有更多的介紹。

              關鍵幀動畫型別

              關鍵幀動畫屬於System.Windows.Media.Animation命令空間下,命名規則約定為
              AnimationUsingKeyFrames
              Type: 為動畫的值型別,例如上面的動畫當中,需要給舉行的X軸移動位置,X的值屬於雙精度型別,所以定義的型別為 :DoubleAnimationUsingKeyFrames 。

              關鍵幀的動畫型別列表

              WPF關鍵幀動畫介紹與實現

              幀物件的型別

              正如我們建立不同型別的動畫,我們需要按照約定命名方式定義,如: DoubleAnimation,ColorAnimation 等等。
              對於幀動畫而言,主要由一個或者N個幀物件組成(Frame),幀物件同時也擁有不同的種類,故幀物件遵循一下的命名約定:
              <插值方法><型別>
              插值方法: 是幀物件使用的插值方法,如: 離散(Discrete)、線性(Linear) 、樣條(Spline) 等。
              型別: 是動畫的值型別,例如Double、Decimal等。
              KeyFrame: 固定的幀物件語法結束

              關鍵幀的主要目的是指定 和KeyTime、Value 每個關鍵幀型別都可提供這兩種屬性。

              • 屬性Value指定該關鍵幀的目標值。
              • 該KeyTime屬性指定何時(在動畫的Duration)中到達關鍵幀。 Value
                當關鍵幀動畫開始時,按其KeyTime屬性定義的順序遍接其關鍵幀。
              • 如果時間 0 時沒有關鍵幀,動畫會在目標屬性的當前值和第Value一個關鍵幀之間的轉換;否則,動畫的輸出值將成為第一個關鍵幀的值。
              • 動畫使用第二個關鍵幀指定的Value插值方法在第一個關鍵幀和第二個關鍵幀之間建立過渡。 轉換從第一個關鍵幀開始KeyTime,並在到達第二個關鍵幀KeyTime時結束。
              • 動畫將繼續,這會建立每個後續關鍵幀和其前面的關鍵幀之間的過渡。
              • 最後,動畫轉換為關鍵幀的值,其最大鍵時間等於或小於動畫的值Duration。
                如果動畫的Duration或Automatic其Duration等於最後一個關鍵幀的時間,則動畫結束。 否則,如果動畫大於Duration最後一個關鍵幀的鍵時間,則動畫將保留關鍵幀值,直到到達其Duration的末尾。 與所有動畫一樣,關鍵幀動畫使用其FillBehavior屬性來確定在到達活動週期結束時是否保留最終值。

              插值方法

              下面將主要介紹有三種不同型別的內插方法: 線性、離散和曲線。

              線性內插

              使用線性內插,動畫將以段持續時間的固定速度進行播放。 例如,如果關鍵幀段從 0 過渡到 10,持續時間為 5 秒,則動畫會在指定時間輸出以下值:

              WPF關鍵幀動畫介紹與實現

              離散內插

              使用離散內插,動畫函式將從一個值跳到下一個值,沒有內插。 如果關鍵幀段從 0 過渡到 10,持續時間為 5 秒,則動畫會在指定時間輸出以下值:

              WPF關鍵幀動畫介紹與實現

              注: 通過觀察線性和離散的插入比較,可以清晰的看出來,離線型別的插入方式,在動畫的執行過程中,我們無法在規定的時間內觀察其變化效果,直接至時間結束後,到指定的目標值。

              曲線內插

              曲線內插可能很難理解;使用不同的設定進行體驗有助於理解。 通過主曲線動畫示例,可以更改主曲線值,並檢視由此所產生的動畫結果,可以檢視最上方視訊進行理解。

              組合內插

              可在一個關鍵幀動畫中使用具有不同內插型別的關鍵幀。 如果兩個具有不同內插的關鍵幀動畫彼此跟隨,第二個關鍵幀的內插方法將用於建立從第一個值到第二個值的過渡。
              下面的示例,演示了一個使用DoubleAnimationUsingKeyFrames建立使用線性、拼接和離散插值的示例:

                    <Rectangle 
                Width="50"
                Height="50"
                Fill="Orange">  
                <Rectangle.RenderTransform>
                  <TranslateTransform 
                    x:Name="ComboAnimatedTranslateTransform" 
                    X="0" Y="0" />
                </Rectangle.RenderTransform>
                <Rectangle.Triggers>
                  <EventTrigger RoutedEvent="Rectangle.Loaded">
                    <BeginStoryboard>
                      <Storyboard>
                        <DoubleAnimationUsingKeyFrames
                          Storyboard.TargetName="ComboAnimatedTranslateTransform"
                          Storyboard.TargetProperty="X"
                          Duration="0:0:15"
                          RepeatBehavior="Forever">
                          <DiscreteDoubleKeyFrame Value="500" KeyTime="0:0:7" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="0:0:10" />
                          <SplineDoubleKeyFrame Value="350" KeyTime="0:0:15"  
                            KeySpline="0.25,1" />                      
                        </DoubleAnimationUsingKeyFrames>           
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger>
                </Rectangle.Triggers> 
              </Rectangle>
              

              Duration與KeyTime

              與其他動畫一樣,關鍵幀動畫具有屬性Duration。 除了指定動畫的Duration外,還需要指定每個關鍵幀的持續時間的哪一部分。 為此,您可以為每個動畫的關鍵KeyTime幀描述 。 每個關鍵幀指定KeyTime該關鍵幀的結束時間。
              屬性KeyTime不指定金鑰時間播放的時間。 關鍵幀的播放時長由關鍵幀的結束時間、前一個關鍵幀的結束時間以及動畫的持續時間確定。 關鍵時間可以指定為時間值、百分比或特殊值Uniform或Paced。

              TimeSpan

              以下示例演示一個持續時間為 10 秒鐘、有四個關鍵幀(這些關鍵幀的關鍵時間指定為時間值)的動畫。

              • 在前 3 秒鐘內,第一個關鍵幀在基值和 100 之間進行動畫處理,結束時間 = 0:0:03。
              • 第二個關鍵幀在 100 和 200 之間進行動畫處理。 它在第一個關鍵幀結束後開始(開始時間 = 3 秒),播放 5 秒鐘,結束時間 = 0:0:8。
              • 第三個關鍵幀在 200 和 500 之間進行動畫處理。 它在第二個關鍵幀結束時開始(開始時間 = 8 秒),播放 1 秒鐘,結束時間 = 0:0:9。
              • 第四個關鍵幀在 500 和 600 之間進行動畫處理。 它在第三個關鍵幀結束時開始(開始時間 = 9 秒),播放 1 秒鐘,結束時間 = 0:0:10。
                    <Rectangle Width="50" Height="50" Fill="Blue">
                <Rectangle.RenderTransform>
                  <TranslateTransform x:Name="TranslateTransform01" X="10" Y="30" />
                </Rectangle.RenderTransform>
                <Rectangle.Triggers>
                  <EventTrigger RoutedEvent="Rectangle.Loaded">
                    <BeginStoryboard>
                      <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                          Storyboard.TargetName="TranslateTransform01" 
                          Storyboard.TargetProperty="X"
                          Duration="0:0:10"
                          RepeatBehavior="Forever">
              
                          <!-- KeyTime properties are expressed as TimeSpan values 
                               which are in the form of "hours:minutes:seconds". -->
                          <LinearDoubleKeyFrame Value="100" KeyTime="0:0:3" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="0:0:8" />
                          <LinearDoubleKeyFrame Value="500" KeyTime="0:0:9" />
                          <LinearDoubleKeyFrame Value="600" KeyTime="0:0:10" />
                        </DoubleAnimationUsingKeyFrames>
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger>
                </Rectangle.Triggers>
              </Rectangle>
              

              百分比

              百分比值指定關鍵幀以動畫的某些Duration百分比結束。 在 XAML 中,指定百分比作為 % 符號後的數字。 在程式碼中,使用FromPercent方法並傳遞一個Double指示百分比的方法。 該值必須大於或等於 0 並且小於或等於 100%。 以下示例演示一個持續時間為 10 秒鐘、有四個關鍵幀(這些關鍵幀的關鍵時間指定為百分比)的動畫。

              • 在前 3 秒鐘內,第一個關鍵幀將在基值和 100 之間進行動畫處理,結束時間 = 0:0:3。
              • 第二個關鍵幀在 100 和 200 之間進行動畫處理。 它在第一個關鍵幀結束後開始(開始時間 = 3 秒),播放 5 秒鐘,結束時間 = 0:0:8 (0.8 * 10 = 8)。
              • 第三個關鍵幀在 200 和 500 之間進行動畫處理。 它在第二個關鍵幀結束時開始(開始時間 = 8 秒),播放 1 秒鐘,結束時間 = 0:0:9 (0.9 * 10 = 9)。
              • 第四個關鍵幀在 500 和 600 之間進行動畫處理。 它在第三個關鍵幀結束時開始(開始時間 = 9 秒),播放 1 秒鐘,結束時間 = 0:0:10 (1 * 10 = 10)。
                    <Rectangle Height="50" Width="50" Fill="Purple">
                <Rectangle.RenderTransform>
                  <TranslateTransform x:Name="TranslateTransform02" X="10" Y="110" />
                </Rectangle.RenderTransform>
                <Rectangle.Triggers>
                  <EventTrigger RoutedEvent="Rectangle.Loaded">
                    <BeginStoryboard>
                      <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                          Storyboard.TargetName="TranslateTransform02" 
                          Storyboard.TargetProperty="X"
                          Duration="0:0:10"
                          RepeatBehavior="Forever">
              
                          <!-- KeyTime properties are expressed as Percentages. -->
                          <LinearDoubleKeyFrame Value="100" KeyTime="30%" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="80%" />
                          <LinearDoubleKeyFrame Value="500" KeyTime="90%" />
                          <LinearDoubleKeyFrame Value="600" KeyTime="100%" />
                        </DoubleAnimationUsingKeyFrames>
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger>
                </Rectangle.Triggers>
              </Rectangle>
              

              Uniform

              當您Uniform希望每個關鍵幀花費相同的時間時,請使用計時。
              Uniform關鍵時間將可用時間平均除以關鍵幀數,以確定每個關鍵幀的結束時間。 下面的示例顯示持續時間為 10 秒的動畫和四個關鍵幀,其關鍵時間指定為Uniform。

              • 在前 2.5 秒鐘內,第一個關鍵幀在基值和 100 之間進行動畫處理,結束時間 = 0:0:2.5。
              • 第二個關鍵幀在 100 和 200 之間進行動畫處理。 它在第一個關鍵幀結束後開始(開始時間 = 2.5 秒),播放大約 2.5 秒鐘,結束時間 = 0:0:5。
              • 第三個關鍵幀在 200 和 500 之間進行動畫處理。 它在第二個關鍵幀結束時開始(開始時間 = 5 秒),播放 2.5 秒鐘,結束時間 = 0:0:7.5。
              • 第四個關鍵幀在 500 和 600 之間進行動畫處理。 它在第二個關鍵幀結束時開始(開始時間 = 7.5 秒),播放 2.5 秒鐘,結束時間 = 0:0:1。
                    <Rectangle Height="50" Width="50" Fill="Red">
                <Rectangle.RenderTransform>
                  <TranslateTransform x:Name="TranslateTransform03" X="10" Y="190" />
                </Rectangle.RenderTransform>
                <Rectangle.Triggers>
                  <EventTrigger RoutedEvent="Rectangle.Loaded">
                    <BeginStoryboard>
                      <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                          Storyboard.TargetName="TranslateTransform03" 
                          Storyboard.TargetProperty="X"
                          Duration="0:0:10"
                          RepeatBehavior="Forever">
              
                          <!-- KeyTime properties are expressed with values of Uniform. 
                               When a key time is set to "Uniform" the total allotted 
                               time of the animation is divided evenly between key frames.  
                               In this example,the total duration of the animation is 
                               ten seconds and there are four key frames each of which 
                               are set to "Uniform",therefore,the duration of each key frame 
                               is 3.3 seconds (10/3). -->
                          <LinearDoubleKeyFrame Value="100" KeyTime="Uniform" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="Uniform" />
                          <LinearDoubleKeyFrame Value="500" KeyTime="Uniform" />
                          <LinearDoubleKeyFrame Value="600" KeyTime="Uniform" />
                        </DoubleAnimationUsingKeyFrames>
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger>
                </Rectangle.Triggers>
              </Rectangle>
              

              Paced

              如果要Paced以恆定速率進行動畫處理,請使用計時。
              Paced關鍵時間根據每個關鍵幀的長度分配可用時間,以確定每個幀的持續時間。 這樣,動畫的速度或速率將保持不變。 下面的示例顯示持續時間為 10 秒的動畫和三個關鍵幀,其關鍵時間指定為Paced。

                    <Rectangle Height="50" Width="50" Fill="Orange">
                <Rectangle.RenderTransform>
                  <TranslateTransform x:Name="TranslateTransform04" X="10" Y="270" />
                </Rectangle.RenderTransform>
                <Rectangle.Triggers>
                  <EventTrigger RoutedEvent="Rectangle.Loaded">
                    <BeginStoryboard>
                      <Storyboard>
                        <DoubleAnimationUsingKeyFrames 
                          Storyboard.TargetName="TranslateTransform04" 
                          Storyboard.TargetProperty="X"
                          Duration="0:0:10"
                          RepeatBehavior="Forever">
              
                          <!-- KeyTime properties are expressed witwww.cppcns.comh values of Paced. 
                               Paced values are used when a constant rate is desired. 
                               The time allocated to a key frame with a KeyTime of "Paced" 
                               is determined by the time allocated to the other key 
                               frames of the animation. This time is calculated to 
                               attempt to give a "paced" or "constant velocity" 
                               for the animation. -->
                          <LinearDoubleKeyFrame Value="100" KeyTime="Paced" />
                          <LinearDoubleKeyFrame Value="200" KeyTime="Paced" />
                          <LinearDoubleKeyFrame Value="500" KeyTime="Paced" />
                          <LinearDoubleKeyFrame Value="600" KeyTime="Paced" />
                        </DoubleAnimationUsingKeyFrames>
                      </Storyboard>
                    </BeginStoryboard>
                  </EventTrigger>
                </Rectangle.Triggers>
              </Rectangle>
              

              關鍵幀時間及順序

              可以在同一動畫中使用具有不同KeyTime值型別的關鍵幀。 儘管建議以關鍵幀的實際播放順序來新增關鍵幀,但此操作不是必需的。 動畫和計時系統能夠處理順序紊亂的關鍵幀。 將忽略關鍵時間無效的關鍵幀。
              下表描述了為關鍵幀動畫的關鍵幀解析關鍵時間的過程。

              • 1 解析TimeSpanKeyTime值。
              • 2 確定動畫的總內插時間,即關鍵幀動畫完成向前迭代所需的全部時間。
                如果動畫的Duration不是Automatic或Forever,則總插值時間是動畫Duration屬性的值。
                否則,總插值時間是其關鍵幀(TimeSpanKeyTime如果有)之間指定的最大值。
                否則,總內插時間為 1 秒。
              • 3 使用總插值時間值解析PercentKeyTime值。
              • 4 如果最後一個關鍵幀尚未在之前步驟中解析,則將解析該關鍵幀。 如果最後KeyTime一個關鍵幀為Uniform或Paced,則其解析時間將等於總插值時間。
                如果第KeyTime一個關鍵幀的,Paced並且此動畫比關鍵幀多,則將其KeyTime值解析為零;如果只有一個關鍵幀,並且其KeyTime值為Paced,則解析為總插值時間,如上一步所述。
              • 5 解析剩餘UniformKeyTime值:每個值都給定可用時間的相等份額。 在此過程中PacedKeyTime,未解析的值將暫時視為UniformKeyTime值,並獲得臨時解析的時間。
              • 6 使用宣告KeyTime的最接近具有已解析KeyTime值的關鍵幀,解決未指定金鑰時間的關鍵幀的值。
              • 7 解析剩餘PacedKeyTime值。 PacedKeyTime使用相鄰KeyTime關鍵幀的值來確定其解析時間。 目的是確保動畫速度在此關鍵幀的解析時間內保持固定不變。
              • 8 按解析時間(主鍵)和宣告順序(輔助鍵)對關鍵幀進行排序,即根據已解決的關鍵幀KeyTime值使用穩定排序。

              到此這篇關於WPF關鍵幀動畫介紹與實現的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援我們。