效果图:
还在羡慕metro的ProgressRing吗?
wpf 也可以拥有
首先说下思路,
一共6个点围绕一直圆转,所以需要使用rotation动画 并且一直转下去。
那么下面的问题就好解决了。
首先是xaml 部分
我们需要实现旋转动画:
所以要用到这个:
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/> <EasingDoubleKeyFrame Value="90" KeyTime="0:0:0.2"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="270" KeyTime="0:0:1.6"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="450" KeyTime="0:0:1.8"> </EasingDoubleKeyFrame> <LinearDoubleKeyFrame Value="630" KeyTime="0:0:3.2"/> <EasingDoubleKeyFrame Value="720" KeyTime="0:0:3.4"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="720" KeyTime="0:0:5.0"> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames>
上面这一段是单个ellipse的运动轨迹,当然你需要在属性中设置他的中心点值
代码如下:
<Ellipse x:Name="el" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" > <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse>
接下来的事情就好办了,我们需要他转1圈就消失 结束后也消失,所以需要控制透明度,
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity"> <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:0.2"> <EasingDoubleKeyFrame.EasingFunction> <BackEase EasingMode="EaseInOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:1.6"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:1.8"> </EasingDoubleKeyFrame> <LinearDoubleKeyFrame Value="1" KeyTime="0:0:3.2"/> <EasingDoubleKeyFrame Value="0" KeyTime="0:0:3.5"> <EasingDoubleKeyFrame.EasingFunction> <BackEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="0" KeyTime="0:0:5.0"> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames>
最终把一个圆变成多个圆的工作 就交给代码了,需要一点点小技巧 以下使用.net 4.5实现 其他版本可以吧Task.Delay 替换成Thread.Sleep
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:local="clr-namespace:Transvalue.MetroStyleBusyIndicator" x:Class="Transvalue.MetroStyleBusyIndicator.MetroRotaionIndicator" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <UserControl.Resources> <Storyboard x:Key="Trans" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Ellipse.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"> <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/> <EasingDoubleKeyFrame Value="90" KeyTime="0:0:0.2"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="270" KeyTime="0:0:1.6"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="450" KeyTime="0:0:1.8"> </EasingDoubleKeyFrame> <LinearDoubleKeyFrame Value="630" KeyTime="0:0:3.2"/> <EasingDoubleKeyFrame Value="720" KeyTime="0:0:3.4"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="720" KeyTime="0:0:5.0"> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity"> <LinearDoubleKeyFrame Value="0" KeyTime="0:0:0"/> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:0.2"> <EasingDoubleKeyFrame.EasingFunction> <BackEase EasingMode="EaseInOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:1.6"> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="1" KeyTime="0:0:1.8"> </EasingDoubleKeyFrame> <LinearDoubleKeyFrame Value="1" KeyTime="0:0:3.2"/> <EasingDoubleKeyFrame Value="0" KeyTime="0:0:3.5"> <EasingDoubleKeyFrame.EasingFunction> <BackEase EasingMode="EaseOut"/> </EasingDoubleKeyFrame.EasingFunction> </EasingDoubleKeyFrame> <EasingDoubleKeyFrame Value="0" KeyTime="0:0:5.0"> </EasingDoubleKeyFrame> </DoubleAnimationUsingKeyFrames> </Storyboard> </UserControl.Resources> <Canvas> <Ellipse x:Name="el" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" > <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse x:Name="el2" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" Opacity="0" > <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse x:Name="el3" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" Opacity="0"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse x:Name="el4" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" Opacity="0"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse x:Name="el5" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" Opacity="0"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> <Ellipse x:Name="el6" Width="10" Height="10" Fill="White" Canvas.Left="73" Canvas.Top="57" Opacity="0"> <Ellipse.RenderTransform> <TransformGroup> <ScaleTransform/> <SkewTransform/> <RotateTransform CenterX="-20" CenterY="-40"/> <TranslateTransform/> </TransformGroup> </Ellipse.RenderTransform> </Ellipse> </Canvas> </UserControl>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Transvalue.MetroStyleBusyIndicator { /// <summary> /// MetroRotaionIndicator.xaml 的交互逻辑 /// </summary> public partial class MetroRotaionIndicator : UserControl { Storyboard trans; public MetroRotaionIndicator() { InitializeComponent(); trans = Resources["Trans"] as Storyboard; this.Loaded += ((sender, e) => { Active(); }); } public async void Active() { el.BeginStoryboard(trans); await Task.Delay(170); el2.BeginStoryboard(trans); await Task.Delay(170); el3.BeginStoryboard(trans); await Task.Delay(170); el4.BeginStoryboard(trans); await Task.Delay(170); el5.BeginStoryboard(trans); await Task.Delay(170); el6.BeginStoryboard(trans); } public void Stop() { trans.Stop(el); trans.Stop(el2); trans.Stop(el3); trans.Stop(el4); trans.Stop(el5); trans.Stop(el6); } } }
将以上内容编译成用户控件即可使用。
xmlns:MetroStyleBusyIndicator="clr-namespace:Transvalue.MetroStyleBusyIndicator;assembly=Transvalue.MetroStyleBusyIndicator"
<MetroStyleBusyIndicator:MetroRotaionIndicator HorizontalAlignment="Left" Height="187" Margin="924,534,0,0" VerticalAlignment="Top" Width="217"/>