Windows Phone開(kāi)發(fā)(42):緩動(dòng)動(dòng)畫(huà)
前面在討論關(guān)鍵幀動(dòng)畫(huà)的時(shí)候,我有意把幾個(gè)帶緩動(dòng)動(dòng)畫(huà)的關(guān)鍵幀動(dòng)畫(huà)忽略掉,如EasingColorKeyFrame、 EasingDoubleKeyFrame和EasingPointKeyFrame,其實(shí)為數(shù)不多,就這么幾個(gè)。因?yàn)槲蚁=y(tǒng)一放到這節(jié)課程來(lái)吹一下緩動(dòng) 函數(shù)。
所謂緩動(dòng)函數(shù),就是我們?cè)诖鷶?shù)里面說(shuō)的函數(shù),說(shuō)白了嘛,就是根特定的函數(shù)規(guī)則,用輸入的值算出最終值,使得動(dòng)畫(huà)在兩個(gè)關(guān)鍵幀之間不再是均衡過(guò)度,而是帶有加/減速或其他效果,當(dāng)然,還要取決于算法。
比如函數(shù)
所以,我們看出來(lái)了,緩動(dòng)函數(shù)涉及復(fù)雜的數(shù)學(xué)運(yùn)算,不過(guò),灰常幸運(yùn)的是,常用的緩函數(shù)MS已經(jīng)為我們封裝好了,這也是從 WPF/Silverlight中遷移到WP的,集成性兼容性MD的好,所以,在使用的時(shí)候,大家可以輕松一大把了,因此,當(dāng)你在練習(xí)的時(shí)候,記得沖一杯 咖啡放在桌上,一邊寫(xiě)代碼一邊品嘗吧。呵呵,編程快樂(lè),快樂(lè)編程。
如果你干過(guò)WPF或SL,這些東西你會(huì)覺(jué)得灰常Easy,我不是第一次強(qiáng)調(diào)了,所以說(shuō),基礎(chǔ)很重要,把基礎(chǔ)扎實(shí)了,無(wú)論你學(xué)習(xí)什么新玩意兒,都可以一通百通的,不管你信不信,反正我信了。
如何你對(duì)緩動(dòng)函數(shù)沒(méi)有一個(gè)直觀的認(rèn)識(shí)也不要緊,下面推薦大家一個(gè)游戲,很好玩的,不玩你學(xué)WP會(huì)后悔的。游戲地址:http://samples.msdn.microsoft.com/Silverlight/silverlight_next/Animations/easing_functions_gallery/testpage.html
記住要認(rèn)真玩,這樣你才會(huì)熟悉緩動(dòng)函數(shù)與相關(guān)的類(lèi)。
某致理名言說(shuō)得好,“自己動(dòng)手,豐衣足食”,還是老規(guī)矩,實(shí)例決定一切,動(dòng)手干活吧。
演練一:
請(qǐng)參考以下XAML代碼構(gòu)建你的UI。
- <Grid Loaded="gridLoaded">
- <Ellipse HorizontalAlignment="Left"
- VerticalAlignment="Top"
- Fill="Orange"
- Width="100"
- Height="100"
- x:Name="elp">
- <Ellipse.RenderTransform>
- <TranslateTransform x:Name="trm"/>
- </Ellipse.RenderTransform>
- </Ellipse>
- <Grid.Resources>
- <Storyboard x:Name="std">
- <DoubleAnimationUsingKeyFrames Duration="0:0:8"
- Storyboard.TargetName="trm"
- Storyboard.TargetProperty="Y"
- RepeatBehavior="30">
- <LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
- <EasingDoubleKeyFrame KeyTime="0:0:8" Value="485">
- <EasingDoubleKeyFrame.EasingFunction>
- <BounceEase Bounciness="3" Bounces="3"/>
- </EasingDoubleKeyFrame.EasingFunction>
- </EasingDoubleKeyFrame>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </Grid.Resources>
- </Grid>
后臺(tái)C#代碼啟用動(dòng)畫(huà)。
- private void gridLoaded(object sender, RoutedEventArgs e)
- {
- this.std.Begin();
- }
現(xiàn)在,運(yùn)行上面的示例,你會(huì)發(fā)現(xiàn)圓在下落的過(guò)程發(fā)生了兩次回彈,動(dòng)畫(huà)才結(jié)束,而且一開(kāi)始較慢,后來(lái)漸漸加速,這就是緩動(dòng)函數(shù)所產(chǎn)生的效果。
演練二:
參考以下XAML代碼創(chuàng)建UI界面。
- <Grid Loaded="gridLoaded">
- <Rectangle Margin="35" x:Name="rec">
- <Rectangle.Fill>
- <LinearGradientBrush x:Name="brs" StartPoint="0,0.5" EndPoint="1,0.5">
- <GradientStop Color="Blue" Offset="0"/>
- <GradientStop Color="Yellow" Offset="0.5"/>
- <GradientStop Color="Blue" Offset="1"/>
- </LinearGradientBrush>
- </Rectangle.Fill>
- </Rectangle>
- <Grid.Resources>
- <Storyboard x:Name="std">
- <DoubleAnimationUsingKeyFrames Duration="0:0:10"
- Storyboard.TargetName="brs"
- Storyboard.TargetProperty="(LinearGradientBrush.GradientStops)[1].(GradientStop.Offset)"
- RepeatBehavior="35"
- AutoReverse="True">
- <EasingDoubleKeyFrame KeyTime="0:0:0" Value="0.2"/>
- <EasingDoubleKeyFrame KeyTime="0:0:10" Value="0.8">
- <EasingDoubleKeyFrame.EasingFunction>
- <ElasticEase Oscillations="4" Springiness="1"/>
- </EasingDoubleKeyFrame.EasingFunction>
- </EasingDoubleKeyFrame>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </Grid.Resources>
- </Grid>
在gridLoaded上右擊,從彈出的菜單中選擇“導(dǎo)航到事件處理程序”,在生成的方法中完成以下C#代碼。
- private void gridLoaded(object sender, RoutedEventArgs e)
- {
- std.Begin();
- }
運(yùn)行程序后,你會(huì)看到漸變填充中間黃色的色塊在左右來(lái)回移動(dòng)。
演練三:
請(qǐng)參照以下XAML建立UI。
- <phone:PhoneApplicationPage
- x:Class="Sample.Page3"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
- xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- FontFamily="{StaticResource PhoneFontFamilyNormal}"
- FontSize="{StaticResource PhoneFontSizeNormal}"
- Foreground="{StaticResource PhoneForegroundBrush}"
- SupportedOrientations="Portrait" Orientation="Portrait"
- mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
- shell:SystemTray.IsVisible="True">
- <!--LayoutRoot 是包含所有頁(yè)面內(nèi)容的根網(wǎng)格-->
- <Grid x:Name="LayoutRoot" Background="Transparent">
- <Grid.RowDefinitions>
- <RowDefinition Height="Auto"/>
- <RowDefinition Height="*"/>
- </Grid.RowDefinitions>
- <!--TitlePanel 包含應(yīng)用程序的名稱(chēng)和頁(yè)標(biāo)題-->
- <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
- <TextBlock x:Name="ApplicationTitle" Text="我的應(yīng)用程序" Style="{StaticResource PhoneTextNormalStyle}"/>
- <TextBlock x:Name="PageTitle" Text="頁(yè)面名稱(chēng)" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
- </StackPanel>
- <!--ContentPanel - 在此處放置其他內(nèi)容-->
- <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
- <Rectangle HorizontalAlignment="Left" VerticalAlignment="Bottom"
- Width="60" Height="45" Fill="White"
- MouseLeftButtonDown="onShow"/>
- <TextBlock HorizontalAlignment="Center"
- VerticalAlignment="Center"
- Text="請(qǐng)點(diǎn)擊左下角的白色矩形。"
- TextWrapping="Wrap"
- Margin="30,0,40,0"
- FontSize="45"/>
- <StackPanel x:Name="sp" Background="LightBlue"
- Height="180"
- VerticalAlignment="Bottom">
- <TextBlock Foreground="Red"
- Margin="20,22,20,20"
- FontSize="32"
- Text="你好,點(diǎn)擊下面的按鈕吧。"/>
- <Button Content="確 定" Background="Blue"
- Click="onHide"/>
- <StackPanel.RenderTransform>
- <TranslateTransform x:Name="trm"
- Y="180"/>
- </StackPanel.RenderTransform>
- </StackPanel>
- <Grid.Resources>
- <Storyboard x:Name="stdShow">
- <DoubleAnimationUsingKeyFrames
- Storyboard.TargetName="trm"
- Storyboard.TargetProperty="Y"
- Duration="1">
- <EasingDoubleKeyFrame
- KeyTime="0:0:0" Value="180"/>
- <EasingDoubleKeyFrame
- KeyTime="0:0:1" Value="0">
- <EasingDoubleKeyFrame.EasingFunction>
- <PowerEase Power="10"/>
- </EasingDoubleKeyFrame.EasingFunction>
- </EasingDoubleKeyFrame>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- <Storyboard x:Name="stdHide">
- <DoubleAnimationUsingKeyFrames
- Duration="0:0:1"
- Storyboard.TargetName="trm"
- Storyboard.TargetProperty="Y">
- <EasingDoubleKeyFrame KeyTime="0:0:0"
- Value="0"/>
- <EasingDoubleKeyFrame KeyTime="0:0:1"
- Value="180">
- <EasingDoubleKeyFrame.EasingFunction>
- <PowerEase Power="10"/>
- </EasingDoubleKeyFrame.EasingFunction>
- </EasingDoubleKeyFrame>
- </DoubleAnimationUsingKeyFrames>
- </Storyboard>
- </Grid.Resources>
- </Grid>
- </Grid>
- </phone:PhoneApplicationPage>
分別在onShow和onHide方法上右擊,從彈出的菜單中選擇“導(dǎo)航到事件處理程序”,完成后臺(tái)代碼邏輯。
- private void onShow(object sender, MouseButtonEventArgs e)
- {
- if (stdHide.GetCurrentState() != ClockState.Stopped)
- {
- stdHide.Stop();
- }
- stdShow.Begin();
- }
- private void onHide(object sender, RoutedEventArgs e)
- {
- if (stdShow.GetCurrentState() != ClockState.Stopped)
- {
- stdShow.Stop();
- }
- stdHide.Begin();
- }
現(xiàn)在,運(yùn)行程序,單擊屏幕左下方的白色矩形,這時(shí)候屏幕下方會(huì)彈出一個(gè)面板,再點(diǎn)擊面板上的按鈕,面板會(huì)縮下去。
這樣,使用動(dòng)畫(huà),我們就做出了一個(gè)類(lèi)似工具條的效果。