儘管前面介紹的幾種動畫會讓覺得很好玩了,但是,不知道你是否發現,在前面說到的一系列XXXAnimation中,都有一個共同點,那就是僅僅針對兩個值的目標值之間產生動畫,如果使用By,將在原值和加上By後的目標值之間進行動畫處理;如果使用From,To,那就更好理解了,就是首尾兩個值之間值的動畫。
那麼,如果我希望三個值呢?或者N多個值呢?每個值之間的時間間隔不一樣呢?如果我還希望更複雜的動畫效果呢?比如可以附加easing 函式的。顯然,前面我們提到的幾個動畫類是不能完成的。
不知道你以前有沒有耍過Flash,若是在Flash裡面,你會怎麼做?對啊,我肯定會說——主要畫面格啊。是啊,那麼,Silverlight for Windows phone裡面有沒有主要畫面格動畫呢?答案顯然是Yes的。
相對於前面說的簡單動畫而言,主要畫面格動畫會顯得更為複雜,更難理解,我問你,你怕了嗎?
如果你怕了,那就不要往下看了,你只能中途而廢了,回家被母親罵了。如果你敢於挑戰,那就不要猶豫,迎難而上!
先向大家透露一個好訊息,其實在實際開發中,你不一定要手寫XAML的,還記得那個人類曆史上從未有過的強大設計工具——Express Blend吧,嗯,對D,必要的時候,你可以拿出來用一下,不要用這麼好的東東在硬碟裡生鏽,會汙染環境的哦。用那傢伙,做動畫就方便了,你會懷疑你在用Flash,說不定比Flash還爽。
如果你問我當初是怎麼學習主要畫面格動畫的,我只能通俗地回答你:唯Coding爾。至於你信不信,反正你想成為高手,你必須相信這句話。
扯蛋的話就不聊了,首先我們要先摸清一下與主要畫面格有關的一些類的大概線路。
從前面的課程中,大家一定知道,一個Storyboard裡面可以放N個Timeline對象,但你知道,Timeline是抽象類別,說白了,就是可以在其中放置從Timeline派生的類的對象,Storyboard除外,這個可不能嵌套。
也就是說,Storyboard裡央也可以放N個主要畫面格時間軸,和簡單動畫一個樣,主要畫面格動畫無非也是針對Double,Color,Point等目標值的。很好找,只要你看到有XXXAnimationUsingKeyFrames字樣的,都是主要畫面格動畫的時間軸,為什麼後面有個s,呵,複數形式,小學英語了,不用我解釋了,既然是複數,當然一個時間軸中可以有N個主要畫面格了。
現在,你一定是雲裡霧裡的,所以說嘛,理論的東西講得再多也是廢話,還是執行個體可愛一點吧?
這一節先來講一下DoubleAnimationUsingKeyFrames,裡面的主要畫面格有三種:LinearDoubleKeyFrame、SplineDoubleKeyFrame和EasingDoubleKeyFrame,我們只玩前面兩個,後面那個是帶easing 函式的動畫,由於緩動動畫的原理都一樣,可以舉一反六,所以我打算放到專門的一節中去吹。
LinearDoubleKeyFrame是比較好懂的,其實它和DoubleAnimation很像,只是主要畫面格的特點就是一個時間點對應一個值,因此,記住這句話:任何主要畫面格都有KeyTime和Value一一對應的,一個時間點對應一個值。
而線性主要畫面格動畫的特點就是“勻速直線運動”,複習一下初中物理知識。兩個關鍵之間的兩個值都是根據時間間隔的大小均勻計算的。
另外,再看一下SplineDoubleKeyFrame,這個東西比較難理解,其實,你不理解它也可以用的,真的,這世界上有些東西不一定非要你弄懂了才能用的,比如,你不太可能在吃藥之前要研究一下藥是怎麼加工出來的再吃,你吃飯之前難道也要想明白大米是如何種出來才吃嗎?顯然不是的。
SplineDoubleKeyFrame被SDK文檔翻譯為曲線插補,這更增加了神奇感。我在學習的時候,凡是遇到這種根本讀不懂的東西的話,我第一時間就寫代碼來試,寫不同的代碼,從不同的角度去測試,玩多了,你的靈感就來了。
這個什麼插入補間動畫,說通俗一點,不就是“變速直線運動”了,你看,又複習中考物理了,唉,當年我差點考滿分,就是被加速度這玩兒耍了。
其中關鍵的是有個KeySpline屬性,它設定一個KeySpline對象,KeySpline類有兩個屬性:ControlPoint1和ControlPoint2,就是兩個點,傳說是貝茲路徑的兩個控制點。
真的複雜了,如果你覺得真的難理解的話,有沒有興趣玩一下這個遊戲?玩了之後,你一定對這個東東有更深的體會,遊戲地址:http://samples.msdn.microsoft.com/Silverlight/SampleBrowser/index.htm#/?sref=KeySplineExample
這個遊戲很好玩的,一定要認真玩啊。
下面,我們動手幹活,先來一段美麗的XAML代碼。+
<Grid Loaded="OnGridLoaded"> <Ellipse VerticalAlignment="Top" HorizontalAlignment="Left" Width="100" Height="100" Fill="Blue"> <Ellipse.RenderTransform> <TranslateTransform x:Name="trf"/> </Ellipse.RenderTransform> </Ellipse> <Grid.Resources> <Storyboard x:Name="storybrd"> <DoubleAnimationUsingKeyFrames Duration="0:0:6" RepeatBehavior="Forever" Storyboard.TargetName="trf" Storyboard.TargetProperty="X"> <LinearDoubleKeyFrame KeyTime="0:0:6" Value="420"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Duration="0:0:6" RepeatBehavior="Forever" Storyboard.TargetName="trf" Storyboard.TargetProperty="Y"> <SplineDoubleKeyFrame KeyTime="0:0:2" Value="700"> <SplineDoubleKeyFrame.KeySpline> <KeySpline ControlPoint1="0,0" ControlPoint2="0,1"/> </SplineDoubleKeyFrame.KeySpline> </SplineDoubleKeyFrame> <SplineDoubleKeyFrame KeyTime="0:0:3" Value="550"> <SplineDoubleKeyFrame.KeySpline> <KeySpline ControlPoint1="1,0" ControlPoint2="0.5,0"/> </SplineDoubleKeyFrame.KeySpline> </SplineDoubleKeyFrame> <SplineDoubleKeyFrame KeyTime="0:0:5" Value="95"> <SplineDoubleKeyFrame.KeySpline> <KeySpline ControlPoint1="0,0" ControlPoint2="0,0.5"/> </SplineDoubleKeyFrame.KeySpline> </SplineDoubleKeyFrame> <LinearDoubleKeyFrame KeyTime="0:0:6" Value="730"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Grid.Resources> </Grid>
代碼就這樣的,看不懂後果自負,第一節中就說過了,先把WPF和Silverlight耍了,再來耍WP。
後台代碼還要加一個,處理上面的OnGridLoaded事件。
private void OnGridLoaded(object sender, RoutedEventArgs e) { this.storybrd.Begin(); }
由於是動畫,沒有意義,就不發了,自己運行一下吧。你的作品,你一定很高興!
曆史證明,一個例子是不夠的,下面再來一“瓶”,這個例子我們對一個Image控制項玩動畫,讓圖片動著出來,動著滾蛋,主要用到透視變換。
<Grid Loaded="OnGridLoaded"> <Image Name="img" Source="/PhoneApp1;component/1.jpg" Stretch="Uniform" Opacity="0"> <Image.Projection> <PlaneProjection x:Name="prj" /> </Image.Projection> </Image> <Grid.Resources> <Storyboard x:Name="std" RepeatBehavior="Forever" Duration="0:0:12"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="img" Storyboard.TargetProperty="Opacity"> <LinearDoubleKeyFrame KeyTime="0:0:3" Value="1"/> <LinearDoubleKeyFrame KeyTime="0:0:8" Value="1"/> <LinearDoubleKeyFrame KeyTime="0:0:12" Value="0"/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="prj" Storyboard.TargetProperty="LocalOffsetZ"> <LinearDoubleKeyFrame KeyTime="0:0:0" Value="-6000"/> <LinearDoubleKeyFrame KeyTime="0:0:8" Value="0" /> <LinearDoubleKeyFrame KeyTime="0:0:12" Value='-12'/> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="prj" Storyboard.TargetProperty="RotationZ"> <SplineDoubleKeyFrame KeyTime="0:0:0" Value="360"/> <SplineDoubleKeyFrame KeyTime="0:0:8" Value="0"> <SplineDoubleKeyFrame.KeySpline> <KeySpline ControlPoint1="0,0" ControlPoint2="0.25,0.5"/> </SplineDoubleKeyFrame.KeySpline> </SplineDoubleKeyFrame> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="prj" Storyboard.TargetProperty="RotationY"> <LinearDoubleKeyFrame KeyTime="0:0:8" Value="0"/> <LinearDoubleKeyFrame KeyTime="0:0:12" Value="90"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </Grid.Resources> </Grid>
別忘了處理OnGridLoaded。
private void OnGridLoaded(object sender, RoutedEventArgs e) { this.std.Begin(); }
這個嘛,還是發個圖好點,免得有人說沒真相,圖片大家可以隨便找,只要內容健康就行了。
還要告訴各位一件事,免得大家去“狗狗擺渡”,與動畫相關的類,基本上都位於System.Windows.Media.Animation命名空間。
至於源碼問題,大部分文章我會保留源碼,我這個人比較落後,沒有用網盤,所以,暫時這樣吧,有需要源碼的朋友,請留下你那個心愛的伊妹兒做人質吧,我會善待她的,放心。