HTML5 Canvas Clear Rect but Keep Background

This is somewhat of a ‘glue’ lesson in our tutorial. Should have been fixed earlier but all is not lost. Again we will be working on our last tutorial so make sure you’ve read that first and have all the changes in the html file.

tile game tutorial

Remember this problem? From our lesson?
clearrect but keep background

And then we fixed the player ‘trail’ with ctx.clearRect but got into another problem? (aka background disappearing)?

Click to play animation

What we want basically is to

clearRect but keep background

One solution do to this is to create another canvas that holds stuff that needs to be animated and keep the current one for the background (stuff that doesn’t change).

Kindly add a new canvas below the existing one like this:

...
<canvas height="180" id="myCanvas" style="border: 1px solid #000000;" width="240"></canvas>
<canvas id="scene" width="240" height="180" style="border: 1px solid #000000;"></canvas>
...

Inside <script> tag, above existing canvas variable add two new ones that hold reference to the new scene canvas and it’s context.

...
var scene = document.getElementById("scene");
var sceneCtx = scene.getContext("2d");
...

Modify render function to use sceneCtx instead of ctx. This means we clear and draw only on scene canvas while keeping the background canvas untouched.

function render(delta) {
	sceneCtx.clearRect(0, 0, canvas.width, canvas.height);
	sceneCtx.drawImage(player.image, player.x, player.y, 20, 20);
}

Remove this line from the buildMap function.

ctx.drawImage(player.image, player.x, player.y, player.width, player.height);

Now should look like this:

function buildMap(map) {
	var mapWidth = map[0].length;
	var mapHeight = map.length;
	
	for (var i = 0; i < mapHeight; ++i) {
		for (var j = 0; j < mapWidth; ++j) {
			var name = "t_" + i + "_" + j;

			if (map[i][j] == 0) {
				game[name] = new BackgroundTile();
				ctx.drawImage(game[name].image, posX, posY, game.tileW, game.tileH);
			} else {
				game[name] = new BoxTile();
				ctx.drawImage(game[name].image, posX, posY, game.tileW, game.tileH);
			}
			posX += game.tileW;
		}
		posX = 0;
		posY += game.tileH;
	}

	player = new Player(2, 1, player_png, 2);
	player.width = 20;
	player.height = 20;
	player.x = (player.centerX * game.tileW) + game.tileW / 2 - (player.width / 2);
	player.y = (player.centerY * game.tileH) + game.tileH / 2 - (player.height / 2);
	
	requestAnimationFrame(frame);
}

Add css to make canvases overlap each other

This is really important, without this CSS the two canvases will be drawn next to each other. Add this inside <head> tag in order for our clearRect but keep background trick to work.

<style>
	canvas {
		position: absolute;
		top: 0;
		left: 0;
	}
</style>

You can now move the player using arrow keys. Open iframe in new tab if the page also scrolls when you move the player.

Click on canvas before testing

Continue next with collision detection!!

FacebookTwitterLinkedin