JS實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果
來(lái)源:易賢網(wǎng) 閱讀:3646 次 日期:2016-07-26 14:15:37
溫馨提示:易賢網(wǎng)小編為您整理了“JS實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果”,方便廣大網(wǎng)友查閱!

這篇文章主要介紹了JS實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

最近公司項(xiàng)目中要用到這種類似環(huán)形進(jìn)度條的效果,初始就從0開始動(dòng)畫到100%結(jié)束。動(dòng)畫結(jié)果始終會(huì)停留在100%上,并不會(huì)到因?yàn)閿?shù)據(jù)的關(guān)系停留在一半。

如圖

名單

代碼如下:

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實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果 ,希望對(duì)大家有所幫助

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機(jī)網(wǎng)站地址:JS實(shí)現(xiàn)環(huán)形進(jìn)度條(從0到100%)效果
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!

2025國(guó)考·省考課程試聽報(bào)名

  • 報(bào)班類型
  • 姓名
  • 手機(jī)號(hào)
  • 驗(yàn)證碼
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 新媒體/短視頻平臺(tái) | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)