3
\$\begingroup\$

I'm making an HTML 5 game. I want mouse clicks on sprites drawn in a canvas element cause events that my code can react to. At the moment, I'm doing it by checking through all of my sprites in a for-loop on each click.

Is there a way to do that by adding an event listener to a sprite so it would respond just like that?

Are Javascript's custom events useful in this situation? I know it's possible with KinectJS, but I don't have any experience with it and really I'd like to learn how to do this myself without the help of a library.

\$\endgroup\$
3
\$\begingroup\$

The computer graphics term for what you're trying to do is picking.

The issue with picking from an HTML canvas is that the canvas doesn't understand anything about sprites -- all it knows about is pixels. In more general terms, canvas is a purely graphical representation -- it stores no semantic information. It has no idea what you wanted those pixels to represent.

The sprites you're talking about (which you're for-looping over and which KineticJS has triggering events and such) are not defined at the canvas level, but at your application's level. You could be rendering them with WebGL or SVG or anything else, but their semantics (what they mean) would stay the same. That's where you should be asking what did we click on?

All of this is just a long way of saying you're doing it totally right. :) Looping over objects to see which one of them was clicked is totally reasonable. (The canvas could only have told you is what colour the clicked pixel was.)


Some stuff you might want to consider:

  • If you want pixel-perfect picking from a canvas, there's a very good discussion of that here.
  • If you're worried about picking performance as the number of objects increases, you could speed it up by storing your objects in a quadtree. I've had great success using D3's quadtree implementation.
  • If you want to make your own EventEmitters, consider using Node.js' event API, which has been ported to also run on browser JS engines.
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thanks for your reply. That makes complete sense really. Good thing is i don't have too much object/sprite at the moment (Max 30 to 40 at times) . I will look into pixel perfect picking more. Thanks again. \$\endgroup\$ – aaa111 Jan 16 '14 at 10:33
  • \$\begingroup\$ @aaa No problem, it's a learning resource for future readers too. I added a few more helpful links and a little about event emitters. \$\endgroup\$ – Anko Jan 16 '14 at 11:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.