Getting touchy - an introduction to touch and pointer events / Future of Web Apps / London...

Post on 09-May-2015

4.296 views 3 download

Transcript of Getting touchy - an introduction to touch and pointer events / Future of Web Apps / London...

mouseover > mousemove* > mousedown >

(focus) > mouseup > click

mouseover > mousemove > mousedown >

(focus) > mouseup > click

mousemove > mousedown > (focus) >

mouseup > click

mouseout > (blur)

focus/blur

mouseout

touchstart

touchmove

touchend

touchcancel

touchenter

touchleave

touchstart > [touchmove]+ > touchend >

mouseover > mousemove > mousedown >

(focus) > mouseup > click

touchstart > [touchmove]+ > touchend > mouseover >

mousemove > mousedown > (focus) > mouseup > click

touchstart > [touchmove]+ > touchend > mousemove >

mousedown > (focus) > mouseup > click

mouseout > (blur)

touchmove touchend

touchmove

mouseover > mousemove > touchstart > touchend > mousedown >

mouseup > click

touchstart > mouseover > mousemove > mousedown > touchend >

mouseup > click

if ('ontouchstart' in window) {

/* some clever stuff here */

}

/* common performance “trick” */

var clickEvent = ('ontouchstart' in window ?

'touchend' : 'click');

blah.addEventListener(clickEvent,

function() { ... }, false);

if ('ontouchstart' in window) {

/* browser supports touch events

but user is not necessarily

using touch (exclusively) */

}

touchstart > touchend > mouseover > mousemove > mousedown > mouseup > click

mouseover > mousedown > mousemove > mouseup > click

focus > click

focus > touchstart > touchend > mouseover > mousemove > mousedown

blur > mouseup > click

focus > touchstart > touchend > mouseover > mousemove > mousedown

blur > mouseup > click

focus > blur > mousedown > mouseup > click > focus(?)

/* doubled-up event listeners */

foo.addEventListener('touchstart',

someFunction, false);

foo.addEventListener('click',

someFunction, false);

/* doubled-up event listeners */

foo.addEventListener('touchstart',

function(e) {

/* prevent delay+mouse events */

e.preventDefault();

someFunction();

/* or even e.target.click(); */

}, false);

foo.addEventListener('click',

someFunction, false);

preventDefault

touchstart > [touchmove]+ > touchend >

mouseover > mousemove* > mousedown >

(focus) > mouseup > click

mousemove touchmove

var posX, posY;

...

function positionHandler(e) {

posX = e.clientX;

posY = e.clientY;

}

...

canvas.addEventListener('mousemove',

positionHandler, false);

var posX, posY;

...

function positionHandler(e) {

/* handle both mouse and touch? */

}

...

canvas.addEventListener('mousemove',

positionHandler, false);

canvas.addEventListener('touchmove',

positionHandler, false);

interface MouseEvent : UIEvent {

readonly attribute long screenX;

readonly attribute long screenY;

readonly attribute long clientX;

readonly attribute long clientY;

readonly attribute boolean ctrlKey;

readonly attribute boolean shiftKey;

readonly attribute boolean altKey;

readonly attribute boolean metaKey;

readonly attribute unsigned short button;

readonly attribute EventTarget

relatedTarget;

void initMouseEvent(...);

};

interface TouchEvent : UIEvent {

readonly attribute TouchList touches;

readonly attribute TouchList targetTouches;

readonly attribute TouchList changedTouches;

readonly attribute boolean altKey;

readonly attribute boolean metaKey;

readonly attribute boolean ctrlKey;

readonly attribute boolean shiftKey;

};

interface Touch {

readonly attribute long identifier;

readonly attribute EventTarget target;

readonly attribute long screenX;

readonly attribute long screenY;

readonly attribute long clientX;

readonly attribute long clientY;

readonly attribute long pageX;

readonly attribute long pageY;

};

var posX, posY;

...

function positionHandler(e) {

if ((e.clientX)&&(e.clientY)) {

posX = e.clientX;

posY = e.clientY;

} else if (e.targetTouches) {

posX = e.targetTouches[0].clientX;

posY = e.targetTouches[0].clientY;

e.preventDefault();

}

}

...

canvas.addEventListener('mousemove',

positionHandler, false );

canvas.addEventListener('touchmove',

positionHandler, false );

touchmove

touchmove

requestAnimationFrame

setInterval

interface TouchEvent : UIEvent {

readonly attribute TouchList touches;

readonly attribute TouchList targetTouches;

readonly attribute TouchList changedTouches;

readonly attribute boolean altKey;

readonly attribute boolean metaKey;

readonly attribute boolean ctrlKey;

readonly attribute boolean shiftKey;

};

for (i=0; i<e.targetTouches.length; i++) {

...

posX = e.targetTouches[i].clientX;

posY = e.targetTouches[i].clientY;

...

}

preventDefault()

preventDefault()

/* iOS/Safari has gesture events for size/rotation,

not supported in Chrome/Firefox/Opera,

not part of the W3C Touch Events spec. */

gesturestart, gesturechange, gestureend

e.scale, e.rotation

/* with some trigonometry we can replicate these

from basic principles. */

var distance = Math.sqrt(Math.pow(...)+Math.pow(...));

var angle = Math.atan2(...);

pointerover > mouseover >

pointerdown > mousedown >

pointermove > mousemove >

(focus) >

pointerup > mouseup >

pointerout > mouseout >

click

pointerenter

pointerleave

gotpointercapture

lostpointercapture

MSPointerDown

MSPointerMove

MSPointerUp

navigator.msPointerEnabled

navigator.msMaxTouchPoints

-ms-touch-action

interface MouseEvent : UIEvent {

readonly attribute long screenX;

readonly attribute long screenY;

readonly attribute long clientX;

readonly attribute long clientY;

readonly attribute boolean ctrlKey;

readonly attribute boolean shiftKey;

readonly attribute boolean altKey;

readonly attribute boolean metaKey;

readonly attribute unsigned short button;

readonly attribute EventTarget

relatedTarget;

void initMouseEvent(...);

};

/* Pointer Events extend Mouse Events

vs Touch Events and their completely new objects/arrays */

interface PointerEvent : MouseEvent {

readonly attribute long pointerId;

readonly attribute long width;

readonly attribute long height;

readonly attribute float pressure;

readonly attribute long tiltX;

readonly attribute long tiltY;

readonly attribute DOMString pointerType;

readonly attribute boolean isPrimary;

};

preventDefault()

pointerdown

touch-action: auto|none|[pan-x][pan-y]

touch-action:none

touch-action:none

touch-action:none

/* PointerEvents don't have the handy touch arrays,

so we have to replicate something similar... */

/* PointerEvents don't have the handy touch arrays,

so we have to replicate something similar... */

var points = [];

switch (e.type) {

case 'pointerdown':

/* add to the array */

break;

case 'pointermove':

/* update the relevant array entry's x and y */

break;

case 'pointerup':

/* remove the relevant array entry */

break;

}

/* like iOS/Safari, IE10/Win has higher-level gestures,

but these are not part of the W3C Pointer Events spec.

Replicate these from basic principles again? */