故事板(StoryBoards)和动画(Animations)
Silverlight & Blend動畫設計系列五:故事板(StoryBoards)和動畫(Animations)
正如你所看到的,Blend是一個非常強大的節約時間的設計工具,在Blend下能夠設計出很多滿意的動畫作品,或許他具體是怎么實現的,通過什么方式實現的我們還是一無所知。本篇將續前面幾篇基礎動畫之上,詳細介紹Silverlight里提供故事板(StoryBorards)的屬性和各種不同類型的動畫(Animations)的詳細知識點,揭曉在Blend下設計動畫的內幕故事。
?
一、故事板(StoryBoard)屬性
Silvelight中的故事板(StoryBoard)提供了管理時間線的功能接口,可以用來控制一個或多個Silverlight動畫進程,故我也稱其為動畫時間線容器。如下XAML代碼塊演示了通過StoryBoard來管理了名為GreenBall的元素在X坐標方向上的偏移變換動畫。
<Storyboard?x:Name="MoveBall"> ?? ?? <DoubleAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="GreenBall"? ???????? ? Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"> ???????? <EasingDoubleKeyFrame?KeyTime="00:00:02"?Value="540"/> ???? </DoubleAnimationUsingKeyFrames>< /Storyboard>?
? StoryBoard提供了六個常用的動畫屬性選項,它們分別是:AutoReverse,BeginTime,Duration,FillBehavior,RepeatBehavior,SpeedRatio。通過這六個屬性可以用來控制動畫的基本行為動作,比如想要實現動畫的緩沖時間,就需要用到Duration屬性;設置動畫的開始時間則用BeginTime;如果動畫執行完后根據執行路線反向執行到原始狀態則需要使用AutoReverse;如果需要設置動畫的運行速度則使用SpeedRatio就可以完成。以下代碼塊演示了AutoReverse屬性的使用,動畫運行完后將按著原來的運行路線進行反向運行。更多詳細可參考這篇博文介紹:《動畫基礎快速入門Animation》或者MSDN。
<Storyboard?x:Name="MoveBall"?AutoReverse="True"> ???? <DoubleAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="GreenBall"? ???????? Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"> ??????? ?<EasingDoubleKeyFrame?KeyTime="00:00:02"?Value="540"/> ???? </DoubleAnimationUsingKeyFrames></Storyboard>?
? Storyboard的屬性是可以組合應用的,如上代碼塊給動畫設置了AutoReverse屬性,使其在動畫執行完后通過原來的運行路徑進行回滾動畫,可以給該動畫時間線容器添加一個BeginTime屬性,使其在程序加載后5秒鐘才開始執行動畫,這樣就使用到了兩個屬性,如下代碼塊:
<Storyboard?x:Name="MoveBall"?AutoReverse="True"?BeginTime="00:00:05"> ????...... </Storyboard>?
二、動畫類型(Types of animation)
Silverlight中的動畫主要分From/To/By和關鍵幀動畫兩種類型。
?
From/To/By動畫也稱為線性插值動畫(Linear Interpolation),是Silverlight類型中最簡單的一種動畫,只需要設置開始(From)、結束(To)和動畫值(By)就可以完成動畫的創建,Silverlight 3中提供了三種基礎的From/To/By動畫類型:DoubleAnimation、ColorAnimation和PointAnimation.
關鍵幀動畫比From/To/By動畫更加強大,無需指定動畫的開始、結束以及動畫緩沖時間等相關參數,只需要關注關鍵幀和如何去控制動畫就行了。Silverlight 3中提供了四種基本的關鍵幀動畫:緩和(Easing)、線性(Linear)、樣條(Spline)和離散(discreet)。
?
DoubleAnimation的使用是非常簡單的,只需要搞清楚From/To/By三要素就基本掌握了該類型動畫的使用,下面是一個簡單的通過DoubleAnimation實現的圓形移動的示例。
<UserControl?x:Class="DoubleByAnimation.MainPage" ????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"? ????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"? ????Width="800"?Height="600"> ??? ?<UserControl.Resources> ???????? <Storyboard?x:Name="Storyboard1"> ???????????? <DoubleAnimation?Storyboard.TargetName="Ellipse"? ???????????????? Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"? ???????????????? From="0"???By="150"?Duration="00:00:01"/> ???????? </Storyboard> ???? </UserControl.Resources>????<Canvas?x:Name="LayoutRoot"?Background="White"?> ???????? <Ellipse?Height="200"?Width="200"?Fill="#FFFF0000"?Canvas.Top="181"?Canvas.Left="92"?RenderTransformOrigin="0.5,0.5"?x:Name="Ellipse"> ????????????<Ellipse.RenderTransform> ???????????????? <TransformGroup> ???????????????????? <ScaleTransform/> ???????????????????? <SkewTransform/> ???????????????????? <RotateTransform/> ???????????????????? <TranslateTransform/> ???????????????? </TransformGroup> ???????????? </Ellipse.RenderTransform> ???????? </Ellipse> ???? </Canvas> </UserControl>
??
下面通過一個稍復雜的示例來演示DoubleAnimation動畫的使用,如下動畫代碼塊實現了名稱為Slider對象的X坐標方向的移動動畫:
<Storyboard?x:Name="SlideOut"> ???? <DoubleAnimation?Storyboard.TargetName="Slider"? ???????? Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"? ??? ?Duration="00:00:00.50"?To="150"/> </Storyboard> <Storyboard?x:Name="SlideIn"> ??? ?<DoubleAnimation?Storyboard.TargetName="Slider"? ??????? ?Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"? ???? Duration="00:00:00.50"?To="0"/> </Storyboard>?
如上動畫定義代碼塊中定義了兩個動畫,一個實現將對象Slider向X坐標方向移動到150像素點的位置,第二個動畫實現將名為Silder的對象向X方向移動到0像素點的坐標位置,這樣其實就實現了一個呈現與不呈現的效果。這里我們發揮大腦的潛力想象一下,如果Slider是一個面板對象,通過鼠標指向和離開的事件使用上面兩個動畫進行控制其不就實現了面板的鼠標指向就顯示,離開就退回到原來的位置了?答案卻是如此,詳細見下代碼塊:
public?partial?class?MainPage?:?UserControl { ???? public?MainPage() ???? { ???????? InitializeComponent();???????? Slider.MouseEnter?+=?new?MouseEventHandler(Slider_MouseEnter); ???????? ? Slider.MouseLeave?+=?new?MouseEventHandler(Slider_MouseLeave); ???? }
????private?void?Slider_MouseLeave(object?sender,?MouseEventArgs?e) ???? { ???????? SlideIn.Begin(); ???? }
????private?void?Slider_MouseEnter(object?sender,?MouseEventArgs?e) ??? ?{ ???????? SlideOut.Begin(); ???? } }
?
?
? 通過上面的示例,是否覺得要在Silverlight中實現一個動畫是非常簡單的?上面的示例就是掩飾了如何使用From/To/By的DoubleAnimation實現了對象的移動動畫,同樣也可以使用關鍵幀動畫(DoubleUsingKeyframes)來實現這一功能。如下代碼片段演示了元素Silder向X坐標方向移動到150像素點。
Storyboard?MoveRight?=?new?Storyboard();DoubleAnimationUsingKeyFrames?Anim?=?new?DoubleAnimationUsingKeyFrames(); Storyboard.SetTargetName(Anim,?"Slider"); Anim.SetValue(Storyboard.TargetPropertyProperty,? ???? new?PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)")); Anim.BeginTime?=?new?TimeSpan(0,?0,?0); SplineDoubleKeyFrame?SKeyFrame?=?new?SplineDoubleKeyFrame(); SKeyFrame.KeyTime?=?KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5)); SKeyFrame.Value?=?150; Anim.KeyFrames.Add(SKeyFrame); MoveRight.Children.Add(Anim); ......
?
ColorAnimation類型動畫主要應用于顏色上的變換動畫效果,比如有一個圓,默認的填充顏色是紅色(Red),設計一個動畫通過2秒鐘的動畫換成將圓的填充顏色變換為藍色。
<Ellipse?Height="218"?Width="218"?Canvas.Left="294"?Canvas.Top="195"?Fill="#FFFF0000"?Cursor="Hand"?x:Name="RedEllipse"/>?
可以通過Blend的設計器來完成這樣的動畫的創建,在對象和時間軸面板里新建動畫容器時間線,然后選中RadEllipse圓形對象在0秒的時間線上填充其顏色為紅色,2秒的時間線上填充其顏色為藍色,詳細設計如下圖:
?
Blend最終生成的XAML代碼如下:
<Storyboard?x:Name="Storyboard1"> ???? ? <ColorAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="RedEllipse"? ???????? Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)"> ???????? ? <EasingColorKeyFrame?KeyTime="00:00:00"?Value="Red"/> ???????? ???? <EasingColorKeyFrame?KeyTime="00:00:02"?Value="Blue"/> ???? ??? </ColorAnimationUsingKeyFrames> </Storyboard>?
? 有Blend這樣強大的設計工具是很幸運的,對于設計人員來說要實現一些動畫需求直接通過界面設計就完成了。對于程序員來說就煩惱了,由于不熟悉設計工具,要實現某種動畫只能通過編寫程序代碼來完成,這將是一個很龐大的工程,比如說當鼠標指向一圓的時候其填充顏色慢慢的向藍色(Blue)漸變,鼠標離開的時候慢慢的恢復其默認顏色紅色。實現這動畫效果則需要寫上如下長篇的程序代碼:
private?Storyboard?TurnBlue?=?new?Storyboard(); private?Storyboard?TurnRed?=?new?Storyboard(); private?ColorAnimation?BlueColor?=?new?ColorAnimation(); private?ColorAnimation?RedColor?=?new?ColorAnimation();public?MainPage() { ???? InitializeComponent();
???? BlueColor.SetValue(Storyboard.TargetNameProperty,?"RedEllipse"); ??? ?BlueColor.SetValue(Storyboard.TargetPropertyProperty,?new?PropertyPath("(Shape.Fill).(SolidColorBrush.Color)")); ???? ??? BlueColor.To?=?Colors.Blue; ???? ??? TurnBlue.Children.Add(BlueColor); ???? ??? LayoutRoot.Resources.Add("TurnBlue",?TurnBlue);
????RedColor.SetValue(Storyboard.TargetNameProperty,?"RedEllipse"); ???? ??? RedColor.SetValue(Storyboard.TargetPropertyProperty,?new?PropertyPath("(Shape.Fill).(SolidColorBrush.Color)")) ????RedColor.To?=?Colors.Red; ????TurnRed.Children.Add(RedColor); ??? ????LayoutRoot.Resources.Add("TurnRed",?TurnRed);
????RedEllipse.MouseEnter?+=?(senderRed,?eRed)?=> ???????? ??? { ???????????? TurnRed.Begin(); ???????? }; ??? ?? ?RedEllipse.MouseLeave?+=?(senderBlue,?eBlue)?=> { ???????????? TurnBlue.Begin(); ???????? }; }
?
這樣的代碼實現其實就是用程序代碼創建了兩個動畫,一個由紅色變換到藍色,一個則由藍色變換到紅色,按照前面的方法直接在Blend中設計也是可以的。最終的運行效果如下圖:
?
PointAnimation類型動畫更好理解,也就是動畫效果是通過不同的坐標點來控制的。比如說浪濤的效果,下面就以浪濤為示例來演示PointAnimation類型動畫的使用。
代碼 <Storyboard?x:Name="Storyboard1"?RepeatBehavior="Forever"?FillBehavior="HoldEnd"> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point2)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="351.732116699219,36.4064197540283"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="415.732116699219,84.4064178466797"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point3)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="425.502014160156,32.8349914550781"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="489.502014160156,80.8349914550781"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point1)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="499.271911621094,29.2635669708252"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="563.271911621094,77.2635650634765"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point2)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="112.729011535644,80.834991455078"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="104.729011535645,32.8349914550781"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point3)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="185.502014160156,80.834991455078"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="177.502014160156,32.8349914550781"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(BezierSegment.Point1)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="258.275024414062,80.834991455078"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="250.275024414063,32.8349914550781"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point2)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="600.704162597656,72.7879943847655"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="608.704162597656,32.8349229097365"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(BezierSegment.Point3)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="665.502014160156,72.7879943847655"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="673.502014160156,32.8349229097365"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point1)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="730.299926757813,72.7879943847655"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="738.299926757813,32.8349229097365"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point2)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="801.502014160156,40.8349914550781"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="801.502014160156,56.8349229097366"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[3].(BezierSegment.Point3)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="801.502014160156,40.8349914550781"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="801.502014160156,56.8349229097366"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[4].(BezierSegment.Point1)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="801.502014160156,40.8349914550781"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="801.502014160156,56.8349229097366"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="1.50201416015619,32.834991455078"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="1.50201416015625,88.8349914550779"/> ????</PointAnimationUsingKeyFrames> ????<PointAnimationUsingKeyFrames?BeginTime="00:00:00"?Storyboard.TargetName="water"?Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point1)"> ????????<EasingPointKeyFrame?KeyTime="00:00:00"?Value="1.50201416015619,32.834991455078"/> ????????<EasingPointKeyFrame?KeyTime="00:00:03"?Value="1.50201416015625,88.8349914550779"/> ????</PointAnimationUsingKeyFrames></Storyboard>?
?
?
? 關于Silverlight中的動畫相關的理論概論暫時就介紹這些,希望上面的簡單介紹能幫助大家深入的理解和使用Blend進行各種不同的動畫功能設計。更多信息可查閱下面的推資源連接。
轉載于:https://www.cnblogs.com/xiaogui9527/p/3190643.html
總結
以上是生活随笔為你收集整理的故事板(StoryBoards)和动画(Animations)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络行为监控系统
- 下一篇: 计算机基础及Python简介