Javascript画布动画未出现

时间:2018-11-26 19:04:07

标签: javascript html animation html5-canvas

我正在尝试创建一个具有2个对象的画布动画:一个圆周和一个实心圆。我的目标是使圆周看起来代表圆轨道。但是,当尝试设置动画时,没有动画,只有当我单击以停止页面时,图像才会以圆圈在轨道中的随机位置出现(这意味着运动部件起作用)。 谢谢您的宝贵时间,代码如下:

function restartAnimate(){
    runAnimation(0);
    setTimeout(restartAnimate(),1000);
}

function runAnimation(i){
    let animation = document.getElementById("Animation");
    let anim = animation.getContext("2d");
    anim.clearRect(0,0,300,150);
    anim.save();

    anim.strokeStyle = "#99ebff";
    anim.lineWidth = 10;
    anim.beginPath();
    anim.arc(150, 75, 40, 0, 2 * Math.PI);
    anim.stroke();

    anim.restore();
    anim.save()
    anim.fillStyle = "#000000";
    anim.translate(150,75);
    anim.rotate(2 * Math.PI * i / 1000);
    anim.translate(-150,-75);
    anim.beginPath();
    anim.arc(150 + 36.5, 75 ,13, 0, 2 * Math.PI);
    anim.fill();

    anim.restore();

    i += 16;
    if(i < 1000) setTimeout(runAnimation(i),16);
}

1 个答案:

答案 0 :(得分:1)

您应使用requestAnimationFrame进行动画处理,以使渲染结果与显示硬件刷新同步显示。

setTimeout非常不准确,随着时间的流逝,您的功能将会落后。如果您使用requestAnimationFrame,则可以使用第一个参数(以毫秒为单位的时间)来精确地保持时间。

ctx.savectx.restore可能是非常昂贵的通话,应尽可能避免。由于仅还原转换,因此可以根据需要使用ctx.setTransform()

手动进行设置

无需重新启动动画,只需让其循环即可。

示例重写代码时要牢记以上几点和其他一些更改。有关更多信息,请参见代码注释。

// Define constants and query DOM outside animation functions
const canvas = document.getElementById("animCanvas");
const ctx = canvas.getContext("2d");
Math.PI2 = Math.PI * 2; 
var startTime;

restartAnimate();

function restartAnimate() {
    if (startTime === undefined) {
        requestAnimationFrame(runAnimation);
    } else {
        startTime = 0;  // next frame animation we have restarted
    }
    // setTimeout(restartAnimate(),1000); // No need to restart as angle is cyclic.
}

function runAnimation(time) {
    if (!startTime) { startTime = time }
    const currentTime = time - startTime;
    ctx.setTransform(1,0,0,1,0,0); // resets transform, better than using save and restore
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); // avoid magic numbers
    //ctx.save(); // not needed

    ctx.setTransform(1,0,0,1,150, 75); // last two values set the origin
                                       // and is the point we rotate around
    ctx.strokeStyle = "#99ebff";
    ctx.lineWidth = 10;
    ctx.beginPath();
    ctx.arc(0, 0, 40, 0, Math.PI2);  // rendering at the origin
    ctx.stroke();

    //ctx.restore(); // not needed
    //ctx.save();  // not needed
    ctx.fillStyle = "#000000";
    //ctx.translate(150,75);   // working from origin so don't need to translate
    ctx.rotate(Math.PI2 * currentTime / 1000);
    //ctx.translate(-150,-75); // working from origin so don't need to translate
    ctx.beginPath();
    ctx.arc(36.5, 0 ,13, 0, Math.PI2);
    ctx.fill();

    //ctx.restore(); not needed

    requestAnimationFrame(runAnimation);
}
<canvas id="animCanvas"></canvas>