WPF动画 - Loading加载动画

Posted 狂想NICE

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF动画 - Loading加载动画相关的知识,希望对你有一定的参考价值。

存在问题:

最近接手公司一个比较成熟的产品项目开发(WPF桌面端),其中,在登陆系统加载时,60张图片切换,实现loading闪烁加载,快有密集恐惧症了!!!

   代码如下:

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);
            }
        }
View Code

     60张图:

这样的实现效果,实在对不住 WPF对动画那么好的支持。

解决方式:

下面使用WPF(Storyboard)只在xaml中,实现Loading加载闪烁动画。

  代码如下:

<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>
View Code

  实现效果:

 

   技术要点:

      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

    

 

以上是关于WPF动画 - Loading加载动画的主要内容,如果未能解决你的问题,请参考以下文章

WPF和Expression Blend开发实例:Loading动画

2021-09-25 WPF上位机 43-Loading动画

在页面未加载完之前显示loading动画

在页面未加载完之前显示loading动画

react-native 加载动画 loading效果

react-native 加载动画 loading效果