【问题标题】:How to optimize animation on canvas? HTML 5如何优化画布上的动画? HTML 5
【发布时间】:2011-11-15 16:28:21
【问题描述】:

我遇到了一个问题,即随着各种图片向左、向右、向上和向下移动,画布上的动画速度变慢。我需要关于如何优化动画的建议。

动画在所有主要浏览器上都能正常运行很重要,特别是:Chrome、Firefox 和 Internet Explorer。

是否可以优化动画?也许延迟绘图?提前谢谢你。

【问题讨论】:

  • 你能贴出你用于画布动画的代码吗?

标签: javascript performance html animation canvas


【解决方案1】:

在 javascript 中,您可以使用 setInterval 和 setTimeout 函数来创建延迟和限制帧速率。

例如,如果你想让你的绘图循环大约 30 FPS,你可以有一些看起来像这样的代码:

function draw(){

        var canvas = document.getElementById('myCanvas');
        //create the image object
        var img = new Image();
        //set the image object's image file path
        var img.src = "images/myImage.png"
        //check to see that our canvas exists 
        if( canvas.getContext )
        {
            //grab the context to draw to.
            var ctx = cvs.getContext('2d');
            //clear the screen to a white background first
            //NOTE to make this faster you can clear just the parts
            //of the canvas that are moving instead of the whole thing
            //every time. Check out 'Improving HTML5 Canvas Performance'
                    //link mention in other post
            ctx.fillStyle="rgb(255,255,255)";
            ctx.fillRect (0, 0,512, 512);

            //DO ALL YOUR DRAWING HERE....

            //draw animation
            ctx.drawImage(img, 0, 0);
        }
        //Recalls this draw update 30 times per second
        setTimeout(draw,1000/30);
}

这将帮助您控制动画所花费的处理时间。因此,如果您发现您的动画运行速度太慢,您可以通过将分母“30”更改为“60”fps 或任何适合您的程序的值来提高帧速率。

除了 setTimeout() 之外的优化,绘制动画的方式也很关键。尝试在渲染之前加载所有图像,这称为“预加载”。也就是说,如果每个动画单元格都有一堆不同的图像,那么在调用绘图函数之前,将所有图像加载到图像数组中,如下所示:

var loadedImages = new Array();
loadedImages[0] = new Image();
loadedImages[0].src = "images/animationFrame1.png";
loadedImages[1] = new Image();
loadedImages[1].src = "images/animationFrame2.png";
loadedImages[2] = new Image();
loadedImages[2].src = "images/animationFrame3.png";
loadedImages[3] = new Image();
loadedImages[3].src = "images/animationFrame4.png";

如果对你的应用有意义,你甚至可以把它们放在一个哈希中而不是

loadedImages[0] = new Image();
loadedImages[0].src = "images/animationFrame1.png";

你这样做

loadedImages['frame1'] = new Image();
loadedImages['frame1'].src = "images/animationFrame1.png";

加载完所有图像后,您可以通过如下方式调用它们来引用它们进行绘图:

//Using the integer array
ctx.drawImage(loadedImages[0], 0, 0);
//OR
//Using the stringed hash 
ctx.drawImage(loadedImages['frame1'], 0, 0);

您希望将加载过程与渲染过程分开,因为加载图像是过程密集型的,因此如果您在渲染时加载内容会减慢动画速度。

这并不是说您在渲染时永远不能加载任何东西,而是说这会减慢动画速度。

Here 是一篇关于预加载图片的文章。

这里还有一篇文章讨论了所有浏览器上一致的动画速度here

注意绿色选中答案发布的link

其他需要注意的事情是确保只清除和重绘边界框,如文章中提到的使用 HTML 5 画布优化。在开发画布动画时,该链接有一些非常好的技巧。

Here 也是一些框架作品,它们可能会派上用场,以交叉比较您正在做的事情和其他引擎正在做的事情。

希望这对您有所帮助。我是 javascript 新手(大约 2 周前才开始使用它进行编码),因此可能有更好的方法来做事,但这些是我迄今为止发现的。

【讨论】:

    【解决方案2】:

    window.requestAnimationFrame() 是让动画运行更流畅的一种可靠方法。

    https://developer.mozilla.org/en/DOM/window.mozRequestAnimationFrame

    (跨浏览器http://paulirish.com/2011/requestanimationframe-for-smart-animating/)

    但它不能解决问题中缺少的绘图代码可能存在的问题。

    【讨论】:

      猜你喜欢
      • 2020-09-11
      • 1970-01-01
      • 2014-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      相关资源
      最近更新 更多