# HTML5 clicking objects in canvas

I have a function in my JS that gets the user's mouse click on the canvas.

Now lets say I have a random shape on my canvas (really its a PNG image which is rectangular) but i don't want to include any alpha space.

My issue lies with lets say i click some where and it involves a pixel of one of the images. The first issue is how do you work out the pixel location is an object on the map (and not the grass tiles behind).

Secondly if i clicked said image, if each image contains its own unique information how do you process the click to load the correct data.

Note I don't use libraries I personally prefer the raw method. Relying on libraries doesn't teach me much I find.

• You will always be using someone else's library for some things, so your last observation is kind of off-track. It may make sense in some context, but don't take it as a dogma.
– o0'.
Mar 14 '12 at 10:42

You carry out a point-shape intersection at the clicked point.

Your event will carry a .clientX and .clientY property which gives you the location of the click relative to the browser window. You can calculate where this is on the canvas.

Once you've got the canvas (x,y), then you need to convert view coordinates into world coordinates, which would effectively reverse any transformation you have used to draw things (e.g. scrolling offszet).

Once you have the world-coordinates, then it's just a matter of doing a point-shape intersection in world-coordinates. If it's a rectangle that is pretty trivial.

• I have done that, i can convert to and from grid to mouse, but images can vary (imagine different shaped buildings on map)... they might span more than one tile in width or height in isometric.. so how would it be accurate?
– Dave
Mar 15 '12 at 0:30
• Also bare in mind because the image has a fair bit of alpha - i only want the object to be selectable if the mouse is over a pixel that is not alpha
– Dave
Mar 15 '12 at 0:34

Use the following for mouse movement:

window.addEventListener("mousemove", function(e)
{
// offsetX and layerX are actual positons of the canvas, while clientX is the position
// in the page
mouse.x = e.offsetX || e.layerX;
mouse.y = e.offsetY || e.layerY;
updateCanvasForClick();
});


You can also round the position to get the tile:

function getTile(canvasX, canvasY)
{
var x = Math.floor(canvasX / tileWidth);
var y = Math.floor(canvasY / tileHeight);
return map[x][y];
}


If I understand your question correctly, you have the coordinate in screen space of the click and want to know if there is an object there. And I'm assuming this is in 2D.

Do you have the height and width of each object and their location in the canvas? You could just then iterate over your object and figure out if that x,y is inside your objects rectangle. Than look at that pixel in the image (your could use a hidden canvas an put the objects image in there and then get the pixel color using https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas then figure out if it's alpha value is above 0.

You could make it faster by organizing your objects in a Quadtree

• So the objects that need to be clicked have to be in a seperate canvas? Because if the object is on a grass tile and i click near the object it won't detect alpha, itll detect the grass behind it and assume its the object?
– Dave
Mar 17 '12 at 0:51
• Yeah and in addition you could to draw the whole scene to a hidden canvas once with the whole grass red or something that way you can just figure out if it's hitting anything at all. That might speed things up a bit to do that. Mar 17 '12 at 2:11
• Not sure i understand that =/ have u got a js fiddle example?
– Dave
Mar 17 '12 at 2:40