WPF利用動畫實現圓形進度條

  這是個人第一篇隨筆,最近由於工做須要,開始學習WPF相關技術,本身想實現如下圓形進度條的效果,逛了園子發現基本都是好久之前的文章,實現方式通常都是GDI實現的,想到WPF中動畫效果不錯,因而本身研究了一下,還真讓我作出來了,廢話很少說了,先上效果。前端

  這個效果是否是還不錯?這裏面實現了數字實時顯示以及根據進度進行自動漸變的效果。實現原理其實很簡單,利用WPF動畫,其中主要元素有border(實現裏外層圓的效果),Arc扇面(就是用來實現外層填充效果的),Label(用來顯示進度百分比)。express

1.實現裏外雙層圓背景效果ide

  這裏我用了兩個border實現,將兩個border的CornerRadius設置爲500,這樣保證他們是兩個圓(這裏不用Ellipse是我以爲border可能更加省資源),而後將他們他們的寬度設置爲100和80,讓他們做爲同心圓。其餘設置主要爲了美觀此處再也不多說,一會上代碼便可。學習

2.利用Arc實現填充效果動畫

  提及這個Arc還真是個好東西,以前只是知道它是個扇面,可是沒想到還能夠實現弧度填充,這得益於它的ArcThickness能夠設置爲小數,這個具體數值能夠在blend中本身調節一下,ArcThicknessUnit設置爲Percent,意思是單位是百分比。而後利用Arc的StartAngle和EndAngle就能夠輕鬆實現進度填充了。this

3.利用Label實現進度顯示spa

  最後在中間放置一個Label,而後將它的Text屬性綁定到Arc的EndAngle上,以後本身寫個Convert將角度轉化爲百分比便可。3d

4.動畫的實現code

  剩下的就能夠利用blend作個動畫,動畫效果十分簡單,開始時間,結束時間,開始角度,結束角度。這樣簡單的填充效果就實現了,最後還要實現漸變效果,好吧,其實也比較簡單,一樣的開始時間,結束時間,開始顏色,結束顏色,而後兩個動畫的時間間隔相同就好,這樣效果比較同步。orm

注意:最後說一句,用ViewBox將整個效果框起來,這樣之後不管你怎麼拖拽這個空間,內部都不會出現變形的效果了。

代碼以下:

 1 <UserControl x:Class="MyUserControlLibrary.WaitingAndProgress"
 2              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 5              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
 6              xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
 7              xmlns:local ="clr-namespace:MyUserControlLibrary"
 8              mc:Ignorable="d" 
 9              d:DesignHeight="100" d:DesignWidth="100" Loaded="UserControl_Loaded">
10     <UserControl.Resources>
11         <local:ConverterCircleToPercent x:Key="converter"/>
12         <Storyboard x:Key="MainStoryboard" RepeatBehavior="Forever">
13             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ShowArea">
14                 <EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="360"/>
15             </DoubleAnimationUsingKeyFrames>
16             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="minCircle">
17                 <EasingDoubleKeyFrame KeyTime="0:0:1.6" Value="360"/>
18             </DoubleAnimationUsingKeyFrames>
19         </Storyboard>
20         <Storyboard x:Key="FillStoryboard" Completed="Storyboard_Completed">
21             <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(ed:Arc.EndAngle)" Storyboard.TargetName="FillArea">
22                 <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
23                 <EasingDoubleKeyFrame KeyTime="0:0:0.05" Value="0"/>
24             </DoubleAnimationUsingKeyFrames>
25             <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="FillArea">
26                 <EasingColorKeyFrame KeyTime="0:0:0" Value="#FFFF0000"/>
27                 <EasingColorKeyFrame KeyTime="0:0:0.05" Value="#FF008000"/>
28             </ColorAnimationUsingKeyFrames>
29         </Storyboard>
30     </UserControl.Resources>
31     <Viewbox>
32     <Grid>
33             <Border Name="MaxCircle" CornerRadius="500" Width="100" Height="100" Background="White"  Opacity="0.2"/>
34             <Border Name="minCircle" CornerRadius="500" Width="80" Height="80" BorderBrush="black" BorderThickness="2" Opacity="0.4" RenderTransformOrigin="0.5,0.5">
35                 <Border.RenderTransform>
36                     <TransformGroup>
37                         <ScaleTransform/>
38                         <SkewTransform/>
39                         <RotateTransform/>
40                         <TranslateTransform/>
41                     </TransformGroup>
42                 </Border.RenderTransform>
43                 <Border.Background>
44                     <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
45                         <GradientStop Color="White" Offset="0"/>
46                         <GradientStop Color="Transparent" Offset="0.5"/>
47                         <GradientStop Color="White" Offset="1"/>
48                     </LinearGradientBrush>
49                 </Border.Background>
50             </Border>
51             <ed:Arc Name="FillArea" ArcThickness="0.18" ArcThicknessUnit="Percent" StartAngle="0" EndAngle="0" Width="95" Height="95" Stretch="None" Opacity="0.8" Fill="Red"/>
52             <Label Name="ShowLabel" Width="60" Height="60" FontFamily="宋體" FontWeight="Bold" Content="{Binding ElementName=FillArea,Path=EndAngle,Converter={StaticResource converter}}" FontSize="32" Foreground="White" Opacity="0.8" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
53     </Grid>
54     </Viewbox>
55 </UserControl>
前端XMAL
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Windows;
  6 using System.Windows.Controls;
  7 using System.Windows.Data;
  8 using System.Windows.Documents;
  9 using System.Windows.Input;
 10 using System.Windows.Media;
 11 using System.Windows.Media.Animation;
 12 using System.Windows.Media.Imaging;
 13 using System.Windows.Navigation;
 14 using System.Windows.Shapes;
 15 
 16 namespace MyUserControlLibrary
 17 {
 18     /// <summary>
 19     /// WaitingAndProgress.xaml 的交互邏輯
 20     /// </summary>
 21     public partial class WaitingAndProgress : UserControl
 22     {
 23         #region 屬性
 24 
 25         private WaitAndProgressType showType = WaitAndProgressType.WaitingAndProgress;
 26         /// <summary>
 27         /// 當前樣式類型
 28         /// </summary>
 29         [System.ComponentModel.Browsable(true),System.ComponentModel.Category("Appreance"),System.ComponentModel.Description("設置或獲取當前樣式類型")]
 30         public WaitAndProgressType ShowType {
 31             get {
 32                 return showType;
 33             }
 34             set {
 35                 showType = value;
 36             }
 37         }
 38 
 39         #endregion
 40 
 41         public WaitingAndProgress()
 42         {
 43             InitializeComponent();
 44         }
 45 
 46         #region 方法
 47 
 48         public void setPrecent(double d) {
 49             if (showType == WaitAndProgressType.Waiting) {
 50                 return;
 51             }
 52             Storyboard b = (Storyboard)this.Resources["FillStoryboard"];
 53             DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[0];
 54             ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[1];
 55             if (d >= 0 && d <= 10)
 56             {
 57                 cf.KeyFrames[1].Value = ToColor("#FFFF3300");
 58             }
 59             if (d > 10 && d <= 20)
 60             {
 61                 cf.KeyFrames[1].Value = ToColor("#FFFF6600");
 62             }
 63             if (d > 20 && d <= 30)
 64             {
 65                 cf.KeyFrames[1].Value = ToColor("#FFFF9900");
 66             }
 67             if (d > 30 && d <= 40)
 68             {
 69                 cf.KeyFrames[1].Value = ToColor("#FFFFCC00");
 70             }
 71             if (d > 40 && d <= 50)
 72             {
 73                 cf.KeyFrames[1].Value = ToColor("#FFFFFF00");
 74             }
 75             if (d > 50 && d <= 60)
 76             {
 77                 cf.KeyFrames[1].Value = ToColor("#FFCCFF00");
 78             }
 79             if (d > 60 && d <= 70)
 80             {
 81                 cf.KeyFrames[1].Value = ToColor("#FF99FF00");
 82             }
 83             if (d > 70 && d <= 80)
 84             {
 85                 cf.KeyFrames[1].Value = ToColor("#FF66FF00");
 86             }
 87             if (d > 80 && d <= 90)
 88             {
 89                 cf.KeyFrames[1].Value = ToColor("#FF33FF00");
 90             }
 91             if (d > 90 && d <= 100)
 92             {
 93                 cf.KeyFrames[1].Value = ToColor("#FF00FF00");
 94             }
 95             df.KeyFrames[1].Value = d*3.6;
 96             b.Begin();
 97         }
 98 
 99         /// <summary>
100         /// 將blend的8位顏色值轉爲color
101         /// </summary>
102         /// <param name="colorName"></param>
103         /// <returns></returns>
104         public Color ToColor(string colorName)
105         {
106             if (colorName.StartsWith("#"))
107                 colorName = colorName.Replace("#", string.Empty);
108             int v = int.Parse(colorName, System.Globalization.NumberStyles.HexNumber);
109             return new Color()
110             {
111                 A = Convert.ToByte((v >> 24) & 255),
112                 R = Convert.ToByte((v >> 16) & 255),
113                 G = Convert.ToByte((v >> 8) & 255),
114                 B = Convert.ToByte((v >> 0) & 255)
115             };
116         }
117 
118         #endregion
119 
120         #region 事件
121 
122         //載入時事件處理
123         private void UserControl_Loaded(object sender, RoutedEventArgs e)
124         {
125             if (showType != WaitAndProgressType.Progress)
126             {
127                 Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"];
128                 b1.Begin();
129                 if (showType == WaitAndProgressType.Waiting)
130                 {
131                     ShowLabel.Visibility = System.Windows.Visibility.Hidden;
132                 }
133                 else {
134                     ShowLabel.Visibility = System.Windows.Visibility.Visible;
135                 }
136             }
137             else {
138                 Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"];
139                 b1.Stop();
140                 ShowLabel.Visibility = System.Windows.Visibility.Visible;
141             }
142         }
143 
144         //漸變更畫完成時
145         private void Storyboard_Completed(object sender, EventArgs e)
146         {
147             Storyboard b = (Storyboard)this.Resources["FillStoryboard"];
148             ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[1];
149             DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[0];
150             df.KeyFrames[0].Value = df.KeyFrames[1].Value;
151             cf.KeyFrames[0].Value = cf.KeyFrames[1].Value;
152         }
153 
154         #endregion
155 
156         
157     }
158 }
後臺代碼
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Globalization;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Windows.Data;
 7 
 8 namespace MyUserControlLibrary
 9 {
10     /// <summary>
11     /// 將角度轉化成百分比
12     /// </summary>
13     public class ConverterCircleToPercent:IValueConverter
14     {
15         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
16         {
17             return (int)(double.Parse(value.ToString()) * 10 / 36);
18         }
19         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20         {
21             throw new NullReferenceException();
22         }
23     }
24 }
轉換類型
相關文章
相關標籤/搜索