I'm trying to learn how to create smooth JavaScript animations using HTML5's canvas. For some reason, the animation is not smooth, but kind of "sputtery".
You can see the framework I've built on this jsFiddle, which only uses Webkit properties at the moment.
Another developer was able to create the same concept using their WebViews source code, which is based on Ext.js. For learning purposes, I wanted to avoid using any libraries in effort to better understand JavaScript. The WebViews concept can be viewed at this jsFiddle, which shows a much smoother animation.
I've read and tried all kinds of different scenarios from pulling the update calls out of the requestAnimationFrame into it's own loop, to translating the context to the draw position, to drawing to a back-buffer context and copying it to the viewport. The following code represents my best efforts so far.
Any suggestions on how to improve the performance in order to get an object to move smoothly without all the overhead of an external library?
Thank you in advance.
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( );
};