存在問題:html
最近接手公司一個比較成熟的產品項目開發(WPF桌面端),其中,在登錄系統加載時,60張圖片切換,實現loading閃爍加載,快有密集恐懼症了!!!express
代碼以下:app
private void LoadPics() { try { _storyboard = new Storyboard(); for (int i = 0; i < 60; i++) { ObjectAnimationUsingKeyFrames oauf = new ObjectAnimationUsingKeyFrames(); //ObjectAnimationUsingKeyFrames 能夠對指定 Duration 內的一組 KeyFrames 中的 Object 屬性值進行動畫處理 BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.UriSource = new Uri("pack://application:,,,/jg.CloudCube.WPF;component/Resources/LoadingAnimation/loading" + (i + 1) + ".png"); bitmap.CacheOption = BitmapCacheOption.Default; bitmap.EndInit(); ImageBrush imgBrush = new ImageBrush(bitmap); //讀取圖片文件 DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame(); //DiscreteObjectKeyFrame 經過使用離散內插,能夠在前一個關鍵幀的 Object 值及其本身的 Value 之間進行動畫處理。 dokf.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(i * 30)); //KeyTime 獲取或設置應到達關鍵幀的目標 Value 的時間 //這裏每隔40毫秒設置一張圖片,也就是每秒1000/40=25幀 dokf.Value = imgBrush; oauf.KeyFrames.Add(dokf); Storyboard.SetTargetProperty(oauf, new PropertyPath("(Rectangle.Fill)")); //把動畫應用到窗體的Rectangle中 Storyboard.SetTarget(oauf, RectDis); //RectDis是Rectangle的名稱 _storyboard.Children.Add(oauf); //把ObjectAnimationUsingKeyFrames動畫添加到Storyboard中 } _storyboard.RepeatBehavior = RepeatBehavior.Forever; } catch (Exception ex) { var log = log4net.LogManager.GetLogger("Error"); log.Error(ex.Message, ex); } }
60張圖:ide
這樣的實現效果,實在對不住 WPF對動畫那麼好的支持。動畫
解決方式:spa
下面使用WPF(Storyboard)只在xaml中,實現Loading加載閃爍動畫。3d
代碼以下:code
<Window x:Class="TestWpf.Window4" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Window4" Height="300" Width="300"> <Window.Resources> <Style x:Key="FlashStyle" TargetType="{x:Type FrameworkElement}"> <Style.Triggers> <EventTrigger RoutedEvent="Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetProperty="(FrameworkElement.Opacity)" BeginTime="00:00:00" From="1" To="0" Duration="00:00:01.5" AutoReverse="True" RepeatBehavior="Forever"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Style.Triggers> </Style> <Storyboard x:Key="StoryLeftToRight" RepeatBehavior="Forever" Duration="00:00:01.5"> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="e1" Storyboard.TargetProperty="(FrameworkElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="e2" Storyboard.TargetProperty="(FrameworkElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="e3" Storyboard.TargetProperty="(FrameworkElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.0" Value="1" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5" Value="0" /> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="e4" Storyboard.TargetProperty="(FrameworkElement.Opacity)"> <SplineDoubleKeyFrame KeyTime="00:00:00.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:00.5" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.0" Value="0" /> <SplineDoubleKeyFrame KeyTime="00:00:01.5" Value="1" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </Window.Resources> <Grid Background="DeepSkyBlue"> <StackPanel Orientation="Horizontal" Margin="20" VerticalAlignment="Bottom" HorizontalAlignment="Right"> <TextBlock Text="Loading " Style="{StaticResource FlashStyle}" Foreground="White" FontSize="20"/> <StackPanel Orientation="Horizontal"> <StackPanel.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource StoryLeftToRight}" /> </EventTrigger> </StackPanel.Triggers> <Ellipse Name="e1" Width="5" Height="5" Margin="5,0,0,0" HorizontalAlignment="Left" Fill="White" /> <Ellipse Name="e2" Width="5" Height="5" Margin="5,0,0,0" HorizontalAlignment="Left" Fill="White" /> <Ellipse Name="e3" Width="5" Height="5" Margin="5,0,0,0" HorizontalAlignment="Left" Fill="White" /> <Ellipse Name="e4" Width="5" Height="5" Margin="5,0,0,0" HorizontalAlignment="Left" Fill="White" /> </StackPanel> </StackPanel> </Grid> </Window>
實現效果:component
技術要點:orm
DoubleAnimation屬性介紹:
Storyboard.TargetName:附加屬性操做到指定的對象上;
Storyboard.TargetProperty:要操做指定對象的屬性;
From..To :上述屬性值的起始範圍;
Duration: 在多少時間內完成上述屬性值的變化;
RepeatBehavior:反覆次數;
AutoReverse:完成向迭代後是否按相反的順序播放
System.Windows.Media.Animation提供三種動畫類線性插值動畫類(17個)、關鍵幀動畫(22個)、路徑動畫(3個).
參考: http://www.cnblogs.com/libaoheng/archive/2012/04/23/2466242.html