你的位置:首页 > Java教程

[Java教程]环形进度条(从0到100%)效果


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

 

如图

 

代码如下

 

demo.html 

 1 <!doctype html> 2 <html lang="zh"> 3   <head> 4     <meta charset="UTF-8"> 5     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  6     <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7     <title>demo</title> 8     <style> 9       .rad-prg{10         position: relative;11       }12       .rad-con{13         position: absolute;14         z-index: 1;15         top:0;16         left: 0;17         text-align: center;18         width:90px;19         height: 90px;20         padding: 10px;21         font-family: "microsoft yahei";22       }23     </style>24   </head>25   <body>26     <div class="prg-cont rad-prg" id="indicatorContainer">27       <div class="rad-con">28         <p>¥4999</p>29         <p>账户总览</p>30       </div>31     </div>32     <script type="text/javascript" src="js/jquery.min.js"></script>33     <script src="js/radialIndicator.js"></script>34     <script>35 36       $('#indicatorContainer').radialIndicator({37         barColor: '#007aff',38         barWidth: 5,39         initValue: 0,40         roundCorner : true,41         percentage: true,42         displayNumber: false,43         radius: 5044       });45 46       setTimeout(function(){47         var radObj = $('#indicatorContainer2').data('radialIndicator');48         radObj.animate(100);49       },300);50       51     </script>52   </body>53 </html>

 

radialIndicator.js  这是jquery的插件

 1 /* 2   radialIndicator.js v 1.0.0 3   Author: Sudhanshu Yadav 4   Copyright (c) 2015 Sudhanshu Yadav - ignitersworld.com , released under the MIT license. 5   Demo on: ignitersworld.com/lab/radialIndicator.html 6 */ 7  8 ;(function ($, window, document) { 9   "use strict"; 10   //circumfence and quart value to start bar from top 11   var circ = Math.PI * 2, 12     quart = Math.PI / 2; 13  14   //function to convert hex to rgb 15  16   function hexToRgb(hex) { 17     // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") 18     var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; 19     hex = hex.replace(shorthandRegex, function (m, r, g, b) { 20       return r + r + g + g + b + b; 21     }); 22  23     var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); 24     return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : null; 25   } 26  27   function getPropVal(curShift, perShift, bottomRange, topRange) { 28     return Math.round(bottomRange + ((topRange - bottomRange) * curShift / perShift)); 29   } 30  31  32   //function to get current color in case of  33   function getCurrentColor(curPer, bottomVal, topVal, bottomColor, topColor) { 34     var rgbAryTop = topColor.indexOf('#') != -1 ? hexToRgb(topColor) : topColor.match(/\d+/g), 35       rgbAryBottom = bottomColor.indexOf('#') != -1 ? hexToRgb(bottomColor) : bottomColor.match(/\d+/g), 36       perShift = topVal - bottomVal, 37       curShift = curPer - bottomVal; 38  39     if (!rgbAryTop || !rgbAryBottom) return null; 40  41     return 'rgb(' + getPropVal(curShift, perShift, rgbAryBottom[0], rgbAryTop[0]) + ',' + getPropVal(curShift, perShift, rgbAryBottom[1], rgbAryTop[1]) + ',' + getPropVal(curShift, perShift, rgbAryBottom[2], rgbAryTop[2]) + ')'; 42   } 43  44   //to merge object 45   function merge() { 46     var arg = arguments, 47       target = arg[0]; 48     for (var i = 1, ln = arg.length; i < ln; i++) { 49       var obj = arg[i]; 50       for (var k in obj) { 51         if (obj.hasOwnProperty(k)) { 52           target[k] = obj[k]; 53         } 54       } 55     } 56     return target; 57   } 58  59   //function to apply formatting on number depending on parameter 60   function formatter(pattern) { 61     return function (num) { 62       if(!pattern) return num.toString(); 63       num = num || 0 64       var numRev = num.toString().split('').reverse(), 65         output = pattern.split("").reverse(), 66         i = 0, 67         lastHashReplaced = 0; 68  69       //changes hash with numbers 70       for (var ln = output.length; i < ln; i++) { 71         if (!numRev.length) break; 72         if (output[i] == "#") { 73           lastHashReplaced = i; 74           output[i] = numRev.shift(); 75         } 76       } 77  78       //add overflowing numbers before prefix 79       output.splice(lastHashReplaced+1, output.lastIndexOf('#') - lastHashReplaced, numRev.reverse().join("")); 80  81       return output.reverse().join(''); 82     } 83   } 84  85  86   //circle bar class 87   function Indicator(container, indOption) { 88     indOption = indOption || {}; 89     indOption = merge({}, radialIndicator.defaults, indOption); 90  91     this.indOption = indOption; 92  93     //create a queryselector if a selector string is passed in container 94     if (typeof container == "string") 95       container = document.querySelector(container); 96  97     //get the first element if container is a node list 98     if (container.length) 99       container = container[0];100 101     this.container = container;102 103     //create a canvas element104     var canElm = document.createElement("canvas");105     container.appendChild(canElm);106 107     this.canElm = canElm; // dom object where drawing will happen108 109     this.ctx = canElm.getContext('2d'); //get 2d canvas context110 111     //add intial value 112     this.current_value = indOption.initValue || indOption.minValue || 0;113 114   }115 116 117   Indicator.prototype = {118     constructor: radialIndicator,119     init: function () {120       var indOption = this.indOption,121         canElm = this.canElm,122         ctx = this.ctx,123         dim = (indOption.radius + indOption.barWidth) * 2, //elm width and height124         center = dim / 2; //center point in both x and y axis125 126 127       //create a formatter function128       this.formatter = typeof indOption.format == "function" ? indOption.format : formatter(indOption.format);129 130       //maximum text length;131       this.maxLength = indOption.percentage ? 4 : this.formatter(indOption.maxValue).length;132 133       canElm.width = dim;134       canElm.height = dim;135 136       //draw a grey circle137       ctx.strokeStyle = indOption.barBgColor; //background circle color138       ctx.lineWidth = indOption.barWidth;139       ctx.beginPath();140       ctx.arc(center, center, indOption.radius, 0, 2 * Math.PI);141       ctx.stroke();142 143       //store the image data after grey circle draw144       this.imgData = ctx.getImageData(0, 0, dim, dim);145 146       //put the initial value if defined147       this.value(this.current_value);148 149       return this;150     },151     //update the value of indicator without animation152     value: function (val) {153       //return the val if val is not provided154       if (val === undefined || isNaN(val)) {155         return this.current_value;156       }157 158       val = parseInt(val);159       160       var ctx = this.ctx,161         indOption = this.indOption,162         curColor = indOption.barColor,163         dim = (indOption.radius + indOption.barWidth) * 2,164         minVal = indOption.minValue,165         maxVal = indOption.maxValue,166         center = dim / 2;167 168       //limit the val in range of 0 to 100169       val = val < minVal ? minVal : val > maxVal ? maxVal : val;170 171       var perVal = Math.round(((val - minVal) * 100 / (maxVal - minVal)) * 100) / 100, //percentage value tp two decimal precision172         dispVal = indOption.percentage ? perVal + '%' : this.formatter(val); //formatted value173 174       //save val on object175       this.current_value = val;176 177 178       //draw the bg circle179       ctx.putImageData(this.imgData, 0, 0);180 181       //get current color if color range is set182       if (typeof curColor == "object") {183         var range = Object.keys(curColor);184 185         for (var i = 1, ln = range.length; i < ln; i++) {186           var bottomVal = range[i - 1],187             topVal = range[i],188             bottomColor = curColor[bottomVal],189             topColor = curColor[topVal],190             newColor = val == bottomVal ? bottomColor : val == topVal ? topColor : val > bottomVal && val < topVal ? indOption.interpolate ? getCurrentColor(val, bottomVal, topVal, bottomColor, topColor) : topColor : false;191 192           if (newColor != false) {193             curColor = newColor;194             break;195           }196         }197       }198 199       //draw th circle value200       ctx.strokeStyle = curColor;201 202       //add linecap if value setted on options203       if (indOption.roundCorner) ctx.lineCap = "round";204 205       ctx.beginPath();206       ctx.arc(center, center, indOption.radius, -(quart), ((circ) * perVal / 100) - quart, false);207       ctx.stroke();208 209       //add percentage text210       if (indOption.displayNumber) {211         var cFont = ctx.font.split(' '),212           weight = indOption.fontWeight,213           fontSize = indOption.fontSize || (dim / (this.maxLength - (Math.floor(this.maxLength*1.4/4)-1)));214 215         cFont = indOption.fontFamily || cFont[cFont.length - 1];216 217 218         ctx.fillStyle = indOption.fontColor || curColor;219         ctx.font = weight +" "+ fontSize + "px " + cFont;220         ctx.textAlign = "center";221         ctx.textBaseline = 'middle';222         ctx.fillText(dispVal, center, center);223       }224 225       return this;226     },227     //animate progressbar to the value228     animate: function (val) {229 230       var indOption = this.indOption,231         counter = this.current_value || indOption.minValue,232         self = this,233         incBy = Math.ceil((indOption.maxValue - indOption.minValue) / (indOption.frameNum || (indOption.percentage ? 100 : 500))), //increment by .2% on every tick and 1% if showing as percentage234         back = val < counter;235 236       //clear interval function if already started237       if (this.intvFunc) clearInterval(this.intvFunc); 238 239       this.intvFunc = setInterval(function () {240 241         if ((!back && counter >= val) || (back && counter <= val)) {242           if (self.current_value == counter) {243             clearInterval(self.intvFunc);244             return;245           } else {246             counter = val;247           }248         }249 250         self.value(counter); //dispaly the value251 252         if (counter != val) {253           counter = counter + (back ? -incBy : incBy)254         }; //increment or decrement till counter does not reach to value255       }, indOption.frameTime);256 257       return this;258     },259     //method to update options260     option: function (key, val) {261       if (val === undefined) return this.option[key];262 263       if (['radius', 'barWidth', 'barBgColor', 'format', 'maxValue', 'percentage'].indexOf(key) != -1) {264         this.indOption[key] = val;265         this.init().value(this.current_value);266       }267       this.indOption[key] = val;268     }269 270   };271 272   /** Initializer function **/273   function radialIndicator(container, options) {274     var progObj = new Indicator(container, options);275     progObj.init();276     return progObj;277   }278 279   //radial indicator defaults280   radialIndicator.defaults = {281     radius: 50, //inner radius of indicator282     barWidth: 5, //bar width283     barBgColor: '#eeeeee', //unfilled bar color284     barColor: '#99CC33', //filled bar color , can be a range also having different colors on different value like {0 : "#ccc", 50 : '#333', 100: '#000'}285     format: null, //format indicator numbers, can be a # formator ex (##,###.##) or a function286     frameTime: 10, //miliseconds to move from one frame to another287     frameNum: null, //Defines numbers of frame in indicator, defaults to 100 when showing percentage and 500 for other values288     fontColor: null, //font color289     fontFamily: null, //defines font family290     fontWeight: 'bold', //defines font weight291     fontSize : null, //define the font size of indicator number292     interpolate: true, //interpolate color between ranges293     percentage: false, //show percentage of value294     displayNumber: true, //display indicator number295     roundCorner: false, //have round corner in filled bar296     minValue: 0, //minimum value297     maxValue: 100, //maximum value298     initValue: 0 //define initial value of indicator299   };300   301   window.radialIndicator = radialIndicator;302 303   //add as a jquery plugin304   if ($) {305     $.fn.radialIndicator = function (options) {306       return this.each(function () {307         var newPCObj = radialIndicator(this, options);308         $.data(this, 'radialIndicator', newPCObj);309       });310     };311   }312 313 }(window.jQuery, window, document, void 0));