HTML5画布绘图图像断断续续/断断续续

HTML5画布绘图图像断断续续/断断续续,html,animation,canvas,drawimage,Html,Animation,Canvas,Drawimage,问题 我试图让画布上的图像从左到右平滑移动。在Chrome/Safari上还不错(仍然有点口吃),但在多台机器上(在Windows和Mac上试用过)的Firefox中有明显的口吃。我对如何解决这个问题有点困惑 我尝试的 我使用requestAnimationFrame而不是setTimeout。我使用clearRect而不是设置画布宽度,尽管我正在清除整个画布而不是最小边界框,因为我想在最坏的情况下测试它。我确实关闭了额外的标签。我甚至禁用了Firebug。我使用的是drawImage,而不是图

问题

我试图让画布上的图像从左到右平滑移动。在Chrome/Safari上还不错(仍然有点口吃),但在多台机器上(在Windows和Mac上试用过)的Firefox中有明显的口吃。我对如何解决这个问题有点困惑

我尝试的

我使用requestAnimationFrame而不是setTimeout。我使用clearRect而不是设置画布宽度,尽管我正在清除整个画布而不是最小边界框,因为我想在最坏的情况下测试它。我确实关闭了额外的标签。我甚至禁用了Firebug。我使用的是drawImage,而不是图像数据函数。因为除了clearRect和drawImage,我什么都不做,所以我避免使用屏幕外的画布

示例1:

这一个有一个设定的帧速率,它可以确保位置是正确的,无论游戏循环运行的频率如何。它显示跳过的帧数。这个例子更接近我的目标。请注意,即使没有跳过任何帧,它也会呈现起伏。我也尝试过帧速率,但没有成功,尽管我希望达到30 fps(var framerate=33;)

示例2:

这里有一个简单的例子,它所做的只是移动图像。这让我在多台机器上口吃

//loop
function loop() {
    //request anim frame
    requestAnimationFrame(loop);

    //set canvas once able
    if (!canvas) {
        var temp = document.getElementById("testCanvas");
        if (temp) {
            canvas = temp;
            ctx = canvas.getContext('2d');
        }
    }

    //update and render if able
    if (canvas) {
        //increase x
        x += 5;

        //start from beginning
        if (x > canvas.width) {
            x = 0;
        }

        //clear
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        //image
        ctx.drawImage(image, x, 200);
    }
}

//start
loop();
我看到的

我意识到这个问题以前有人问过,我在问之前确实看了一下。然而,不幸的是,给出的答案没有帮助


谢谢你的帮助!非常感谢。

例如,在位置计算中使用时间增量。这将确保对象在给定的时间内以一定的值移动,而不考虑帧间的FPS和延迟

编辑您的小提琴:

错误的方法:

x+=5

好办法:

x+=speed*delta/1000


其中delta是以[ms]为单位从最后一帧开始经过的时间,而速度是以[pixels/s]为单位测量的。

您必须使用画布吗?你可以用CSS动画制作这些动画。如果你必须使用画布,你能使用TweenJS这样的tween库吗:我更喜欢画布而不是CSS,因为我认为画布只会变得更好更快。为现在和未来编码!我会调查Tweenj。我不熟悉tweening,但这可能是我需要的。我看了TweenJ,我认为它不能解决我的问题。它为帧之间的帧设置动画,使事情更平滑。然而,在我的例子中,我可以通过减少x的移动量和增加帧速率来获得相同的速度。即使这样,Firefox仍然很不稳定。除非你的应用程序特别需要画布,否则我会认真考虑CSS动画。CSS动画就像画布一样经得起未来的考验。另外,我还会看看EaselJS来处理帧循环和向画布/舞台添加资源。自从你提到CSS动画以来,我一直在看它们。它们似乎是基于时间的动画,我需要将时间转换为帧。我只需要在每个渲染循环中不断中断CSS动画,因为X/Y位置在碰撞后可能会发生变化,这也可能会导致起伏。我也有点不确定创建和删除DOM对象的速度有多快(比如玩家射出大量火球)。这是可行的,但肯定比画布更难。至少,我会先尝试一个小例子,然后再看。我已经在另一个例子中内置了类似的东西(使用固定的时间步长),但它仍然不稳定。我刚试过,你贴的小提琴对我来说也是波涛汹涌的。如果有帮助,这里的链接再次。我将编辑原始的post和swap示例1和2。不相关,但我刚刚看到您在小提琴中使用Date.now()而不是new Date()。没有意识到它的存在,而且它显然更快!我现在就用它来代替。