画布:多个径向进度条

时间:2014-09-19 12:10:36

标签: javascript canvas progress-bar radial

我有一点问题,我用canvas和js制作了3个径向进度条(或多或少遵循codeplayer.com上的指南)。

结果几乎是好的,并且它正在工作,问题是如果我有多个条形,则最后一条从第一条中获取百分比。在我的例子中,第一个是65%,最后一个应该是88%,但它从第一个开始采用数据属性。

这是代码

使用Javascript:

window.onload = function(){

var canvas = document.getElementsByTagName('canvas');

for (var i = 0; i < canvas.length; i++) {
    progressBar(canvas[i].id);
}

// load the canvas
function progressBar(canvasId) {
    var canvas = document.getElementById(canvasId);
    var ctx = canvas.getContext('2d');

    // declare some variables
    var cWidth = canvas.width;
    var cHeight = canvas.height;
    var progressColor = 'lightblue';
    var circleColor = '#333';
    var rawPerc = canvas.getAttribute('data-perc');
    var definition = canvas.getAttribute('data-text');
    var perc = parseInt(rawPerc);
    var degrees = 0;
    var endDegrees = (360*perc)/100;

    var lineWidth = 10; // The 'brush' size

    console.log(canvasId+' '+perc);

    function getDegrees() {
        if(degrees < endDegrees) {
            degrees++;
        }
        else {
            clearInterval(degreesCall);
       }

    drawProgressBar();
}

function drawProgressBar() {
   //clear the canvas after every instance
   ctx.clearRect(0,0,cWidth,cHeight);

   // let's draw the background circle
   ctx.beginPath();
   ctx.strokeStyle = circleColor;
   ctx.lineWidth = lineWidth -1;
   ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0, Math.PI*2, false);
   ctx.stroke();
   var radians = 0; // We need to convert the degrees to radians

   radians = degrees * Math.PI/180;
   // let's draw the actual progressBar
   ctx.beginPath();
   ctx.strokeStyle = progressColor;
   ctx.lineWidth = lineWidth;
   ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
   ctx.stroke();

   // let's get the text
  ctx.fillStyle = progressColor;
  ctx.font = '20px Arial';
  var outputTextPerc = Math.floor(degrees/360*100)+'%';
  var outputTextPercWidth = ctx.measureText(outputTextPerc).width;
  var outputTextDefinitionWidth = ctx.measureText(definition).width;
  ctx.fillText(outputTextPerc, cWidth/2 - outputTextPercWidth/2, cHeight/2 - 10);
  ctx.fillText(definition, cWidth/2 - outputTextDefinitionWidth/2, cHeight/2 + 15);
}

degreesCall = setInterval(getDegrees, 10/(degrees - endDegrees));
}
}

(抱歉坏账)

HTML:

<canvas id="canvas-3" width="300" height="300" data-text="Radial 1" data-perc="65"></canvas>
<canvas id="canvas-4" width="300" height="300" data-text="Radial 2" data-perc="90"></canvas>
<canvas id="canvas-1" width="450" height="450" data-text="Radial 3" data-perc="88"></canvas>

我在http://jsfiddle.net/ranqgnr8/做了一个工作的jsfiddle。

知道为什么它会占第一百分比?

感谢所有正在阅读的人。

编辑:

奇怪的是,在控制台日志中,百分比是正确的。

1 个答案:

答案 0 :(得分:0)

您忘记定义degreesCall变量,因此它最终会在全局空间中覆盖相同的间隔

var canvas = document.getElementsByTagName('canvas');

for (var i = 0; i < canvas.length; i++) {
    progressBar(canvas[i].id);
}

// load the canvas
function progressBar(canvasId) {
    var degreesCall;        
    
    var canvas = document.getElementById(canvasId);
    var ctx = canvas.getContext('2d');

    // declare some variables
    var cWidth = canvas.width;
    var cHeight = canvas.height;
    var progressColor = 'lightblue';
    var circleColor = '#333';
    var rawPerc = canvas.getAttribute('data-perc');
    var definition = canvas.getAttribute('data-text');
    var perc = parseInt(rawPerc);
    var degrees = 0;
    var endDegrees = (360*perc)/100;
    
    var lineWidth = 10; // The 'brush' size

    console.log(canvasId+' '+perc);

    function getDegrees() {
        if(degrees < endDegrees) {
            degrees++;
        }
        else {
            clearInterval(degreesCall);
        }

        drawProgressBar();
    }

    function drawProgressBar() {
        //clear the canvas after every instance
        ctx.clearRect(0,0,cWidth,cHeight);

        // let's draw the background circle
        ctx.beginPath();
        ctx.strokeStyle = circleColor;
        ctx.lineWidth = lineWidth -1;
        ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0, Math.PI*2, false);
        ctx.stroke();
        var radians = 0; // We need to convert the degrees to radians

        radians = degrees * Math.PI/180;
        // let's draw the actual progressBar
        ctx.beginPath();
        ctx.strokeStyle = progressColor;
        ctx.lineWidth = lineWidth;
        ctx.arc(cHeight/2, cWidth/2, cWidth/3, 0 - 90*Math.PI/180, radians - 90*Math.PI/180, false);
        ctx.stroke();

        // let's get the text
        ctx.fillStyle = progressColor;
        ctx.font = '20px Arial';
        var outputTextPerc = Math.floor(degrees/360*100)+'%';
        var outputTextPercWidth = ctx.measureText(outputTextPerc).width;
        var outputTextDefinitionWidth = ctx.measureText(definition).width;
        ctx.fillText(outputTextPerc, cWidth/2 - outputTextPercWidth/2, cHeight/2 - 10);
        ctx.fillText(definition, cWidth/2 - outputTextDefinitionWidth/2, cHeight/2 + 15);
    }

    degreesCall = setInterval(getDegrees, 10/(degrees - endDegrees));
}
body {
	padding-top: 100px;
	background: #555;
}

canvas {
	display: inline-block;
	margin: auto;
}
<canvas id="canvas-3" width="300" height="300" data-text="Radial 1" data-perc="65"></canvas>
<canvas id="canvas-4" width="300" height="300" data-text="Radial 2" data-perc="90"></canvas>
<canvas id="canvas-1" width="450" height="450" data-text="Radial 3" data-perc="88"></canvas>