原文: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. 使用easy_install安装numpy、pandas、matplotlib及各种第三方模块

    倒腾了一晚上最终把题目中的环境配好了.以下简要说明.留作资料.并共享. 1.安装python. 在cmd中能进入python环境,通过把python路径加入到系统路径中就可以实现. 2.安装easy- ...

  2. 代码讲解Android Scroller、VelocityTracker

    在编写自定义滑动控件时常常会用到Android触摸机制和Scroller及VelocityTracker.Android Touch系统简介(二):实例详解onInterceptTouchEvent与 ...

  3. DM8168 坎坷硬件之路(DDR3)

    新做了8168板,调试DDR3的时候EMIF0遇到了个别数据位出错的问题 DDR3 128MB*8=1GB 我为了測试DDR3的所有空间,把地址存到DDR3中,就是*pdata++=(Uint32)p ...

  4. 关于cocostudio加载UI json CCUIHELPER未声明问题

    查看官方的文档,在文档的最后添加了如何加载项目.如下代码: UILayer* ul =UILayer::create(); ul->addWidget(CCUIHELPER->create ...

  5. IntPtr与自定义结构互转

    //IntPtr转自定义结构 struct onlydata { IntPtr hwnd; }; onlydata pd=new onlydata(); IntPtr pd; pd=Marshal.P ...

  6. 使用 Java 配置进行 Spring bean 管理--转

    概述 众所周知,Spring 框架是控制反转 (IOC) 或依赖性注入 (DI) 模式的推动因素,而这种推动是通过基于容器的配置实现的.过去,Spring 允许开发人员使用基于 XML 的配置,通过利 ...

  7. 洛谷 1373 小a和uim之大逃离

    /* 很容易想到f[i][j][k][l][01] 表示到ij点 两个人得分为kl 01表示这一步谁走的 因为起点不同 路径不同 所以要枚举起点.. 时间复杂度 O(nmk*nmk) 空间复杂度 O( ...

  8. 移动端屏幕自适应js与rem

    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;&qu ...

  9. jquery获取元素到屏幕底的可视距离

    jquery获取元素到屏幕底的可视距离 要打对号的图里的height(我自称为可视高度:滚动条未滑到最底端)  不是打叉图里的到页面底部(滚动条到最底部时的height)(offset().top方法 ...

  10. Dedecms当前位置{dede:field name='position'/}修改

    这个实在list_article.htm模板出现的,而这个模板通过loadtemplage等等一系列操作是调用的include 下的arc.archives.class.php $this->F ...