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 相关文章推荐
js压缩利器
Feb 20 Javascript
javascript js cookie的存储,获取和删除
Dec 29 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
Apr 18 Javascript
在子窗口中关闭父窗口的一句代码
Oct 21 Javascript
简单的邮箱登陆的提示效果类似于yahoo邮箱
Feb 26 Javascript
给html超链接设置事件不使用href来完成跳
Apr 20 Javascript
JQuery设置获取下拉菜单某个选项的值(比较全)
Aug 05 Javascript
表单中单选框添加选项和移除选项
Jul 04 Javascript
JavaScript简单实现合并两个Json对象的方法示例
Oct 16 Javascript
微信小程序App生命周期详解
Jan 31 Javascript
vue 路由子组件created和mounted不起作用的解决方法
Nov 05 Javascript
Element实现动态表格的示例代码
Aug 02 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
英雄试炼之肉山谷—引领RPG新潮流
2020/04/20 DOTA
PHILIPS AE3805收音机的分析打磨
2021/03/02 无线电
php字符串截取中文截取2,单字节截取模式
2007/12/10 PHP
php google或baidu分页代码
2009/11/26 PHP
浅谈php+phpStorm+xdebug配置方法
2015/09/17 PHP
php使用ZipArchive函数实现文件的压缩与解压缩
2015/10/27 PHP
php英文单词统计器
2016/06/23 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
extjs fckeditor集成代码
2009/05/10 Javascript
JQuery入门—编写一个简单的JQuery应用案例
2013/01/03 Javascript
JQuery 在文档中查找指定name的元素并移除的实现方法
2016/05/19 Javascript
webpack中引用jquery的简单实现
2016/06/08 Javascript
原生nodejs使用websocket代码分享
2018/04/07 NodeJs
Vue Cli3 创建项目的方法步骤
2018/10/15 Javascript
vue-cli的build的文件夹下没有dev-server.js文件配置mock数据的方法
2019/04/17 Javascript
vue登录以及权限验证相关的实现
2019/10/25 Javascript
Python模拟登录验证码(代码简单)
2016/02/06 Python
Python 3.6 读取并操作文件内容的实例
2018/04/23 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
浅析Windows 嵌入python解释器的过程
2019/07/26 Python
Django之全局使用request.user.username的实例详解
2020/05/14 Python
keras自定义回调函数查看训练的loss和accuracy方式
2020/05/23 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
解决redis与Python交互取出来的是bytes类型的问题
2020/07/16 Python
HTML中fieldset标签概述及使用方法
2013/02/01 HTML / CSS
浅谈基于HTML5的在线视频播放方案
2016/02/18 HTML / CSS
美国玩具公司:U.S.Toy
2018/05/19 全球购物
《争吵》教学反思
2014/02/15 职场文书
三八妇女节演讲稿
2014/05/27 职场文书
大学教师师德师风演讲稿
2014/08/22 职场文书
小学四年级学生评语
2014/12/26 职场文书
2015年试用期自我评价范文
2015/03/10 职场文书
学校会议通知范文
2015/04/15 职场文书
导游词之台湾阿里山
2019/10/23 职场文书
nginx处理http请求实现过程解析
2021/03/31 Servers
matlab xlabel位置的设置方式
2021/05/21 Python