最近公司项目中要用到这种类似环形进度条的效果,初始就从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%)效果 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
本文向大家介绍canvas实现环形进度条效果,包括了canvas实现环形进度条效果的使用技巧和注意事项,需要的朋友参考一下 昨下午睡着了,晚上打开手机才发现朋友给我发了一个QQ消息,问我这个怎么实现? 这里就选canvas来简单写一下 先上代码,然后在说一说需要注意的点: 接下来说一些注意点和我写的过程中碰到的疑问: 疑问: 01 整体代码没有封装成一个组件,感兴趣的同学可以封装一下。 我这有时间
本文向大家介绍Android实现环形进度条,包括了Android实现环形进度条的使用技巧和注意事项,需要的朋友参考一下 一个通俗易懂的环形进度条,可以定制颜色角度,监听进度。 定义一个attrs.xml 自定义CircleProgressView 代码就这么些,接下来我们测算一下 源码:下载地址 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
本文向大家介绍js实现增加数字显示的环形进度条效果,包括了js实现增加数字显示的环形进度条效果的使用技巧和注意事项,需要的朋友参考一下 效果如下: 代码如下: 以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持呐喊教程!
本文向大家介绍Android实现环形进度条的实例,包括了Android实现环形进度条的实例的使用技巧和注意事项,需要的朋友参考一下 Android实现环形进度条的效果图如下: 自定义控件:AttendanceProgressBar 代码如下: 因为是自定义控件,所以在attr.xml文件定义了一些控件属性,以便在xml文件中设置这些属性 代码如下: 最后,在xml文件中,可以这样使用 这只是初步处
介绍 圆环形的进度条组件,支持进度渐变动画。 引入 import { createApp } from 'vue'; import { Circle } from 'vant'; const app = createApp(); app.use(Circle); 代码演示 基础用法 rate 属性表示进度条的目标进度,v-model:current-rate 表示动画过程中的实时进度。当 ra
本文向大家介绍iOS快速实现环形渐变进度条,包括了iOS快速实现环形渐变进度条的使用技巧和注意事项,需要的朋友参考一下 前言 进度条相信我们大家都不陌生,往往我们很多时候需要使用到圆形进度条。这篇文章给大家分享了利用iOS如何快速实现环形进度条,下面来一起看看。 一:先制作一个不带颜色渐变的进度条 自定义一个cycleView,在.m 中实现drawRect方法 因为drawRect方法只是在视图