Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Canvas set z-index

Is it possible to set the z-index of a drawn object in HTML5 canvas?

I am trying to get it so one object can be infront of a the "player" and another object is behind the "player"

like image 593
Eli Stone Avatar asked Feb 06 '12 19:02

Eli Stone


3 Answers

Yes..kind of yes. You can use globalCompositeOperation to "draw behind" existing pixels.

ctx.globalCompositeOperation='destination-over';

Here's an example and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");

var cx=100;

drawCircle()
cx+=20;

ctx.globalCompositeOperation='destination-over';

$("#test").click(function(){
  drawCircle();
  cx+=20;
});

function drawCircle(){
  ctx.beginPath();
  ctx.arc(cx,150,20,0,Math.PI*2);
  ctx.closePath();
  ctx.fillStyle=randomColor();
  ctx.fill();
}

function randomColor(){ 
  return('#'+Math.floor(Math.random()*16777215).toString(16));
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id="test">Draw new circle behind.</button><br>
<canvas id="canvas" width=300 height=300></canvas>
like image 63
markE Avatar answered Oct 30 '22 10:10

markE


Just draw the things behind it first, then the thing, then the other objects.

To do hit testing you may need to iterate backwards over your display list, testing each object. This will work if you know the object boundaries really well.

Or you may want to try some standard graphics tricks like drawing the same objects to another in-memory canvas with unique colours for every object drawn: to hit test this just check the pixel colour on the in-memory canvas. Neat ;-)

like image 34
Joe Parry Avatar answered Oct 30 '22 08:10

Joe Parry


A solution that I've found works for me (and gets rid of flickering, hurrah!) is to use two canvases. (or more)

I will assume you are making a game of some kind (since you mention a player) and use that as an example.

You can take a page from the way windows works and put a canvas first as a background with another canvas over it as your player canvas. You can mark the player canvas as 'dirty' or changed whenever it has been altered and only redraw the changed layer when needed. This means that you only update the second canvas when your player moves or takes an action.

This method can be taken even farther and you can add a third canvas for a HUD with gameplay stats on it that is only changed when the player's stats change.

The html might look something like this:

<canvas id="background-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
<canvas id="player-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
<canvas id="hud-canvas" height="500" width="1000" style="border:1px solid #000000;"></canvas>
like image 7
nicholeous Avatar answered Oct 30 '22 09:10

nicholeous