进度栏动画

时间:2014-09-08 16:09:51

标签: javascript jquery html html5 canvas

我想创建一个进度条,它遵循我的jquery示例中概述的代码路径:

Jsfiddle:http://jsfiddle.net/42a7s5nt/13/

context.beginPath();
context.moveTo(85, 161);
context.lineTo(245, 161);
context.quadraticCurveTo(310, 145, 310, 90);
context.quadraticCurveTo(300,20,230,20);
context.lineTo(85, 20);
context.quadraticCurveTo(20,34,20,90);
context.quadraticCurveTo(35,160,85,160);
context.lineWidth = 30;
context.strokeStyle = '#db1e33';
context.stroke();

我如何将此栏设置为百分比/进度条的动画?它从左下方开始呈红色,并以逆时针方向工作。我已经看到了各种示例,但我无法实现它们,因为它们基于使用pi或直线的径向示例。

我基本上想要根据百分比设置绘制路径的动画。

对此的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

@GameAlchemist有一个很好的简化想法,在每一侧使用半圆而不是Q曲线。这是因为圆的圆周很容易计算:2 * PI *半径。 Q曲线的周长更难以计算:绘制曲线上的100+点并测量这些点所覆盖的总距离。

反过来,您可以轻松计算路径的总长度。如果您希望从0%到100%时均匀显示进度条,则总长度至关重要。

想法是尽可能多地显示2行和2个半圆来表示完成百分比。

enter image description here enter image description here

示例代码和演示:http://jsfiddle.net/m1erickson/qbapv8ws/

// calculate the total path length
var PI=Math.PI;
var radius=50;
var circumference=2*PI*radius;
var lineLeft=100;
var lineRight=200;
var lineWidth=lineRight-lineLeft;
var totalLength=circumference+lineWidth*2;

然后,您可以使用这些计算加上百分比完成来绘制进度条:

var lineTop=100;
var lineBottom=lineTop+radius*2;
var lineVertMiddle=(lineTop+lineBottom)/2;


function draw(pct){
    var pctLength=totalLength*pct;

    // draw complete path in red
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.strokeStyle='red';
    ctx.beginPath();
    ctx.moveTo(lineLeft,lineBottom);
    ctx.lineTo(lineRight,lineBottom);
    ctx.arc(lineRight,lineVertMiddle,radius,PI/2,-PI/2,true);
    ctx.lineTo(lineLeft,lineTop);
    ctx.arc(lineLeft,lineVertMiddle,radius,PI*3/2,PI/2,true);
    ctx.stroke();

    // draw percent path in green
    ctx.strokeStyle='green';
    ctx.beginPath();
    ctx.moveTo(lineLeft,lineBottom);

    // bottom line counterclockwise
    if(pctLength>0){
        var x=Math.min(pctLength,lineWidth);
        ctx.lineTo(lineLeft+x,lineBottom);
        pctLength-=x;
    }
    // right arc
    if(pctLength>0){
        var sweepAngle=Math.min(PI,PI*pctLength/(circumference/2));
        ctx.arc(lineRight,lineVertMiddle,radius,PI/2,PI/2-sweepAngle,true);
        pctLength-=Math.min(pctLength,circumference/2);
    }
    // top line
    if(pctLength>0){
        var x=Math.min(pctLength,lineWidth);
        ctx.lineTo(lineRight-x,lineTop);
        pctLength-=x;
    }
    // left arc
    if(pctLength>0){
        var sweepAngle=Math.min(PI,PI*pctLength/(circumference/2));
        ctx.arc(lineLeft,lineVertMiddle,radius,PI*3/2,PI*3/2-sweepAngle,true);
    }   

    ctx.stroke();
}