JS实现环形进度条(从0到100%)效果


Posted in Javascript onJuly 05, 2016

最近公司项目中要用到这种类似环形进度条的效果,初始就从0开始动画到100%结束。动画结果始终会停留在100%上,并不会到因为数据的关系停留在一半。

如图

JS实现环形进度条(从0到100%)效果

代码如下

demo.html

<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
<style>
.rad-prg{
position: relative;
}
.rad-con{
position: absolute;
z-index: 1;
top:0;
left: 0;
text-align: center;
width:90px;
height: 90px;
padding: 10px;
font-family: "microsoft yahei";
}
</style>
</head>
<body>
<div class="prg-cont rad-prg" id="indicatorContainer">
<div class="rad-con">
<p>¥4999</p>
<p>账户总览</p>
</div>
</div>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/radialIndicator.js"></script>
<script>
$('#indicatorContainer').radialIndicator({
barColor: '#007aff',
barWidth: 5,
initValue: 0,
roundCorner : true,
percentage: true,
displayNumber: false,
radius: 50
});
setTimeout(function(){
var radObj = $('#indicatorContainer2').data('radialIndicator');
radObj.animate(100);
},300);
</script>
</body>
</html>

radialIndicator.js 这是jquery的插件

/*
radialIndicator.js v 1.0.0
Author: Sudhanshu Yadav
Copyright (c) 2015 Sudhanshu Yadav - ignitersworld.com , released under the MIT license.
Demo on: ignitersworld.com/lab/radialIndicator.html
*/
;(function ($, window, document) {
"use strict";
//circumfence and quart value to start bar from top
var circ = Math.PI * 2,
quart = Math.PI / 2;
//function to convert hex to rgb
function hexToRgb(hex) {
// Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
hex = hex.replace(shorthandRegex, function (m, r, g, b) {
return r + r + g + g + b + b;
});
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : null;
}
function getPropVal(curShift, perShift, bottomRange, topRange) {
return Math.round(bottomRange + ((topRange - bottomRange) * curShift / perShift));
}
//function to get current color in case of 
function getCurrentColor(curPer, bottomVal, topVal, bottomColor, topColor) {
var rgbAryTop = topColor.indexOf('#') != -1 ? hexToRgb(topColor) : topColor.match(/\d+/g),
rgbAryBottom = bottomColor.indexOf('#') != -1 ? hexToRgb(bottomColor) : bottomColor.match(/\d+/g),
perShift = topVal - bottomVal,
curShift = curPer - bottomVal;
if (!rgbAryTop || !rgbAryBottom) return null;
return 'rgb(' + getPropVal(curShift, perShift, rgbAryBottom[0], rgbAryTop[0]) + ',' + getPropVal(curShift, perShift, rgbAryBottom[1], rgbAryTop[1]) + ',' + getPropVal(curShift, perShift, rgbAryBottom[2], rgbAryTop[2]) + ')';
}
//to merge object
function merge() {
var arg = arguments,
target = arg[0];
for (var i = 1, ln = arg.length; i < ln; i++) {
var obj = arg[i];
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
target[k] = obj[k];
}
}
}
return target;
}
//function to apply formatting on number depending on parameter
function formatter(pattern) {
return function (num) {
if(!pattern) return num.toString();
num = num || 0
var numRev = num.toString().split('').reverse(),
output = pattern.split("").reverse(),
i = 0,
lastHashReplaced = 0;
//changes hash with numbers
for (var ln = output.length; i < ln; i++) {
if (!numRev.length) break;
if (output[i] == "#") {
lastHashReplaced = i;
output[i] = numRev.shift();
}
}
//add overflowing numbers before prefix
output.splice(lastHashReplaced+1, output.lastIndexOf('#') - lastHashReplaced, numRev.reverse().join(""));
return output.reverse().join('');
}
}
//circle bar class
function Indicator(container, indOption) {
indOption = indOption || {};
indOption = merge({}, radialIndicator.defaults, indOption);
this.indOption = indOption;
//create a queryselector if a selector string is passed in container
if (typeof container == "string")
container = document.querySelector(container);
//get the first element if container is a node list
if (container.length)
container = container[0];
this.container = container;
//create a canvas element
var canElm = document.createElement("canvas");
container.appendChild(canElm);
this.canElm = canElm; // dom object where drawing will happen
this.ctx = canElm.getContext('2d'); //get 2d canvas context
//add intial value 
this.current_value = indOption.initValue || indOption.minValue || 0;
}
Indicator.prototype = {
constructor: radialIndicator,
init: function () {
var indOption = this.indOption,
canElm = this.canElm,
ctx = this.ctx,
dim = (indOption.radius + indOption.barWidth) * 2, //elm width and height
center = dim / 2; //center point in both x and y axis
//create a formatter function
this.formatter = typeof indOption.format == "function" ? indOption.format : formatter(indOption.format);
//maximum text length;
this.maxLength = indOption.percentage ? 4 : this.formatter(indOption.maxValue).length;
canElm.width = dim;
canElm.height = dim;
//draw a grey circle
ctx.strokeStyle = indOption.barBgColor; //background circle color
ctx.lineWidth = indOption.barWidth;
ctx.beginPath();
ctx.arc(center, center, indOption.radius, 0, 2 * Math.PI);
ctx.stroke();
//store the image data after grey circle draw
this.imgData = ctx.getImageData(0, 0, dim, dim);
//put the initial value if defined
this.value(this.current_value);
return this;
},
//update the value of indicator without animation
value: function (val) {
//return the val if val is not provided
if (val === undefined || isNaN(val)) {
return this.current_value;
}
val = parseInt(val);
var ctx = this.ctx,
indOption = this.indOption,
curColor = indOption.barColor,
dim = (indOption.radius + indOption.barWidth) * 2,
minVal = indOption.minValue,
maxVal = indOption.maxValue,
center = dim / 2;
//limit the val in range of 0 to 100
val = val < minVal ? minVal : val > maxVal ? maxVal : val;
var perVal = Math.round(((val - minVal) * 100 / (maxVal - minVal)) * 100) / 100, //percentage value tp two decimal precision
dispVal = indOption.percentage ? perVal + '%' : this.formatter(val); //formatted value
//save val on object
this.current_value = val;
//draw the bg circle
ctx.putImageData(this.imgData, 0, 0);
//get current color if color range is set
if (typeof curColor == "object") {
var range = Object.keys(curColor);
for (var i = 1, ln = range.length; i < ln; i++) {
var bottomVal = range[i - 1],
topVal = range[i],
bottomColor = curColor[bottomVal],
topColor = curColor[topVal],
newColor = val == bottomVal ? bottomColor : val == topVal ? topColor : val > bottomVal && val < topVal ? indOption.interpolate ? getCurrentColor(val, bottomVal, topVal, bottomColor, topColor) : topColor : false;
if (newColor != false) {
curColor = newColor;
break;
}
}
}
//draw th circle value
ctx.strokeStyle = curColor;
//add linecap if value setted on options
if (indOption.roundCorner) ctx.lineCap = "round";
ctx.beginPath();
ctx.arc(center, center, indOption.radius, -(quart), ((circ) * perVal / 100) - quart, false);
ctx.stroke();
//add percentage text
if (indOption.displayNumber) {
var cFont = ctx.font.split(' '),
weight = indOption.fontWeight,
fontSize = indOption.fontSize || (dim / (this.maxLength - (Math.floor(this.maxLength*1.4/4)-1)));
cFont = indOption.fontFamily || cFont[cFont.length - 1];
ctx.fillStyle = indOption.fontColor || curColor;
ctx.font = weight +" "+ fontSize + "px " + cFont;
ctx.textAlign = "center";
ctx.textBaseline = 'middle';
ctx.fillText(dispVal, center, center);
}
return this;
},
//animate progressbar to the value
animate: function (val) {
var indOption = this.indOption,
counter = this.current_value || indOption.minValue,
self = this,
incBy = Math.ceil((indOption.maxValue - indOption.minValue) / (indOption.frameNum || (indOption.percentage ? 100 : 500))), //increment by .2% on every tick and 1% if showing as percentage
back = val < counter;
//clear interval function if already started
if (this.intvFunc) clearInterval(this.intvFunc); 
this.intvFunc = setInterval(function () {
if ((!back && counter >= val) || (back && counter <= val)) {
if (self.current_value == counter) {
clearInterval(self.intvFunc);
return;
} else {
counter = val;
}
}
self.value(counter); //dispaly the value
if (counter != val) {
counter = counter + (back ? -incBy : incBy)
}; //increment or decrement till counter does not reach to value
}, indOption.frameTime);
return this;
},
//method to update options
option: function (key, val) {
if (val === undefined) return this.option[key];
if (['radius', 'barWidth', 'barBgColor', 'format', 'maxValue', 'percentage'].indexOf(key) != -1) {
this.indOption[key] = val;
this.init().value(this.current_value);
}
this.indOption[key] = val;
}
};
/** Initializer function **/
function radialIndicator(container, options) {
var progObj = new Indicator(container, options);
progObj.init();
return progObj;
}
//radial indicator defaults
radialIndicator.defaults = {
radius: 50, //inner radius of indicator
barWidth: 5, //bar width
barBgColor: '#eeeeee', //unfilled bar color
barColor: '#99CC33', //filled bar color , can be a range also having different colors on different value like {0 : "#ccc", 50 : '#333', 100: '#000'}
format: null, //format indicator numbers, can be a # formator ex (##,###.##) or a function
frameTime: 10, //miliseconds to move from one frame to another
frameNum: null, //Defines numbers of frame in indicator, defaults to 100 when showing percentage and 500 for other values
fontColor: null, //font color
fontFamily: null, //defines font family
fontWeight: 'bold', //defines font weight
fontSize : null, //define the font size of indicator number
interpolate: true, //interpolate color between ranges
percentage: false, //show percentage of value
displayNumber: true, //display indicator number
roundCorner: false, //have round corner in filled bar
minValue: 0, //minimum value
maxValue: 100, //maximum value
initValue: 0 //define initial value of indicator
};
window.radialIndicator = radialIndicator;
//add as a jquery plugin
if ($) {
$.fn.radialIndicator = function (options) {
return this.each(function () {
var newPCObj = radialIndicator(this, options);
$.data(this, 'radialIndicator', newPCObj);
});
};
}
}(window.jQuery, window, document, void 0));

以上所述是小编给大家介绍的JS实现环形进度条(从0到100%)效果 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript使用过程中需要注意的地方和一些基本语法
Aug 26 Javascript
JavaScript异步编程:异步数据收集的具体方法
Aug 19 Javascript
JS之Date对象和获取系统当前时间详解
Jan 13 Javascript
JavaScript保留两位小数的2个自定义函数
May 05 Javascript
Js可拖拽放大的层拖动特效实现方法
Feb 25 Javascript
代码分析jQuery四种静态方法使用
Jul 23 Javascript
jQuery简单实现提交数据出现loading进度条的方法
Mar 29 Javascript
js解决movebox移动问题
Mar 29 Javascript
js获取时间函数及扩展函数的方法
Oct 30 Javascript
原生js实现放大镜特效
Mar 08 Javascript
送你43道JS面试题(收藏)
Jun 17 Javascript
layui内置模块layim发送图片添加加载动画的方法
Sep 23 Javascript
JQuery组件基于Bootstrap的DropDownList(完整版)
Jul 05 #Javascript
结合代码图文讲解JavaScript中的作用域与作用域链
Jul 05 #Javascript
jQuery的Each比JS原生for循环性能慢很多的原因
Jul 05 #Javascript
Node.js实现文件上传
Jul 05 #Javascript
JavaScript数组方法大全(推荐)
Jul 05 #Javascript
JS与HTML结合使用marquee标签实现无缝滚动效果代码
Jul 05 #Javascript
js利用正则表达式检验输入内容是否为网址
Jul 05 #Javascript
You might like
zend framework配置操作数据库实例分析
2012/12/06 PHP
php中socket通信机制实例详解
2015/01/03 PHP
PHP实现移除数组中为空或为某值元素的方法
2017/01/07 PHP
php实现base64图片上传方式实例代码
2017/02/22 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
PHP7 新增常量
2021/03/09 PHP
JavaScript 创建对象和构造类实现代码
2009/07/30 Javascript
CodeMirror2 IE7/IE8 下面未知运行时错误的解决方法
2012/03/29 Javascript
为原生js Array增加each方法
2012/04/07 Javascript
使用jquery实现简单的ajax
2013/07/08 Javascript
Node.js实现简单聊天服务器
2014/06/20 Javascript
extjs_02_grid显示本地数据、显示跨域数据
2014/06/23 Javascript
js实现的简洁网页滑动tab菜单效果代码
2015/08/24 Javascript
使用do...while的方法输入一个月中所有的周日(实例代码)
2016/07/22 Javascript
详解jQuery停止动画——stop()方法的使用
2016/12/14 Javascript
Vue动态生成el-checkbox点击无法赋值的解决方法
2019/02/21 Javascript
typescript配置alias的详细步骤
2020/08/12 Javascript
[03:07]【DOTA2亚洲邀请赛】我们,梦开始的地方
2017/03/07 DOTA
Python实现将HTML转换成doc格式文件的方法示例
2017/11/20 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
python list删除元素时要注意的坑点分享
2018/04/18 Python
python钉钉机器人运维脚本监控实例
2019/02/20 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
2019/06/25 Python
pytorch实现CNN卷积神经网络
2020/02/19 Python
东方红海科技面试题软件测试方面
2012/02/08 面试题
四年的个人工作自我评价
2013/12/10 职场文书
高中军训广播稿
2014/01/14 职场文书
会计学专业学生的求职信范文
2014/01/27 职场文书
决心书范文
2014/03/11 职场文书
房地产活动策划方案
2014/05/14 职场文书
教师敬业奉献模范事迹材料
2014/05/18 职场文书
滴水洞导游词
2015/02/10 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书
MySQL 使用SQL语句修改表名的实现
2021/04/07 MySQL
html css3不拉伸图片显示效果
2021/06/07 HTML / CSS
Python os和os.path模块详情
2022/04/02 Python