2012-09-25 66 views
2

我在学习如何使用HTML5的画布创建流畅的JavaScript动画。出于某种原因,动画不太流畅,但有点“讽刺”。平滑画布动画

你可以看到我在this jsFiddle上构建的框架,它目前只使用Webkit属性。

另一位开发人员使用their WebViews source code创建了基于Ext.js的相同概念。为了学习目的,我想避免使用任何库来努力更好地理解JavaScript。 WebViews的概念可以在this jsFiddle查看,这显示了更平滑的动画。

我已经阅读并尝试了从requestAnimationFrame调用update调用到它自己的循环中的各种不同场景,将上下文转换为绘制位置,绘制到后台缓冲区上下文并将其复制到视口。以下代码代表了我迄今为止的最大努力。

有关如何提高性能以便在没有外部库的所有开销的情况下使对象平稳移动的任何建议?

预先感谢您。

var app; 
var now = then = delta = 0; 
var viewport = document.createElement('canvas'); 
var viewportContext = viewport.getContext('2d'); 

function App() 
{ 
    this.circle = { 
     position : viewport.width/2, 
     radius : 10 
    }; 
} 

App.prototype.initialize = function() 
{ 
    app = this; 
    document.body.appendChild(viewport); 
    viewport.width = 320; 
    viewport.height = 200; 

    webkitRequestAnimationFrame(app.render, viewport); 
}; 

App.prototype.render = function() 
{ 
    now = performance.webkitNow(); 
    delta = (now - then)/1000.0; 
    then = now; 

    app.update(delta); 
    viewportContext.clearRect(0, 0, viewport.width, viewport.height); 
    app.draw(viewportContext); 

    webkitRequestAnimationFrame(app.render, viewport); 
}; 

App.prototype.draw = function(context) 
{ 
    context.fillStyle = "white"; 
    context.beginPath(); 
    context.arc(this.circle.position | 0, viewport.height/2 | 0, this.circle.radius | 0, 0, Math.PI * 2, true); 
    context.closePath(); 
    context.fill(); 
}; 

App.prototype.update = function(deltaTime) 
{ 
    this.circle.position += viewport.width/5 * deltaTime; 

    if(this.circle.position >= viewport.width) 
    { 
     this.circle.position = 0; 
    } 
}; 

window.onload = function() 
{ 
    new App().initialize(); 
};​ 
+0

顺利运行。话虽如此,您可以通过访问您的F12开发人员工具并查看分析选项来分析您的应用程序 - 这会告诉您应用程序的哪些部分耗尽了大量资源和时间。 – Sampson

+0

与您的WebViews演示相比,我看不出您的演示的平滑度存在显着差异。我正在运行Chrome 21.0.1180.89米。 –

+0

嗯......任何区别都是不同的,对我的演示来说不是很明显,但它在那里。我运行的是相同版本的Chrome,并且我尝试了解开发人员工具中的堆配置文件和内存时间轴,但无济于事。事实上,我无法达到与WebViews演示相同的保真度水平,这让我发疯。 – Quantastical

回答

3

许多常见的优化,以及为什么,以及如何提高性能有很大的解释请参见this page

此外,出于某种原因,性能似乎在更“中等”的画布上增加。我不完全确定这是为什么,但我相信它与浏览器优化有关。

你可以注意到有一些小的调整在这里的一些性能提升:http://jsfiddle.net/3TAVu/1/

具体来说,我去掉了多余的分配填充样式这里:

App.prototype.draw = function(context) 
{ 
    context.beginPath(); 
    context.arc(this.circle.position | 0, viewport.height/2 | 0, this.circle.radius | 0, 0, Math.PI * 2, true); 
    context.closePath(); 
    context.fill(); 
}; 

我也只是清理修改的渲染方法而不是整个画布的相关部分:

App.prototype.render = function() 
{ 
    now = performance.webkitNow(); 
    delta = (now - then)/1000.0; 
    then = now; 

    var cX = app.circle ? (app.circle.position - app.circle.radius) : 0; 
    var cY = Math.round(viewport.height/2) - app.circle.radius; 
    var w = app.circle ? app.circle.radius * 2 : 0; 

    viewportContext.clearRect(cX - 1, cY - 1, w + 2, w + 2); 

    app.update(delta); 
    app.draw(viewportContext); 

    webkitRequestAnimationFrame(app.render, viewport); 
}; 
+0

感谢您的帮助,@Shmiddty。我认为我有足够的能力从这里开始并继续进行框架。很可能,我将不得不重新加入清晰的画布,考虑到场景通常比水平移动的球更有趣。另外,感谢链接到文档。我已经阅读了大部分内容,但我可能需要再次查看,因为我在这里有一些信息超载。 – Quantastical

+0

当然可以。我通常觉得这个东西很有趣。 – Shmiddty

2

嘿我找到了this很好地解释了关于requestAnimationFrame的事情,它处理更流畅的动画。如果您或未来的这个问题的查看者可能会觉得这有用..