When I draw some objects in canvas, sometimes new objects places under old ones. For example, I add some images to canvas and then draw a line. when I run code images are top of the line. I searched web for a solution. But there was not an straight-forward solution. :( In some cases, it have seen as a bug! in explorers. How can I control z-index?
Edit: this is my code
<img id="black_checkers_piece" src="egsdk/BlackCheckersPiece.png" style="display: none;">
<canvas id="c1" style="border:1px solid #998800"></canvas>
<script type="text/javascript">
var canvasID = document.getElementById('c1');
var ctx = canvasID.getContext('2d');
var img = new Image();
img.src = document.getElementById('black_checkers_piece').src;
img.onload = function(){
ctx.drawImage(img, 10, 10, 32, 32);
}
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(0, 0);
ctx.lineTo(50, 50);
ctx.stroke();
</script>
When I draw some objects in canvas, sometimes new objects places under old ones. For example, I add some images to canvas and then draw a line. when I run code images are top of the line. I searched web for a solution. But there was not an straight-forward solution. :( In some cases, it have seen as a bug! in explorers. How can I control z-index?
Edit: this is my code
<img id="black_checkers_piece" src="egsdk/BlackCheckersPiece.png" style="display: none;">
<canvas id="c1" style="border:1px solid #998800"></canvas>
<script type="text/javascript">
var canvasID = document.getElementById('c1');
var ctx = canvasID.getContext('2d');
var img = new Image();
img.src = document.getElementById('black_checkers_piece').src;
img.onload = function(){
ctx.drawImage(img, 10, 10, 32, 32);
}
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(0, 0);
ctx.lineTo(50, 50);
ctx.stroke();
</script>
Share
Improve this question
edited Jan 10, 2013 at 23:15
JalalJaberi
asked Jan 10, 2013 at 4:11
JalalJaberiJalalJaberi
2,6178 gold badges27 silver badges44 bronze badges
4
- 1 Maybe this can help you : stackoverflow./questions/9165766/html5-canvas-set-z-index – Iswanto San Commented Jan 10, 2013 at 4:30
- Thank you, but that isn't solution. Selected answer doesn't work in many situations. – JalalJaberi Commented Jan 10, 2013 at 4:37
- Show us your code. Drawing the image before the line should work. – Bergi Commented Jan 10, 2013 at 17:05
- There is a sample now :) – JalalJaberi Commented Jan 10, 2013 at 23:16
3 Answers
Reset to default 9You are most likely waiting for images to load before drawing them.
Additionally, you are probably drawing lines as soon as you can.
You need to wait for all images to load, then draw everything in the order you want (from farthest z-order to closest). Do not draw anything until all images have been loaded, or your z-order will not be correct.
If you want to show items on the screen before all images are loaded, you must redraw everything on each image load, not just draw that one image.
Here's an example, where I draw 3 objects: A circle, an image, and a window. I draw them immediately, whether the image is loaded or not, but I draw all of them again once the image is loaded to ensure that the image is correctly in between the other two objects:
http://jsfiddle/U5bXf/32/
The shorthand relevant code (in case jsfiddle goes down) is:
var img = new Image()
img.onload = function() {
draw()
};
img.src = "http://placekitten./100/140";
draw();
function draw() {
// object one
// Now we'll draw the image in between, if its loaded
ctx.drawImage(img, 100, 30);
// object two
}
Code below this line is a response to the ments
You've since posted code, but you'll notice that the only thing you are drawing in the onload
function is the image.
The onload function usually happens after the other drawing mands (unless the page is already loaded, then it could be either). You need to move all drawing code into the onload function or else make your own drawing function that loads everything. For example:
<img id="black_checkers_piece" src="egsdk/BlackCheckersPiece.png" style="display: none;">
<canvas id="c1" style="border:1px solid #998800"></canvas>
<script type="text/javascript">
var canvasID = document.getElementById('c1');
var ctx = canvasID.getContext('2d');
var img = new Image();
img.src = document.getElementById('black_checkers_piece').src;
img.onload = function(){
// assuming we want the image drawn before the line:
ctx.drawImage(img, 10, 10, 32, 32);
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(0, 0);
ctx.lineTo(50, 50);
ctx.stroke();
}
Canvas doesn't have any concept of 'z-index.' There are no objects in a canvas - canvases are just bitmaps, just pixels.
Are you sure you're drawing the line and the images on the canvas, and not just creating new elements (like img elements?).
If you are, then check the order in which you're calling the drawing methods like fill() and stroke(). Shapes aren't actually drawn until you do that (no matter where you have your moveTo and lineTo calls).
I have been using fabric.js and it has some features that you may find useful. While not z-index per se, it can set a background or an overlay - below is an example found on http://fabricjs./customization/
var canvas = new fabric.Canvas('c13'); canvas.add(new fabric.Circle({ radius: 30, fill: '#f55', top: 100, left: 100 })); canvas.setOverlayImage('../assets/jail_cell_bars.png', canvas.renderAll.bind(canvas)); this.__canvases.push(canvas);