WPF 实现一个吃豆豆的Loading加载动画

运行的效果如下

先引入一下我们需要的库

在nuget上面搜一下"expression.Drawing",安装一下这个包

我们再创建一个Window,引入一下这个包的命名空间

我们设置一下这个加载动画呈现的窗体的样式

复制代码
        xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
        mc:Ignorable="d"
        WindowStyle="None"
        ResizeMode="NoResize"
        Background="#4C858585"
        WindowStartupLocation="CenterScreen"
        AllowsTransparency="True"
        Loaded="Window_Loaded"
        Title="Window1" Height="400" Width="400"

然后我们要用到我们添加的库里面的一个圆弧控件

复制代码
        <ed:Arc x:Name="arc" Height="100" Width="100" StrokeThickness="50" Panel.ZIndex="1"
                StartAngle="-240" EndAngle="-300" Stretch="None"
                ArcThicknessUnit="Pixel">
            <ed:Arc.Stroke>
                <RadialGradientBrush GradientOrigin="0.3,0.3" RadiusX="0.7" RadiusY="0.7">
                    <GradientStop Color="#FFFFF00E" Offset="1"/>
                    <GradientStop Color="White" Offset="0"/>
                </RadialGradientBrush>
            </ed:Arc.Stroke>
        </ed:Arc>

背景色设置成一个圆形渐变的原因是为了让这个控件看起来像一个球体,而不是一个圆,得到的效果如下:

再到下面放几个圆球

复制代码
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Margin="200,0,0,0">
    <StackPanel x:Name="stackPanel" Orientation="Horizontal" RenderTransformOrigin="0.5,0.5">
    <!--这里是为了后面的动画用,因为我是用blend添加的动画,所以生成的代码如下-->
        <StackPanel.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform/>
            </TransformGroup>
        </StackPanel.RenderTransform>
        <Ellipse/>
        <Ellipse Margin="20,0"/>
        <Ellipse />
        <Ellipse Margin="20,0"/>
        <Ellipse />
        <Ellipse Margin="20,0"/>
    </StackPanel>
</StackPanel>

资源里面添加一下这些球的大小和颜色

复制代码
        <Style TargetType="{x:Type Ellipse}">
            <Setter Property="Height" Value="20"/>
            <Setter Property="Width" Value="20"/>
            <Setter Property="Fill" Value="#FFFF5800"/>
        </Style>

就会得到下面这个样子

我们再添加一下动画,让这两部分动起来

复制代码
        <Storyboard x:Key="Storyboard1" RepeatBehavior="Forever" AutoReverse="True">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="arc" Storyboard.TargetProperty="(ed:Arc.EndAngle)">
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="-300"/>
                <EasingDoubleKeyFrame KeyTime="00:00:0.25" Value="-271"/>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="arc" Storyboard.TargetProperty="(ed:Arc.StartAngle)">
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="-240"/>
                <EasingDoubleKeyFrame KeyTime="00:00:0.25" Value="-270"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="Storyboard2" RepeatBehavior="Forever">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="stackPanel" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="00:00:01" Value="-78"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>

还需要把这个动画也动起来,在window的loaded事件里面添加下面的代码

复制代码
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            var b = FindResource("Storyboard1") as Storyboard;
            b.Begin();

            var c = FindResource("Storyboard2") as Storyboard;
            c.Begin();
        }

这个时候运行这个窗体,就会发现已经实现了吃豆豆的效果,但是因为动画是一直在循环,小豆子一直往左边移动的时候,移动到一个位置就不会移动了,动画在重置的时候会让

动画看起来有一个延迟感,我们可以给这豆子的父级添加一个clip,让动画视觉上看起来是连续的(这里可以对比一下添加clip和不添加的效果的区别)

复制代码
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Margin="200,0,0,0">
    <StackPanel.Clip>
        <RectangleGeometry>
            <RectangleGeometry.Rect>
                <Rect X="0" Y="0" Width="150" Height="40"/>
            </RectangleGeometry.Rect>
        </RectangleGeometry>
    </StackPanel.Clip>
    <StackPanel x:Name="stackPanel" Orientation="Horizontal" RenderTransformOrigin="0.5,0.5">
        <!--这里是为了后面的动画用,因为我是用blend添加的动画,所以生成的代码如下-->
        <StackPanel.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform/>
            </TransformGroup>
        </StackPanel.RenderTransform>
        <Ellipse/>
        <Ellipse Margin="20,0"/>
        <Ellipse />
        <Ellipse Margin="20,0"/>
        <Ellipse />
        <Ellipse Margin="20,0"/>
    </StackPanel>
</StackPanel>

然后就是怎么把这个效果运用到我们的项目中

我们再添加一个window2,在里面添加一个button

button的click事件代码如下

我们运行window2,点击一下按钮,就会发现3秒钟以后,吃豆豆的动画就消失了,也就是数据加载完成,吃豆豆就不显示了

如果项目里面有很多的地方都要用到这个动画,我们可以添加一个类来专门做这个动画的事情

代码里面的Action就是我们需要耗时的一些操作

所以我们的button的click里面的代码就变成了下面这段代码

好了,到这里这个动画的实现就结束了

项目github地址:bearhanQ/WPFFramework: Share some experience (github.com)

QQ技术交流群:332035933;

相关推荐
做个文艺程序员1 天前
MQ第12篇:AI原生消息架构演进:从MQ到事件驱动的全链路设计
架构·消息队列·wpf·事件驱动架构·ai-native·cqrs
donk13143 天前
React Native for OpenHarmony 实战:三方库 react-native-circular-action-menu 的鸿蒙化适配指南
javascript·分布式·react native·react.js·wpf·harmonyos
donk13144 天前
React Native for OpenHarmony 实战:三方库 react-native-step-indicator 的鸿蒙化适配指南
分布式·react native·react.js·wpf·harmonyos
He BianGu4 天前
【笔记】WPF中RenderOptions类的详细功能
笔记·wpf
VidDown4 天前
上线三个月后的第一次事故:一个 Django 服务的日志、监控与故障复盘
数据库·python·django·wpf·音视频·视频编解码
He BianGu4 天前
【笔记】WPF中CachingHint的功能
笔记·wpf
He BianGu4 天前
【笔记】在WPF中BitmapScalingMode的作用
笔记·wpf
Vae_Mars5 天前
幂等性学习笔记
笔记·学习·wpf
samble6 天前
从零搭建灌装监控系统(十九):单元测试实战,xUnit + 内存SQLite + 反射测试私有方法
c#·wpf·mvvm·modbus·工业控制
光泽雨7 天前
路由概念和路由事件 继承链路 RadioButton的事件解析
wpf