首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >深度剖析一个弧形进度条的实现

深度剖析一个弧形进度条的实现

作者头像
极炫小钢炮
发布2024-12-13 17:06:01
发布2024-12-13 17:06:01
1K0
举报

1、使用 Path 结合 ArcSegment 绘制圆弧

1、属性解读

Path 是 WPF 中的一个标记元素,用于绘制复杂的几何路径形状,而 ArcSegment 用于描述 Path 中两点之间的一条椭圆弧。两者结合可以很轻松的实现圆弧效果。

通常使用以下几个属性控制 ArcSegment:

属性

说明

Size

X 轴和 Y 轴的半径。(相等时表示圆的半径)

IsLargeArc

绘制大圆弧(大于180度)部分,还是小圆(小于180度)弧部分。

SweepDirection

弧线绘制的方向。(Clockwise 顺时针方向)

Point

终点(起点在 Path 或外层 Segment 中描述)。

2、静态圆弧

在 WPF 中,原点坐标始终位于左上角,知道这个概念,那么就可以按照下面代码绘制一个弧形:

代码语言:csharp
复制
                <Path Stroke="SlateBlue" StrokeThickness="8" Width="200" Height="200">
                    <Path.Data>
                        <PathGeometry>
                            <PathFigure IsClosed="False" StartPoint="90,180">
                                <ArcSegment IsLargeArc="True"
                                            Point="180,90"
                                            Size="90,90"
                                            SweepDirection="Clockwise"/>
                            </PathFigure>
                        </PathGeometry>
                    </Path.Data>
                </Path>

代码说明:绘制一个起点(90,180)到终点(180,90) 的顺时针方向的大圆弧。

有人看了就要说了,我要的是一个左右对称的圆弧,很简单,我们给他旋转45度就行了,在Path上增加旋转属性,代码如下:

代码语言:csharp
复制
<Path Stroke="SlateBlue" StrokeThickness="8" Width="200" Height="200" RenderTransformOrigin="0.5,0.5">
    <Path.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="45"/>
        </TransformGroup>
    </Path.RenderTransform>
    <Path.Data>
        <PathGeometry>
            <PathFigure IsClosed="False" StartPoint="90,180">
                <ArcSegment IsLargeArc="True"
                            Point="180,90"
                            Size="90,90"
                            SweepDirection="Clockwise" x:Name="pathArc"/>
            </PathFigure>
        </PathGeometry>
    </Path.Data>
</Path>

RenderTransformOrigin 表示旋转中心,整个Path我们把它看作为0到1的区域大小,中心点位置就是(0.5,0.5)。

代码语言:csharp
复制
<Path Stroke="#6BCD5A" StrokeThickness="5" Width="200" Height="200" RenderTransformOrigin="0.5,0.5">
                    <Path.RenderTransform>
                        <TransformGroup>
                            <RotateTransform Angle="45"/>
                        </TransformGroup>
                    </Path.RenderTransform>
                    <Path.Data>
                        <PathGeometry>
                            <PathFigure IsClosed="False" StartPoint="90,180">
                                <ArcSegment IsLargeArc="True"
                            Point="180,90"
                            Size="90,90"
                            SweepDirection="Clockwise" x:Name="pathArc"/>
                            </PathFigure>
                        </PathGeometry>
                    </Path.Data>
                </Path>

这里我们通过两个圆弧的 StrokeThickness 数字大小来实现圆弧边界,覆盖的圆弧一般小于底色圆弧,保证一种内部镶嵌的感觉。为了凸显对比度,我把窗体背景色改为 Background="#959494" 。效果如下:

3、动态圆弧

那么问题来的,进度条都是动态的,那么怎么实现动态变化效果呢,这里我们需要先学习一下弧形计算的基础知识。首先,我们要知道圆弧线的坐标计算公式如下:

  • x轴坐标 计算公式为:x = 圆心x + 半径 × cos(弧度)。
  • y轴坐标 计算公式为:y = 圆心y + 半径 × sin(弧度)。

接下来了解就是根据这个公式动态计算圆弧坐标,再利用定时器动态绘制圆弧即可。注意前面我给覆盖层的圆弧取了一个别名 x:Name="pathArc",方便后台获取绘制的圆弧对象,我们写一个方法 CalculateEndPoint 来计算弧形的终点坐标,代码如下:

代码语言:csharp
复制
 /// <summary>
 /// 计算弧线终点坐标
 /// </summary>
 /// <param name="Value">弧形当前值</param>
 /// <param name="Min">弧形最小值</param>
 /// <param name="Max">弧形最大值</param>
 /// <param name="totalAngle">整个弧形的角度</param>
 /// <param name="offsetAngle">弧形缺失的角度</param>
 private void CalculateEndPoint(int Value,int Min,int Max,int totalAngle,int offsetAngle)
 {
     //值有效性校验
     int value = Value >= Max ? Max : Value <= Min ? Min : Value;
     int radius = 90;//圆弧半径

     //计算圆弧坐标 
     // 1、计算圆弧角度  我们给弧度设定一个最小值和最大值,最小值表示0度,对最大值表示圆弧最大角度 这里我们的圆弧最大角度为270度
     //根据相似性就有以下等式成立  (当前圆弧值-最小值)/(最大值-最小值)=当前圆弧角度/总的圆弧角度
     //得到 当前圆弧角度=总的圆弧角度*(当前圆弧值-最小值)/(最大值-最小值)

     //2、计算角度
     double angle = totalAngle / (Max - Min) * (Value - Min);
     //3、计算弧度
     //计算弧度 加上圆形缺失的角度值(面板有90度是缺失的)
     double rad = (Math.PI / 180) * (angle + offsetAngle);

     //4、计算弧线终点坐标
     //x = 圆心x + 半径 × cos(角度)。
     double x = radius * Math.Cos(rad) + radius;
     //y = 圆心y + 半径 × sin(角度)。
     double y = radius * Math.Sin(rad) + radius;
     Point point = new Point(x, y);
     pathArc.IsLargeArc = angle > 180;
     pathArc.Point = point;
 }

代码注释请详细观看哦,每一步的计算都写了详细说明。

4、运行效果

5、圆弧两端点的形状

有些同学又想问了,我们的需求是要两端是圆形的,现在弧线两端都是平平的直角,不满足需求。那么我介绍下 Path 的两个属性 StrokeStartLineCap 和 StrokeEndLineCap ,这两个就是用来描述起始和终点端点的样式,样式支持的是 PenLineCap 枚举类型,一共有四种形态,满足各种端点需求,可首位不同组合使用:

所以要实现圆形端点,给 Path 代码修改如下:

代码语言:csharp
复制
   <Path Stroke="SlateBlue" StrokeThickness="8" Width="200" Height="200" RenderTransformOrigin="0.5,0.5" StrokeStartLineCap="Round" StrokeEndLineCap="Round">

2、总结

以上就是今天要讲的内容,本文详解析了一个圆弧的绘制和动态绘制实现,感兴趣的同学可以加WPF群(加资源群 971786928 获取源代码 ,WPF学习群 733530469)一起学习,下一节,我们讲解如何封装一圆弧绘制的控件。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、使用 Path 结合 ArcSegment 绘制圆弧
    • 1、属性解读
    • 2、静态圆弧
    • 3、动态圆弧
    • 4、运行效果
    • 5、圆弧两端点的形状
  • 2、总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档