原文:WPF利用动画实现圆形进度条

  这是我的第一篇随笔,最近因为工作需要,开始学习WPF相关技术,自己想实现以下圆形进度条的效果,逛了园子发现基本都是很久以前的文章,实现方式一般都是GDI实现的,想到WPF中动画效果不错,于是自己研究了一下,还真让我做出来了,废话不多说了,先上效果。

  这个效果是不是还不错?这里面实现了数字实时显示以及根据进度进行自动渐变的效果。实现原理其实很简单,利用WPF动画,其中主要元素有border(实现里外层圆的效果),Arc扇面(就是用来实现外层填充效果的),Label(用来显示进度百分比)。

1.实现里外双层圆背景效果

  这里我用了两个border实现,将两个border的CornerRadius设置为500,这样保证他们是两个圆(这里不用Ellipse是我觉得border可能更加省资源),然后将他们他们的宽度设置为100和80,让他们作为同心圆。其他设置主要为了美观此处不再多说,一会上代码即可。

2.利用Arc实现填充效果

  说起这个Arc还真是个好东西,之前只是知道它是个扇面,但是没想到还可以实现弧度填充,这得益于它的ArcThickness可以设置为小数,这个具体数值可以在blend中自己调节一下,ArcThicknessUnit设置为Percent,意思是单位是百分比。然后利用Arc的StartAngle和EndAngle就可以轻松实现进度填充了。

3.利用Label实现进度显示

  最后在中间放置一个Label,然后将它的Text属性绑定到Arc的EndAngle上,之后自己写个Convert将角度转化为百分比即可。

4.动画的实现

  剩下的就可以利用blend做个动画,动画效果十分简单,开始时间,结束时间,开始角度,结束角度。这样简单的填充效果就实现了,最后还要实现渐变效果,好吧,其实也比较简单,同样的开始时间,结束时间,开始颜色,结束颜色,然后两个动画的时间间隔相同就好,这样效果比较同步。

注意:最后说一句,用ViewBox将整个效果框起来,这样以后无论你怎么拖拽这个空间,内部都不会出现变形的效果了。

代码如下:

 <UserControl x:Class="MyUserControlLibrary.WaitingAndProgress"
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:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:local ="clr-namespace:MyUserControlLibrary"
mc:Ignorable="d"
d:DesignHeight="" d:DesignWidth="" Loaded="UserControl_Loaded">
<UserControl.Resources>
<local:ConverterCircleToPercent x:Key="converter"/>
<Storyboard x:Key="MainStoryboard" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="ShowArea">
<EasingDoubleKeyFrame KeyTime="0:0:1.6" Value=""/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="minCircle">
<EasingDoubleKeyFrame KeyTime="0:0:1.6" Value=""/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="FillStoryboard" Completed="Storyboard_Completed">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(ed:Arc.EndAngle)" Storyboard.TargetName="FillArea">
<EasingDoubleKeyFrame KeyTime="" Value=""/>
<EasingDoubleKeyFrame KeyTime="0:0:0.05" Value=""/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="FillArea">
<EasingColorKeyFrame KeyTime="0:0:0" Value="#FFFF0000"/>
<EasingColorKeyFrame KeyTime="0:0:0.05" Value="#FF008000"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<Viewbox>
<Grid>
<Border Name="MaxCircle" CornerRadius="" Width="" Height="" Background="White" Opacity="0.2"/>
<Border Name="minCircle" CornerRadius="" Width="" Height="" BorderBrush="black" BorderThickness="" Opacity="0.4" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
<GradientStop Color="White" Offset=""/>
<GradientStop Color="Transparent" Offset="0.5"/>
<GradientStop Color="White" Offset=""/>
</LinearGradientBrush>
</Border.Background>
</Border>
<ed:Arc Name="FillArea" ArcThickness="0.18" ArcThicknessUnit="Percent" StartAngle="" EndAngle="" Width="" Height="" Stretch="None" Opacity="0.8" Fill="Red"/>
<Label Name="ShowLabel" Width="" Height="" FontFamily="宋体" FontWeight="Bold" Content="{Binding ElementName=FillArea,Path=EndAngle,Converter={StaticResource converter}}" FontSize="" Foreground="White" Opacity="0.8" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
</Grid>
</Viewbox>
</UserControl>

前端XMAL

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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 MyUserControlLibrary
{
/// <summary>
/// WaitingAndProgress.xaml 的交互逻辑
/// </summary>
public partial class WaitingAndProgress : UserControl
{
#region 属性 private WaitAndProgressType showType = WaitAndProgressType.WaitingAndProgress;
/// <summary>
/// 当前样式类型
/// </summary>
[System.ComponentModel.Browsable(true),System.ComponentModel.Category("Appreance"),System.ComponentModel.Description("设置或获取当前样式类型")]
public WaitAndProgressType ShowType {
get {
return showType;
}
set {
showType = value;
}
} #endregion public WaitingAndProgress()
{
InitializeComponent();
} #region 方法 public void setPrecent(double d) {
if (showType == WaitAndProgressType.Waiting) {
return;
}
Storyboard b = (Storyboard)this.Resources["FillStoryboard"];
DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[];
ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[];
if (d >= && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFFF3300");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFFF6600");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFFF9900");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFFFCC00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFFFFF00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FFCCFF00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FF99FF00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FF66FF00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FF33FF00");
}
if (d > && d <= )
{
cf.KeyFrames[].Value = ToColor("#FF00FF00");
}
df.KeyFrames[].Value = d*3.6;
b.Begin();
} /// <summary>
/// 将blend的8位颜色值转为color
/// </summary>
/// <param name="colorName"></param>
/// <returns></returns>
public Color ToColor(string colorName)
{
if (colorName.StartsWith("#"))
colorName = colorName.Replace("#", string.Empty);
int v = int.Parse(colorName, System.Globalization.NumberStyles.HexNumber);
return new Color()
{
A = Convert.ToByte((v >> ) & ),
R = Convert.ToByte((v >> ) & ),
G = Convert.ToByte((v >> ) & ),
B = Convert.ToByte((v >> ) & )
};
} #endregion #region 事件 //载入时事件处理
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
if (showType != WaitAndProgressType.Progress)
{
Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"];
b1.Begin();
if (showType == WaitAndProgressType.Waiting)
{
ShowLabel.Visibility = System.Windows.Visibility.Hidden;
}
else {
ShowLabel.Visibility = System.Windows.Visibility.Visible;
}
}
else {
Storyboard b1 = (Storyboard)this.Resources["MainStoryboard"];
b1.Stop();
ShowLabel.Visibility = System.Windows.Visibility.Visible;
}
} //渐变动画完成时
private void Storyboard_Completed(object sender, EventArgs e)
{
Storyboard b = (Storyboard)this.Resources["FillStoryboard"];
ColorAnimationUsingKeyFrames cf = (ColorAnimationUsingKeyFrames)b.Children[];
DoubleAnimationUsingKeyFrames df = (DoubleAnimationUsingKeyFrames)b.Children[];
df.KeyFrames[].Value = df.KeyFrames[].Value;
cf.KeyFrames[].Value = cf.KeyFrames[].Value;
} #endregion }
}

后台代码

 using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data; namespace MyUserControlLibrary
{
/// <summary>
/// 将角度转化成百分比
/// </summary>
public class ConverterCircleToPercent:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int)(double.Parse(value.ToString()) * / );
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NullReferenceException();
}
}
}

转换类型

WPF利用动画实现圆形进度条的更多相关文章

  1. 微信小程序动画之圆形进度条

    微信小程序动画之圆形进度条 上图: js: //获取应用实例 var app = getApp() var interval; var varName; var ctx = wx.createCanv ...

  2. 利用css3动画和border来实现圆形进度条

    最近在学习前端的一些知识,发现border的功能十分强大啊! 首先来看看demo 就是这么一个圆形的进度条,在文本框中输入0-100的数值下面的进度条相应的转到多少 这个主要是利用border,旋转和 ...

  3. WPF 实现圆形进度条

    项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...

  4. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画

    通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程先简单的介绍下CAShapeLayer1,CAShapeLayer继承自CALayer,可使用CALayer的所有属性2 ...

  5. 基于CAShapeLayer和贝塞尔曲线的圆形进度条动画【装载】

    初次接触CAShapeLayer和贝塞尔曲线,看了下极客学院的视频.对初学者来说感觉还不错.今天来说一个通过CAShapeLayer和贝塞尔曲线搭配的方法,创建的简单的圆形进度条的教程先简单的介绍下C ...

  6. Google Chrome 圆形进度条

    Conmajia © 2012 Updated on Feb. 21, 2018 Google Chrome 的圆形进度条. Demo 功能 显示百分比(0-100).如果进度值达到 100%,则将闪 ...

  7. 移动端纯CSS3制作圆形进度条所遇到的问题

    近日在开发的页面中,需要制作一个动态的圆形进度条,首先想到的是利用两个矩形,宽等于直径的一半,高等于直径,两个矩形利用浮动贴在一起,设置overflow:hidden属性,作为盒子,内部有一个与其宽高 ...

  8. vue 圆形进度条组件解析

    项目简介 本组件是vue下的圆形进度条动画组件 自由可定制,几乎全部参数均可设置 源码简单清晰 面向人群 急于使用vue圆形进度条动画组件的同学.直接下载文件,拷贝代码即可运行. 喜欢看源码,希望了解 ...

  9. canvas圆形进度条

    通过定义一个canvas标签, new方法传进ID值,和旋转角度值,即可生成圆形进度条 <!DOCTYPE html> <html lang="en"> & ...

随机推荐

  1. IE chrome兼容问题

    1.关于display显示和隐藏问题 document.getElementById("id").style.display="";//表示显示 documen ...

  2. listview 遇到问题java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0

    开发的时候 遇到 java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 这个异常有时候会有,有时候正常 不太好捕捉 猜测 已经 ...

  3. Android之开发常用颜色

    Android开发中常常要用一些个性化的颜色,然而茫茫的RBG颜色对照表,往往给人眼花缭乱的感觉,更别说从中轻易选出一两种比较满意的颜色,下面我就总结一下开发中常用到的比较绚丽的颜色,都是有名有姓的哦 ...

  4. Valgrind简介:

    Valgrind是动态分析工具的框架.有很多Valgrind工具可以自动的检测许多内存管理和多进程/线程的bugs,在细节上剖析你的程序.你也可以利用Valgrind框架来实现自己的工具. Valgr ...

  5. 二分图最大匹配(匈牙利算法Dfs模板)

    #include<iostream> #include<cstdio> #include<cstring> #define maxn 2020 using name ...

  6. (Excel导出失败)检索COM类工厂中CLSID为{00024500-0000-0000-C000-000000000046}的组件时失

    在DCOM 中不存在WORD.EXCEL等OFFICE组件   最近在做一个关于office转存PDF的Web项目.开发过程一切顺利. 起初在网上找到一些Word,PPT转PDF的代码.很好用.一切顺 ...

  7. oracle中创建一个用户,只能查看指定的视图,如何授权,创建别名

    1.create user A identified by Apassword,创建用户,用户名是A,密码是Apassword2.grant connect to A --授予connect权限3.g ...

  8. BOM和DOM详解

    DOM介绍 D(文档)可以理解为整个Web加载的网页文档,O(对象)可以理解为类似window对象只来的东西,可以调用属性和方法,这里我们说的是document对象,M(模型)可以理解为网页文档的树形 ...

  9. MTP设备无法安装驱动的解决办法

    1,进入设备管理器右击带黄色问号的MTP,选择“属性”,“详细信息”“设备范例 ID”(用Ctrl+C复制). 2,找到c:\windows\inf\wpdmtp.inf打开(或者通过运行打开),找到 ...

  10. 使用wireshark抓本机之间的包(转)

    所转地址:http://www.chinadmd.com/file/oc6evrwtzieitexvoupppisr_1.html 在进行通信开发的过程中,我们往往会把本机既作为客户端又作为服务器端来 ...