绘制和重绘图像以模拟动画不起作用

时间:2015-03-03 18:51:49

标签: javascript html5 animation html5-canvas

我有一个简单的动画,显示燃气表从绿色变为红色。我只是绘制,清除然后重新绘制计时器上的图像以尝试和模拟动画。虽然它很有效,但动画有所滞后,有时只是在应该完成后才会前后移动。

下面是代码:

function meter(){
        requestAnimationFrame(meter);

        setTimeout(function() {

        var radius = 40;
        ctx.clearRect(500, 200, 100, 100);
        ctx.beginPath();
        ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
        ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
        ctx.fill();
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#000000';
        ctx.stroke();

        ctx.fillStyle = "#ffcc4a";
        ctx.fillRect(525, 220, 50, 60);
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(528, 225, 44, 45);


        var grd = ctx.createLinearGradient(510, 0, 670, 0);
        grd.addColorStop(0, "black");
        grd.addColorStop(0.25, "yellow");
        grd.addColorStop(0.5, "red");
        ctx.fillStyle = grd;
        ctx.fillRect(530, 228, 40, 30);

            ctx.beginPath();
            ctx.fillStyle = "#000000";
            ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
            ctx.moveTo(549, 260);
            ctx.lineTo(548, 240);
            ctx.fill();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#000000';
            ctx.stroke();
            ctx.closePath();


        ctx.closePath();
        //ctx.clearRect(500, 200, 100, 100);    

            }, 2000);

            setTimeout(function() {

        var radius = 40;
        ctx.clearRect(500, 200, 100, 100);
        ctx.beginPath();
        ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
        ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
        ctx.fill();
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#000000';
        ctx.stroke();

        ctx.fillStyle = "#ffcc4a";
        ctx.fillRect(525, 220, 50, 60);
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(528, 225, 44, 45);


        var grd = ctx.createLinearGradient(510, 0, 670, 0);
        grd.addColorStop(0, "black");
        grd.addColorStop(0.25, "yellow");
        grd.addColorStop(0.5, "red");
        ctx.fillStyle = grd;
        ctx.fillRect(530, 228, 40, 30);

            ctx.beginPath();
            ctx.fillStyle = "#000000";
            ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
            ctx.moveTo(549, 260);
            ctx.lineTo(558, 240);
            ctx.fill();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#000000';
            ctx.stroke();
            ctx.closePath();


        ctx.closePath();
        //ctx.clearRect(500, 200, 100, 100);    

            }, 2500);

            setTimeout(function() {

        var radius = 40;
        ctx.clearRect(500, 200, 100, 100);
        ctx.beginPath();
        ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
        ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
        ctx.fill();
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#000000';
        ctx.stroke();

        ctx.fillStyle = "#ffcc4a";
        ctx.fillRect(525, 220, 50, 60);
        ctx.fillStyle = "#ffffff";
        ctx.fillRect(528, 225, 44, 45);


        var grd = ctx.createLinearGradient(510, 0, 670, 0);
        grd.addColorStop(0, "black");
        grd.addColorStop(0.25, "yellow");
        grd.addColorStop(0.5, "red");
        ctx.fillStyle = grd;
        ctx.fillRect(530, 228, 40, 30);

            ctx.beginPath();
            ctx.fillStyle = "#000000";
            ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
            ctx.moveTo(549, 260);
            ctx.lineTo(568, 240);
            ctx.fill();
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#000000';
            ctx.stroke();
            ctx.closePath();


        ctx.closePath();
        //ctx.clearRect(500, 200, 100, 100);    

            }, 3000);   



    }

1 个答案:

答案 0 :(得分:1)

在我看来,你有足够的时间来调用requestAnimationFrame函数很多次,而第一个setTimeout函数正在等待触发和绘制东西。这意味着你可能最终会在第一个触发计时器之前几次启动setTimeout计时器。

这基本上就是你所拥有的:

function meter(){
    requestAnimationFrame(meter);

    setTimeout(function() {
        //drawing stuff
    }, 2000);

    setTimeout(function() {
        //drawing stuff
    }, 2500);

    setTimeout(function() {
        //drawing stuff
    }, 3000);   
}

你用一个小小的改变画三次同样的东西。相反,使用参数将其变为1函数:

function meter(indicatorPosition){
    //black circle
    var radius = 40;
    ctx.clearRect(500, 200, 100, 100);
    ctx.beginPath();
    ctx.arc(550, 250, radius, 0, 2 * Math.PI, false);
    ctx.fillStyle = 'rgba(192, 192, 192, 0.4)';
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#000000';
    ctx.stroke();

    //yellow rectangle
    ctx.fillStyle = "#ffcc4a";
    ctx.fillRect(525, 220, 50, 60);
    //white rectangle over yellow
    ctx.fillStyle = "#ffffff";
    ctx.fillRect(528, 225, 44, 45);

    //meter gradient background
    var grd = ctx.createLinearGradient(510, 0, 670, 0);
    grd.addColorStop(0, "black");
    grd.addColorStop(0.25, "yellow");
    grd.addColorStop(0.5, "red");
    ctx.fillStyle = grd;
    ctx.fillRect(530, 228, 40, 30);

    //circle and indicator
    ctx.beginPath();
    ctx.fillStyle = "#000000";
    ctx.arc(550, 264, 5, 0, 2 * Math.PI, false);
    ctx.moveTo(549, 260);
    ctx.lineTo(indicatorPosition, 240); //this is the only variable!
    ctx.fill();
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#000000';
    ctx.stroke();
    ctx.closePath();
}

现在让它移动:

如果你想让它每0.5秒移动一次,最好使用setInterval。

var meterPosition = 548 //your starting position
var myInterval = setInterval(function() {
    //each run we draw the meter
    meter(meterPosition);
    //Then we want to add 10 to the meter position
    meterPosition+=10;
    //We don't want the meter to go nuts and disappear to the right, so we'll make it reset after 3 moves
    if (meterPosition > 568) {
        meterPosition = 548;
    }
},500);

以下是行动中代码的小提琴:http://jsfiddle.net/Niddro/7jxknwk4/