logo
post image

Handling Multi-Touch with Pointer Events in Javascript

Quick Recap : Handling Multi-Touch with Touch Events

Handling multi-touch using Touch Events could be achieved by using the touches, targetTouches & changedTouches properties of the event object. These 3 properties are arrays of objects, each object containing useful information such as touch co-ordinates, pressure etc. Using these properties we can handle multi-touch. You can get detailed information on Multi-touch Web Development.

Handling Multi-Touch with the new Pointer Events

Pointer Events have made it a little easier to handle multi-touch. Pointer Events pass a pointerId in the event object. A pointerId is a unique identifier for the pointer causing the event. With each new pointer, browser generates a new pointerId.

For example, with each pointerdown event, browser generates a pointerId for the current pointer. You can get this pointerId from the event object. As you move your pointer, pointermove events are generated - event objects will contain the same pointerId. When a pointerup event is performed, you get the same pointerId in the event's object. So in order to handle multi-touch, your application must keep track of all pointerId currently involved.

Please note that Pointer Events are generated for each of the active pointers, and unlike Touch Events, the event's object contains no information about other active pointers.

Demo Application Code

Below are the codes for a sample canvas paint application that demonstates multi-touch. When the canvas is touched at exactly 2 points, a line will be drawn between those points. Nothing will happen when touch points are less than or more then 2.

<canvas id="paint-canvas" width="300" height="200"></canvas> <div id="message"></div> #paint-canvas { border: 1px solid rgba(0,0,0,0.15); touch-action: none; } var _CANVAS = $("#paint-canvas").get(0), _CTX = _CANVAS.getContext("2d"), _TOUCHED_POINTS = [], // This array will hold the active touch points _CANVAS_OFFSET = null; // This will hold the offset co-ordinates of the canvas $('#paint-canvas').on('pointerdown', function(e) { _CANVAS_OFFSET = $("#paint-canvas").offset(); e = e.originalEvent; // On each pointerdown we save the new pointer in an array (which holds all the active pointers) // We save the pointer id & the co-ordinates of the pointer relative to the canvas _TOUCHED_POINTS.push({ pointer_id: e.pointerId, x: e.pageX - _CANVAS_OFFSET.left, y: e.pageY - _CANVAS_OFFSET.top }); // If the length of the array is 2, we draw a line between the 2 pointer locations if(_TOUCHED_POINTS.length == 2) { _CTX.beginPath(); _CTX.moveTo(_TOUCHED_POINTS[0]['x'], _TOUCHED_POINTS[0]['y']); _CTX.lineTo(_TOUCHED_POINTS[1]['x'], _TOUCHED_POINTS[1]['y']); _CTX.lineWidth = 2; _CTX.strokeStyle = "#000000"; _CTX.stroke(); _CTX.closePath(); } $("#message").text('Touched at ' + _TOUCHED_POINTS.length + ' points'); }); $('#paint-canvas').on('pointerup', function(e) { e = e.originalEvent; // On each pointerup we find the current pointer from the array (pointer id helps in finding the specific pointer) var index = _TOUCHED_POINTS.findIndex(function(point, index) { if(point.pointer_id == e.pointerId) return true; }); // Current pointer is removed from the array _TOUCHED_POINTS.splice(index, 1); $("#message").text('Touched at ' + _TOUCHED_POINTS.length + ' points'); });

jQuery does not pass pointerId property into its event object (jQuery has its own event object that is different from the original event object passed by Javascript). So we have to access the original event object through the originalEvent property of the jQuery event object.