zoukankan      html  css  js  c++  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: 50
    44             });
    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-fd])([a-fd])([a-fd])$/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-fd]{2})([a-fd]{2})([a-fd]{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 element
    104         var canElm = document.createElement("canvas");
    105         container.appendChild(canElm);
    106 
    107         this.canElm = canElm; // dom object where drawing will happen
    108 
    109         this.ctx = canElm.getContext('2d'); //get 2d canvas context
    110 
    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 height
    124                 center = dim / 2; //center point in both x and y axis
    125 
    126 
    127             //create a formatter function
    128             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 circle
    137             ctx.strokeStyle = indOption.barBgColor; //background circle color
    138             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 draw
    144             this.imgData = ctx.getImageData(0, 0, dim, dim);
    145 
    146             //put the initial value if defined
    147             this.value(this.current_value);
    148 
    149             return this;
    150         },
    151         //update the value of indicator without animation
    152         value: function (val) {
    153             //return the val if val is not provided
    154             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 100
    169             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 precision
    172                 dispVal = indOption.percentage ? perVal + '%' : this.formatter(val); //formatted value
    173 
    174             //save val on object
    175             this.current_value = val;
    176 
    177 
    178             //draw the bg circle
    179             ctx.putImageData(this.imgData, 0, 0);
    180 
    181             //get current color if color range is set
    182             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 value
    200             ctx.strokeStyle = curColor;
    201 
    202             //add linecap if value setted on options
    203             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 text
    210             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 value
    228         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 percentage
    234                 back = val < counter;
    235 
    236             //clear interval function if already started
    237             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 value
    251 
    252                 if (counter != val) {
    253                     counter = counter + (back ? -incBy : incBy)
    254                 }; //increment or decrement till counter does not reach  to value
    255             }, indOption.frameTime);
    256 
    257             return this;
    258         },
    259         //method to update options
    260         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 defaults
    280     radialIndicator.defaults = {
    281         radius: 50, //inner radius of indicator
    282         barWidth: 5, //bar width
    283         barBgColor: '#eeeeee', //unfilled bar color
    284         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 function
    286         frameTime: 10, //miliseconds to move from one frame to another
    287         frameNum: null, //Defines numbers of frame in indicator, defaults to 100 when showing percentage and 500 for other values
    288         fontColor: null, //font color
    289         fontFamily: null, //defines font family
    290         fontWeight: 'bold', //defines font weight
    291         fontSize : null, //define the font size of indicator number
    292         interpolate: true, //interpolate color between ranges
    293         percentage: false, //show percentage of value
    294         displayNumber: true, //display indicator number
    295         roundCorner: false, //have round corner in filled bar
    296         minValue: 0, //minimum value
    297         maxValue: 100, //maximum value
    298         initValue: 0 //define initial value of indicator
    299     };
    300     
    301     window.radialIndicator = radialIndicator;
    302 
    303     //add as a jquery plugin
    304     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));
  • 相关阅读:
    直接拿来用!最火的Android开源项目(二)
    直接拿来用!最火的Android开源项目(一)
    Android应用经典主界面框架之二:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)
    Android应用经典主界面框架之一:仿QQ (使用Fragment)
    Android Studio导入第三方类库的方法
    Socket编程总结—Android手机服务器与多个Android手机客户端之间的通信(非阻塞)
    Android 客户端与服务器交互方式
    消息模式Toast.makeText的几种常见用法
    在eclipse中将android项目生成apk并且给apk签名
    Android Studio 1.0.1 + Genymotion安卓模拟器打造高效安卓开发环境
  • 原文地址:https://www.cnblogs.com/sonicwater/p/5643627.html
Copyright © 2011-2022 走看看