JS实现环形进度条(从0到100%)效果
来源: 阅读:3533 次 日期:2016-07-26 14:15:37
温馨提示: 小编为您整理了“JS实现环形进度条(从0到100%)效果”,方便广大网友查阅!

这篇文章主要介绍了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%)效果 ,希望对大家有所帮助

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map