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

最近公司项目中要用到这种类似环形进度条的效果,初始就从0开始动画到100%结束。动画结果始终会停留在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%)效果 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • PHP中使用Session配合Javascript实现文件上传进度条功能

    Web应用中常需要提供文件上传的功能.典型的场景包括用户头像上传.相册图片上传等.当需要上传的文件比较大的时候,提供一个显示上传进度的进度条就很有必要了. 在PHP 5.4以前,实现这样的进度条并不容易,主要有三种方法: 1.使用Flash, Java, ActiveX 2.使用PHP的APC扩展 3.使用HTML5的File API 第一种方法依赖第三方的浏览器插件,通用性不足,且易带来安全隐患.不过由于Flash的使用比较广泛,因此还是有很多网站使用Flash作为解决方案. 第二种方法的不足

  • 利用js编写网页进度条效果

    一.基本思路 为了让我们编写的网页进度条满足现有需求,又足够轻便,所以使用原生js写一个构造函数,为了见名知义,可以把该函数命名为"Loading".该函数接收2个参数,分别为arr.callback.其中arr定义图片数组,callback定义执行完成后回调函数.该构造函数内部,遍历图片数组加载图片,每加载完一张图片,修改进度条进度,直至全部加载完成,进度条进度为100%. 二.实现步骤 (1)先搭建好进度条的样子,把html和css写好. 写完后预览一下进度条的效果 (2)编写Lo

  • JavaScript实现网页加载进度条代码超简单

    网页进度条能够更好的反应当前网页的加载进度情况,loading进度条可用动画的形式从开始0%到100%完成网页加载这一过程.但是目前的浏览器并没有提供页面加载进度方面的接口,也就是说页面还无法准确返回页面实际加载的进度,本文中我们使用jQuery来实现页面加载进度条效果. HTML 首先我们要知道的是,目前没有任何浏览器可以直接获取正在加载对象的大小.所以我们无法通过数据大小来实现0-100%的加载显示过程. 因此我们需要通过html代码逐行加载的特性,在整页代码的若干个跳跃行数中设置节点,进行

  • 用CSS+JS实现的进度条效果效果

    进度条,就是在用户进入你的网站的时候,能让用户看到网页下载了多少,这个的作用非常明显---就是让用户的等待时间变长,可以有效的弥补空间慢的缺点(当然,你空间太慢,还是建议你换下空间,呵呵) 好了,现在我先来举两个例子 一个是用FLASH实现的 (这个网上很多网站都是,不说了) 一个是用动态的GIF实现的 (这个你可以看微软官方的下载页面,也不说了) 这里,我们的重点是用 CSS+JS 实现这个效果 好了,废话不多说,我们开始 首先,写一段HTML代码 <div id="loading&qu

  • JS 进度条效果实现代码整理

    第一种方法:Loading.js 复制代码 代码如下: //频率 var frequency = 50; //步长 var step = 3; //背景颜色 var loadingBgcolor = "#ffffff"; //宽度 var loadingWidth = 354; /* *参数说明: *content:显示内容,可以为空: *imageURL:将引用JS文件的路径设置即可: *left:进度条显示位置left *top:进度条显示位置top */ function Loa

  • javascript 进度条的几种方法

    我们先看看最终效果: 第一步,基本 构建基本的代码,看效果演示: 制作进度条的两种方法 *{ margin:0; padding:0; } body{font-size:12px;}h1{font-size:15px;} .wrap{ font-size: 12px; margin:40px auto; width:400px; } /*进度条样式*/ .progressbar_1{ background-color:#eee; height:16px; width:150px; border:

  • js实现进度条的方法

    本文实例讲述了js实现进度条的方法.分享给大家供大家参考.具体实现方法如下: 1.setTimeout和clearTimeout <html> <head> <title>进度条</title> <style type="text/css"> .container{ width:450px; border:1px solid #6C9C2C; height:25px; } #bar{ background:#95CA0D; f

  • Javascript jquery css 写的简单进度条控件

    通过我们伟大的 CSS,可以实现非常漂亮的进度条样式.加上 Javascript 的效果,就可以完全"欺骗"我们的用户,让他们有耐心等待浏览器处理完成.上述的原理已经知道了,那么就可以直接看代码了.本人使用的还是 jQuery 框架,因为这样简短的代码可能会更容易理解. 当然这个控件还有很多需要完成的地方,我仅仅是提供了一种遵循 Web 标准的实现思路.废话不多说. Javascript Progress Bar Demo - jb51.net #progress {backgroun

  • Extjs实现进度条的两种便捷方式

    做Extjs开发中,往往后台程序可能要执行一段时间才能得到返回结果,加入进度条可以提高客户体验度,以下为两种便捷的方式: 1.提交数据前用Ext.Msg.wait('提示','正在处理数据,请稍候');弹出等待条,数据处理成功后用Ext.Msg.hide();将等待去掉,例如: Ext.Msg.wait('提示','正在处理数据,请稍候'); 复制代码 代码如下: Ext.Ajax.request({ url:'DataAction.ashx?method=update', params:{It

  • js 进度条实现代码

    进度条 body{ text-align:center; } .graph{ width:450px; border:1px solid #F8B3D0; height:25px; } #bar{ display:block; background:#FFE7F4; float:left; height:100%; text-align:center; } #barNum{ position:absolute; } function $(obj){ return document.getElem

随机推荐