前段时间有个需求就是实现一个动态的环形进度条,作为某业务的入口,这块呢经过一番查阅和思考后最终选择了canvas.
传统方式下,除非使用图片,不然没办法做出这种圆环的动态效果。但进度数据的范围相对而言比较广(整数值状态下为 0%~100% ,约 100 个独立状态),每个状态用图片来做显然是不现实的。可以考虑使用CSS3、Canvas来解决。
一、背景图
原理
将各个状态下的图片拼成一个sprite,定时更新background-position来显示各个状态下的图片,时间间隔掌握合适就形成了动画。这是最简单粗暴的做法。
优势
- 基本不用编写复杂的绘图代码,只要写好定时器部分的逻辑即可完成交互。
- 每个状态都可以用图来表示,展现复杂的进度效果很简单,只需要修改PSD即可。
- 整体来说,对开发人员的要求较低。
缺点
- 对状态点的数目很敏感。正常情况下的 100(0%~100%) 个状态需要相同数据的图片。当然也可以减少状态点的数目,但是这么做有可能会影响到后期状态切换时的渐进效果。
- 后期需要修改状态点展现时,需要重新制作 sprite 。
二、CSS3
CSS3 本身提供很多强大的属性,可以通过使用 border-radius、transform 等属性来完成上面的需求。
原理
先做一个环形的进度条,然后在它上面分别放置左右两个半圆(使用 clip 来显示一个圆的一半区域),最后定时旋转(使用 transform 中的 rotate 来实现)这两个半圆来显示出下面的进度条。连续执行后就形成了渐进的动画。
css属性帮助链接:
实现步骤
1)先实现一个静态的圆环形进度条
1 | <div class="circle-progress"></div> |
1 | .circle-progress{ |
效果:

2)不是完整圆环
1 | .circle-progress{ |

看上去也不难吧!
3)不刚好都是45度的倍数
一步一步来,首先设置一个200 * 200的方块,再放两个矩形,每个矩形都占一半, 每个矩形内部有个半圆
1 | <div class="circleProgress-wrapper"> |
1 | .circleProgress-wrapper { |
效果如下:
关键: overflow: hidden;
然后看下右边圆
1 | .circle-progress { |

一个半圆弧出来了,但由于我们设置了上边框和右边框,所以上边框有一半溢出而被隐藏了,通过旋转得以还原:
1 | .circle-progress { |
溢出部分被旋转出来而显示:
所以只要旋转自己想要的角度就可以实现任意比例的进度条。接下来把左半圆弧也实现,变成一个全圆:
1 | .left-circle{ |

然后就是要让圆环动起来,原理: 先让右半圆弧旋转180度,再让左半圆弧旋转180度。这样,两个半圆弧由于先后都全部溢出而消失了,所以看起来就是进度条再滚动的效果:
1 | .right-circle { |
附上完整代码:
1 | <div class="circle-progress-wrapper"> |
1 | .circle-progress-wrapper { |
See the Pen
YmVQvr by Iona (@lozoe)
on CodePen.
三、canvas
思路
先确定展示的形状,是整个圆、半圆还是一般的弧形
把确定好形状的圆弧均分100等份,计算出每一份所占的弧度
灰色圆弧占100份,红色圆弧最终占的份数由参数确定
设置setInterval定时器,重复执行画图操作
- 清空画布
- 先画灰色的圆弧,占100份
- 再画红色的圆弧:红色圆弧的份数从0开始,每次加1
- 当红色圆弧的份数达到指定值(传的参数)的时候,清除定时器
代码实现
1 |
|
See the Pen
canvas progress bar by Iona (@lozoe)
on CodePen.
参考:
https://www.cnblogs.com/jr1993/p/4677921.html
http://reygreen1.github.io/2015/09/08/canvas-circle-progress/
https://www.xiabingbao.com/css/2015/07/27/css3-animation-circle.html