Handling JavaScript touch events in HTML5 Canvas

Luke Canvin

Right from the start, we wanted to make our application as usable on a tablet as it was on a laptop or desktop computer, which means offering top-notch support for touch as well as mouse-clicks. The only area where this presented a challenge was in allowing a user to use touch to drag and drop in our HTML5 Canvas controls.

It was clear how to do this with mouse-clicks; you would bind your mousedown, mousemove and mouseup events to the canvas element and you could get the pageX and pageY properties from the event and do whatever you’d like with them. For example (in CoffeeScript):

$(@).mousedown (event) =>

Here we’re using jQuery to bind the mousedown event and call our own Mousedown method, passing the X and Y parameters taken from the event. If you’re not a CoffeeScript user, the @ symbol translates to the JavaScript this keyword.

For touch, we have the touchstart, touchmove and touchend events, but you cannot bind to them in quite the same way (as they don’t have dedicated jQuery methods) and you cannot get the X and Y positions in quite the same way. For example:

$(@).bind 'touchstart', (event) =>
	@Mousedown(event.originalEvent.touches[0].pageX, event.originalEvent.touches[0].pageY)

So here we call the jQuery bind method, passing the touchstart as the event we’re binding, and call our own Mousedown method passing the X and Y positions, taken from deep within the touch event object. That gives us exactly what we need.

Preventing the default touch event (scrolling the browser)

Because the iPad (for example) browser naturally wants to interpret a user’s touch-dragging as them trying to scroll the page, we need to prevent that from happening when they touch and drag one of the parts of the canvas we want to be draggable. To do that, as part of our Mousedown method, we figure out whether the user has touched on a draggable area and if they have, we prevent the default browser behaviour with event.preventDefault().

That means if they touch and drag part of the canvas we want to be draggable, then the browser doesn’t scroll around, but if they touch any other part, the browser scrolls as normal – perfect!