用Raphael在网页中画圆环进度条

简介:

条状的进度条我们见得太多了,实现起来比较简单,它总是长方形的,在方形的区域里摆放就不太好看了。随着css3的出现,圆环状的进度条开始用得越来越多,不过由于IE6/7/8不支持css3,我们只能换其它方法来实现。本文就采用Raphael来画一个,这个组件对svg和vml进行了一个统一的封装,根据浏览器使用不同的技术实现绘制,因此IE也能用。


先上效果图:

164217248.png


效果还不错吧?代码其实也不复杂,抛砖引玉一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!DOCTYPE html PUBLIC  "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
<html xmlns= "http://www.w3.org/1999/xhtml"  >
<head>
<title>圆形进度条</title>
<meta http-equiv= "Content-Type"  content= "text/html; charset=gb2312" />
<script src= "jquery-1.4.2.js" ></script>
<script src= "raphael-min.js" ></script>
<style>
#txt{
     width:74px;
     height:74px;
     line-height:74px;
     position:absolute;
     margin-top:-74px;
     text-align:center;
     color: #9e9fa3;
     font-size:18px;
     font-family:Arial;
}
</style>
<script>
var  demo = {
                                      
     paper:  null ,
     init:  function (){
         //初始化Raphael画布
         this .paper = Raphael( "bg" , 74, 74);
         //把底图先画上去
         this .paper.image( "progressBg.png" , 0, 0, 74, 74);
         //进度比例,0到1,在本例中我们画65%
         //需要注意,下面的算法不支持画100%,要按99.99%来画
         var  percent = 0.65,
             drawPercent = percent >= 1 ? 0.9999 : percent;
         //开始计算各点的位置,见后图
         //r1是内圆半径,r2是外圆半径
         var  r1 = 26, r2 = 31, PI = Math.PI,
             p1 = {
                 x:37,
                 y:69
             },
             p4 = {
                 x:p1.x,
                 y:p1.y - r2 + r1
             },
             p2 = {
                 x:p1.x + r2 * Math.sin(2 * PI * (1 - drawPercent)),
                 y:p1.y - r2 + r2 * Math.cos(2 * PI * (1 - drawPercent))
             },
             p3 = {
                 x:p4.x + r1 * Math.sin(2 * PI * (1 - drawPercent)),
                 y:p4.y - r1 + r1 * Math.cos(2 * PI * (1 - drawPercent))
             },
             path = [
                 'M' , p1.x,  ' ' , p1.y,
                 'A' , r2,  ' ' , r2,  ' 0 ' , percent > 0.5 ? 1 : 0,  ' 1 ' , p2.x,  ' ' , p2.y,
                 'L' , p3.x,  ' ' , p3.y,
                 'A' , r1,  ' ' , r1,  ' 0 ' , percent > 0.5 ? 1 : 0,  ' 0 ' , p4.x,  ' ' , p4.y,
                 'Z'
             ].join( '' );
         //用path方法画图形,由两段圆弧和两条直线组成,画弧线的算法见后
         this .paper.path(path)
             //填充渐变色,从#3f0b3f到#ff66ff
             .attr({ "stroke-width" :0.5,  "stroke" : "#c32ec3" "fill" : "90-#3f0b3f-#ff66ff" });
         //显示进度文字
         $( "#txt" ).text(Math.round(percent * 100) +  "%" );
     }
};
$( function (){
     demo.init();
});
</script>
</head>
<body>
<!-- 承载图形主体 -->
<div id= "bg" ></div>
<!-- 承载进度文字 -->
<div id= "txt" ></div>
</body>
</html>


进度条由两部分组成,首先是底图 progressBg.png,74×74的png图片,把它用Raphael的image方法先画上去:

164443714.png


其次是用Raphael画进度部分,由两条圆弧和两条线段组成,见下图:

164604197.png


先从p1画顺时针圆弧到p2,然后直线到p3,然后逆时针画圆弧到p4,再直线收回p1。之后用渐变色填充一下。以65%时为例,描述这个图形的path如下(基本上就是svg的语法):

1
2
3
4
5
M37 69
A31 31 0 1 1 62.079526825623375 19.778657178933337
L58.03444185374863 22.7175834403957
A26 26 0 1 0 37 64
Z


看起来有点吓人,其实分成几部分来看就简单了:

◆ 第一行表示移动到(37, 69)这个点作为起点,也就是p1;
◆ 第二行表示画一段圆弧,就是p1到p2之间的这一段;
◆ 第三行表示画一条直线,就是p2到p3之间的这一段;
◆ 第四行表示画一段圆板,已经p3到p4之间的这一段;
◆ 第五行表示封闭图形,相当于从p4连回p1;


这其中比较复杂的是圆弧的参数,其参数是这样的:

1
A rx ry x-axis-rotation large-arc-flag sweep-flag x y


以第一段弧为例,各参数说明如下:

◆ rx和ry:弧的半长轴和半短轴长度,由于我们画的是正圆,所以我们用的都是31;
◆ x-axix-rotation:此段弧的x轴与水平方向夹角,由于我们画的是正圆,所以此参数没用,填了0;
◆ large-arc-flag:大角度弧线还是小角度弧线,简单点说就是画圆的哪半边,1表示大角度。由于我们画的是65%的弧,是比较大的那半个弧,所以填了1。程序里是做了判断的;
◆ sweep-flag:绕中心的方向,1表示顺时针,0表示逆时针。我们的第一段弧是顺时针的,第二段是逆时针的;
◆ x和y:弧的终点坐标;


想深入了解的同学可以参考一下这篇文章:http://www.cnblogs.com/dxy1982/archive/2012/04/06/2395729.html,讲得挺不错的。


PS:如果不需要渐变,直接画一比较粗的圆弧就可以了,要简单得多。
PPS:不一定要画正圆,小修改一下,我们也可以画椭圆形的进度条。






     本文转自 BoyTNT 51CTO博客,原文链接:http://blog.51cto.com/boytnt/1074215,如需转载请自行联系原作者





相关文章
element 下拉菜单el-dropdown如何更改样式?
element 下拉菜单el-dropdown如何更改样式?
1810 0
uniapp拖动排序实现思路
uniapp拖动排序实现思路
276 0
|
6月前
|
机器学习/深度学习 人工智能 自然语言处理
超越文本局限:生成式人工智能(GAI)认证引领未来技能新范式
生成式人工智能(GAI)正成为重塑社会生产力的关键力量,但其在复杂逻辑与深度推理方面存在局限。本文探讨GAI技术现状、局限及突破路径,如多模态融合、强化学习等,并引入GAI认证体系,助力个人技能提升与企业创新。未来,GAI认证有望引领技能新范式,推动社会生产力变革。
|
9月前
|
前端开发 JavaScript Java
java常用数据判空、比较和类型转换
本文介绍了Java开发中常见的数据处理技巧,包括数据判空、数据比较和类型转换。详细讲解了字符串、Integer、对象、List、Map、Set及数组的判空方法,推荐使用工具类如StringUtils、Objects等。同时,讨论了基本数据类型与引用数据类型的比较方法,以及自动类型转换和强制类型转换的规则。最后,提供了数值类型与字符串互相转换的具体示例。
433 3
|
分布式计算 Hadoop 分布式数据库
Hadoop生态系统介绍(二)大数据技术Hadoop入门理论系列之一----hadoop生态圈介绍
Hadoop生态系统介绍(二)大数据技术Hadoop入门理论系列之一----hadoop生态圈介绍
420 2
|
数据采集 运维 Cloud Native
Flink+Paimon在阿里云大数据云原生运维数仓的实践
构建实时云原生运维数仓以提升大数据集群的运维能力,采用 Flink+Paimon 方案,解决资源审计、拓扑及趋势分析需求。
18676 54
Flink+Paimon在阿里云大数据云原生运维数仓的实践
|
10月前
|
存储 前端开发 安全
现货量化合约跟单交易所系统开发逻辑策略及源码示例
现货量化合约跟单交易所系统的开发涉及需求分析、技术选型、数据获取、策略设计、风险管理、交易接口、系统架构、安全合规、测试优化等多个环节。本文档详细介绍了开发策略指南及Python源码示例,涵盖从连接交易所API获取市场数据到系统部署和优化的全过程。
|
10月前
|
JavaScript 测试技术 UED
解决 Vue 项目中 Tree shaking 无法去除某些模块
【10月更文挑战第23天】解决 Vue 项目中 Tree shaking 无法去除某些模块的问题需要综合考虑多种因素,通过仔细分析、排查和优化,逐步提高 Tree shaking 的效果,为项目带来更好的性能和用户体验。同时,持续关注和学习相关技术的发展,不断探索新的解决方案,以适应不断变化的项目需求。
|
12月前
|
XML 编解码 JavaScript
从浏览器的解析规则认识XSS防御
从浏览器的解析规则认识XSS防御
129 3
|
存储 监控 安全
中间件 安全问题
【7月更文挑战第14天】
268 2