【问题标题】:Javascript canvas animation not appearingJavascript画布动画没有出现
【发布时间】:2019-04-28 11:21:50
【问题描述】:

我正在尝试使用 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);
}

【问题讨论】:

  • setTimeout(()=&gt;runAnimation(i),16);
  • 谢谢!正是这个问题。

标签: javascript html animation html5-canvas


【解决方案1】:

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

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

ctx.savectx.restore 可能是非常昂贵的调用,应尽可能避免。由于您只是恢复转换,您可以根据需要使用ctx.setTransform() 手动设置它

动画不需要重启,让它循环就好了。

示例根据以上几点和其他一些更改重写了您的代码。有关详细信息,请参阅代码 cmets。

// 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);
}
&lt;canvas id="animCanvas"&gt;&lt;/canvas&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多