Parallax scrolling in HTML5 canvas – HowTo

A few month ago I created a simple animation in a HTML5 canvas. Today I had the idea of extending the example with parallax scrolling.

Okay, so what exactly is parallax scrolling? Well, parallax scrolling is a technology used in 2D video and computer games where you create image depth in two dimensional spaces.

Although we have a two dimensional screen, for the viewer it seems that there is a three dimensional depth, because the background is sliced in layers and each one moves with a different speed. The first layer is moved by 0, the second by 1 and the third (top most) by 2, so that the top most layer is the fastest.

See the wiki page for parallax scrolling for more information – they can explain things better that me. Let’s get into code.

My approach for parallax scrolling is:

/** 
 * Data structure to hold layer data
 * @param s <string> Absolute path to the image
 * @param x <int> X coordinate
 * @param Y </int><int> Y coordinate
 */
function Layer(s, x, y) {
	this.img = new Image();
	this.img.src = s;
	this.x = x;
	this.y = y;	
}
 
 
/**
 * Main ParallaxScrolling class
 * @param ctx <context> Canvas context
 * @param imgdata <array> Array with absolute image paths
 */
function ParallaxScrolling(ctx, imgdata) {
	var self = this;	
	if( typeof imgdata === 'undefined' ) imgdata = [];
	this.ctx = ctx;			
 
	// Initialize the layers
	this.layers = new Array(imgdata.length);
	for(i=0; i<imgdata .length; i++) {	
		this.layers[i] = new Layer(imgdata[i], 0, 0);
	}
 
	// Function: Move all layer except the first one
	this.Move = function() {
		for(var i=1; i<self.layers.length; i++) {
			if( self.layers[i].x > self.layers[i].img.width ) self.layers[i].x = 0;
			self.layers[i].x += i;			
		}
	};
 
	// Function: Draw all layer in the canvas
	this.Draw = function() {
		self.Move();
		for(var i=0; i<self .layers.length; i++) {
			var x1 = (self.layers[i].x-self.layers[i].img.width);
			self.ctx.drawImage(self.layers[i].img, 0, 0, self.layers[i].img.width, self.layers[i].img.height, 
												 self.layers[i].x, 0, self.layers[i].img.width, self.layers[i].img.height);
			self.ctx.drawImage(self.layers[i].img, 0, 0, self.layers[i].img.width, self.layers[i].img.height, 
												 x1, 0, self.layers[i].img.width, self.layers[i].img.height);						
		}
	}
}

We have two classes here. One (Layer) is just an object to hold the layer data. We need an image and x and y coordinates for that. The second one (ParallaxScrolling) is our “main” class, where we initialize the layers and have a function to draw them. The Draw function also moves the layers and takes care of the x coodinate. In this example we don’t care for the y coordinate, because we just want to move the image horizontaly.

You may notice that the ctx.drawImage function is called twice. This is for having a smooth transition when the image “leaves” the screen. As we shift the image to one direction we have to fill up the empty space it leaves behind. For that we draw a copy of the image just behind the original one. Because the move function controls the x coordinate for us, we also don’t have to care for a reset of the x1 coordinate, that is the copy’s x coodinate, as the x1 coordinate is relative to the x coodinate.

The layers in the example are:

Background layer

Background layer

Layer #1 (middle)

Layer #1 (middle)

Top most layer

Top most layer

The final result would look like:


Refresh the page if you don't see the example above!

And when we add our sprite from the earlier example:


Refresh the page if you don't see the example above!

I think this simple example should explain how parallax scrolling works and how it can be implemted in HTML5 and Javascript.

Similar Posts:

  • Kristopher Kendall

    Hi. I’m doing a game and I want to make the background move a lot faster than the character. How do you think I could make the background and the character move at different speeds?