【问题标题】:HTML5 Canvas DrawImage Stutter / ChoppinessHTML5 Canvas DrawImage 口吃/断断续续
【发布时间】:2013-01-01 16:13:40
【问题描述】:

问题

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

我尝试了什么

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

示例 1: http://jsfiddle.net/QkvYs/

这个有一个固定的帧率,无论游戏循环运行的频率如何,它都能确保位置正确。它显示跳过的帧数。这个例子更接近我的目标。请注意,即使没有跳过任何帧,它看起来也很不稳定。我也玩过帧率,但没有成功,但我想瞄准大约 30 fps (var frameRate = 33;)。

示例 2: http://jsfiddle.net/R8sEV/

这是一个简单的例子,它所做的只是移动图像。这在多台机器上对我来说会卡顿。

//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();

我看到了什么

我意识到这个问题之前已经被问过,我确实在问之前看过。然而,不幸的是,给出的答案没有帮助。

感谢您的帮助!我很感激。

【问题讨论】:

  • 你必须使用画布吗?你可以用 CSS Animations 来做这个动画。如果一定要用画布,能不能用TweenJS之类的补间库:createjs.com/#!/TweenJS
  • 我更喜欢画布而不是 CSS,因为我看到画布只会变得越来越好。为现在和未来编码!我将研究 TweenJS。我不熟悉补间,但这可能是我需要的。
  • 我查看了 TweenJS,但我认为它不能解决我的问题。它对帧之间的帧进行动画处理,以使事情更流畅。但是,在我的情况下,我可以通过减少 x 的移动量并增加帧速率来获得相同的速度来做同样的事情。即使这样,它在 Firefox 上仍然不稳定。
  • 我会认真考虑 CSS 动画,除非您的应用程序特别需要画布。 CSS 动画与画布一样是面向未来的。附言。我还会查看 EaselJS 来处理帧循环并将资产添加到画布/舞台。
  • 自从你提到 CSS 动画后,我就一直在研究它们。它们似乎是基于时间的动画,我需要将其转换为帧。我只需要在每个渲染循环中不断中断 CSS 动画,因为 X/Y 位置可能在碰撞后发生变化,这也可能导致断断续续。我也有点不确定创建和删除 DOM 对象的速度有多快(就像玩家射击大量火球一样)。这是可行的,但绝对比画布更难。至少,我会先尝试一个小例子,然后从那里看到。

标签: html animation canvas drawimage


【解决方案1】:

例如,在您的头寸计算中使用时间增量。这将确保对象在给定时间内移动某个值,而不管 FPS 和帧之间的延迟。

编辑了你的小提琴: http://jsfiddle.net/R8sEV/2/

错误的方法:

x += 5

好方法:

x += speed * delta / 1000

其中 delta 是从上一帧经过的时间(以 [ms] 为单位) - 速度以 [pixels/second] 为单位测量

【讨论】:

  • 我已经在另一个示例中内置了类似的东西(使用固定的时间步长),但它仍然不稳定。我刚试过,你贴的小提琴对我来说也很不稳定。如果它有帮助,这里的链接再次。 jsfiddle.net/QkvYs我将编辑原始帖子并交换示例1和2。
  • 不相关,但我刚刚看到您在小提琴中使用了 Date.now() 而不是 new Date()。没有意识到它的存在,它显然更快!我现在将使用它。
猜你喜欢
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多