如何优化画布上的动画? HTML 5

Posted

技术标签:

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

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

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

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

【问题讨论】:

你能贴出你用于画布动画的代码吗? 【参考方案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/)

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

【讨论】:

以上是关于如何优化画布上的动画? HTML 5的主要内容,如果未能解决你的问题,请参考以下文章

如何在 html 画布中获取动画方向?

如何在两个动画画布元素之间进行通信?

如何在html5画布中逐步绘制线条动画

如何在一页上放置多个画布js动画。 (创建js)

使用 Delphi 的 HTML5 画布动画

HTML5 画布中的动画 GIF