Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is HTML5 hit detection possible?

I have used the Canvas code provided elsewhere on this site to create a screen where I have several overlapping transparent pngs with the non-transparent parts being irregular shapes. I can get the color under the cursor and that is great. But my shapes are all the same color and I need a way to get the ID of the particular shape as well so I know which one was clicked on. Imagine a map made of overlapping pngs fo reach country and you want to detect which country was clicked on. From what I can tell, id detection only applies to rectangular regions. Any suggestions?

$('#myCanvas').click(function(e){
var position = findPos(this);
var x = e.pageX - position.x;
var y = e.pageY - position.y;
var coordinate = "x=" + x + ", y=" + y;
var canvas = this.getContext('2d');
var p = canvas.getImageData(x, y, 1, 1).data;
var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
alert(hex);
});

This code gets and displays the color (findPos and rgbToHex are separate functions left off for clarity). I need an id! Help!

like image 612
Doug Wolfgram Avatar asked Oct 07 '22 09:10

Doug Wolfgram


1 Answers

Even with transparency, the images are all rectangles. You then know which images are at a clicked point by rectangle intersection - check your array of images and their x,y points with width,height for point intersection. You then come up with an array of possibly clicked images. If there's only one in the list, you are done.

The images have an implied Z-order of the reverse order in which you wrote them, meaning, an image is overwritten by the next image written which overlaps it. You can use that to know which order to try them in for hit-testing if more than one is at the point clicked. The only trick is to detect if an image pixel is transparent or not.

To detect transparency for a pixel point clicked in a single image, you could keep a second hidden canvas element. Clear it, then write the target image to it at the same position, and use the same code to see if the clicked pixel within the second canvas is the transparent color. If it is, repeat this process with the next image in the Z-order until you get the image where a non-transparent pixel was clicked.

A small but important optimization is to check the color clicked first, and if it's the transparent color you already know none of the images were clicked on a non-transparent point.

like image 115
Ed Bayiates Avatar answered Oct 10 '22 04:10

Ed Bayiates