user172163
user172163

Reputation:

Infinite Canvas background scrolling without hiccups

The chart below shows how I am making an infinite background scrolling in HTML5/JS. My continuous background is consist of X canvases. I will render the next Canvas immediately before reaching it, and I will release previous Canvas. The problem here is the fact that animation is smooth after rendering, but it has a quick hiccup when it reaches to next frame. because it will render the next frame, logically there will be a quick hiccup. The problem could be solved using multi-threading in other languages. but this rendering needs DOM so it will be locked.

The question: How to render next background Canvas in HTML5 without blocking current jQuery animation?

    INIT     > START render 0
 _________
|         |
|    0    |  > render1
|_________|
|         |
|    1    |  > render 2
|_________|
|         |
|    2    |  > render 3
|_________|
|         |
|    ∞    |  > render X
|_________|

Pseudo

var currentSpite = 0;
function goAnimate() {

    render(currentSpite + 1); //50ms hiccup here
    $("#allSpites").animate({ "top": (currentSpite * 1000) + "px" }, 1000, function () {
        goAnimate();
    });
    currentSpite += 1;

    release(currentSpite - 2);
    if (currentSpite > max) return;

}

Upvotes: 0

Views: 1294

Answers (1)

GameAlchemist
GameAlchemist

Reputation: 19294

As i said in the comments, creating a canvas is not something you want to do within an animation loop : it takes several milliseconds to do so, which is enough to switch from 60fps to 30 (or 50 to 25), since you already have some drawings to do.
Worst thing is that if you create canvas then 'dispose' of them, they'll have to be garbage collected, which is another 'long' pause for your app.

My first though was to use two canvases and to swap them through css. But i just did a quick test and smoothness was poor : to many reflow i guess.
Smoothness had little to see with a small scrolling demo i did some time ago using only a single canvas ( jsfiddle.net/gamealchemist/5VJhp ) .

So final advice was to use only one single canvas, clear it on each frame, and draw the two required 'render' with KinectJS, just translating the canvas before the draw to adjust coordinates.

It seems to work, since with 9ms you even have a few ms left within the 16ms of 60fps : sweet ! :-)

Upvotes: 1

Related Questions