最近公司项目中要用到这种类似环形进度条的效果,初始就从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.0Author: Sudhanshu YadavCopyright (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 topvar circ = Math.PI * 2,quart = Math.PI / 2;//function to convert hex to rgbfunction 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 objectfunction 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 parameterfunction formatter(pattern) {return function (num) {if(!pattern) return num.toString();num = num || 0var numRev = num.toString().split('').reverse(),output = pattern.split("").reverse(),i = 0,lastHashReplaced = 0;//changes hash with numbersfor (var ln = output.length; i < ln; i++) {if (!numRev.length) break;if (output[i] == "#") {lastHashReplaced = i;output[i] = numRev.shift();}}//add overflowing numbers before prefixoutput.splice(lastHashReplaced+1, output.lastIndexOf('#') - lastHashReplaced, numRev.reverse().join(""));return output.reverse().join('');}}//circle bar classfunction Indicator(container, indOption) {indOption = indOption || {};indOption = merge({}, radialIndicator.defaults, indOption);this.indOption = indOption;//create a queryselector if a selector string is passed in containerif (typeof container == "string")container = document.querySelector(container);//get the first element if container is a node listif (container.length)container = container[0];this.container = container;//create a canvas elementvar canElm = document.createElement("canvas");container.appendChild(canElm);this.canElm = canElm; // dom object where drawing will happenthis.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 heightcenter = dim / 2; //center point in both x and y axis//create a formatter functionthis.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 circlectx.strokeStyle = indOption.barBgColor; //background circle colorctx.lineWidth = indOption.barWidth;ctx.beginPath();ctx.arc(center, center, indOption.radius, 0, 2 * Math.PI);ctx.stroke();//store the image data after grey circle drawthis.imgData = ctx.getImageData(0, 0, dim, dim);//put the initial value if definedthis.value(this.current_value);return this;},//update the value of indicator without animationvalue: function (val) {//return the val if val is not providedif (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 100val = val < minVal ? minVal : val > maxVal ? maxVal : val;var perVal = Math.round(((val - minVal) * 100 / (maxVal - minVal)) * 100) / 100, //percentage value tp two decimal precisiondispVal = indOption.percentage ? perVal + '%' : this.formatter(val); //formatted value//save val on objectthis.current_value = val;//draw the bg circlectx.putImageData(this.imgData, 0, 0);//get current color if color range is setif (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 valuectx.strokeStyle = curColor;//add linecap if value setted on optionsif (indOption.roundCorner) ctx.lineCap = "round";ctx.beginPath();ctx.arc(center, center, indOption.radius, -(quart), ((circ) * perVal / 100) - quart, false);ctx.stroke();//add percentage textif (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 valueanimate: 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 percentageback = val < counter;//clear interval function if already startedif (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 valueif (counter != val) {counter = counter + (back ? -incBy : incBy)}; //increment or decrement till counter does not reach to value}, indOption.frameTime);return this;},//method to update optionsoption: 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 defaultsradialIndicator.defaults = {radius: 50, //inner radius of indicatorbarWidth: 5, //bar widthbarBgColor: '#eeeeee', //unfilled bar colorbarColor: '#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 functionframeTime: 10, //miliseconds to move from one frame to anotherframeNum: null, //Defines numbers of frame in indicator, defaults to 100 when showing percentage and 500 for other valuesfontColor: null, //font colorfontFamily: null, //defines font familyfontWeight: 'bold', //defines font weightfontSize : null, //define the font size of indicator numberinterpolate: true, //interpolate color between rangespercentage: false, //show percentage of valuedisplayNumber: true, //display indicator numberroundCorner: false, //have round corner in filled barminValue: 0, //minimum valuemaxValue: 100, //maximum valueinitValue: 0 //define initial value of indicator};window.radialIndicator = radialIndicator;//add as a jquery pluginif ($) {$.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%)效果 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!
新闻热点
疑难解答