getting touchy - an introduction to touch and pointer events / frontend ne / 2 march 2017

Post on 19-Mar-2017

98 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

getting touchyAN INTRODUCTION TO TOUCH AND POINTER EVENTS

Patrick H. Lauke / Frontend NE / 2 March 2017

about me...•   senior accessibility consultant at The Paciello Group

•   previously developer relations at Opera

•   co-editor Touch Events Level 2

•   WG chair and co-editor Pointer Events Level 2

github.com/patrickhlauke/getting-touchy-presentation"evergreen" expanded version of this presentation

(and branches for specific conferences)

patrickhlauke.github.io/touch

Touch/pointer events test results

my JavaScript sucks... (but will hopefully convey the right concepts)

how can I make my website work on touch devices?

you don't need touch events browsers emulate regular

mouse events

patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html

patrickhlauke.github.io/touch/tests/event-listener_mouse-only.html

compatibility mouse events(mouseenter) > mouseover > mousemove* > mousedown >

(focus) > mouseup > click* only a single sacrificial mousemove event fired

on first tap(mouseenter) > mouseover > mousemove >

mousedown > (focus) > mouseup > click

subsequent tapsmousemove > mousedown > mouseup > click

tapping away(mouseout) > (blur)

focus / blur only on focusable elements; subtle differences between browsers Mobile/tablet touchscreen activation/tap event order

emulation works, but is limiting/problematic

1.  delayed event dispatch2.  mousemove doesn't track

1.  delayed event dispatch2.  mousemove doesn't track

patrickhlauke.github.io/touch/tests/event-listener_show-delay.htmlless of a problem in modern browsers, but for iOS < 9.3 or older Androids still relevant

patrickhlauke.github.io/touch/tests/event-listener_show-delay.html

1.  delayed event dispatch2.  mousemove doesn't track

patrickhlauke.github.io/touch/particle/2

patrickhlauke.github.io/touch/particle/2

we need to go deeper...

touch events

introduced by Apple, adoptedin Chrome/Firefox/Opera

(and belatedly IE/Edge – more on that later)

www.w3.org/TR/touch-events

caniuse.com: Can I use touch events?

touchstart touchmove touchend

touchcancel

patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.htmlBug 128534 - 'mouseenter' mouse compat event not fired...

events fired on taptouchstart > [touchmove]+ > touchend >

(mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click

(mouse events only fired for single-finger tap)

on first taptouchstart > [touchmove]+ > touchend >

(mouseenter) > mouseover > mousemove > mousedown > (focus) > mouseup > click

subsequent tapstouchstart > [touchmove]+ > touchend > mousemove > mousedown > mouseup > click

tapping awaymouseout > (mouseleave) > (blur)

•   too many touchmove events prevent mouse compatibility events

after touchend (not considered a "clean" tap)

•   too many touchmove events on activatable elements can lead to

touchcancel (in old Chrome/Browser versions)

•   not all browsers consistently send touchmove•   differences in focus / blur and some mouse compatibility events

(e.g. mouseenter / mouseleave )

•   some events may only fire when tapping away to another focusable

element (e.g. blur )

some browsers outright weird...

Browser/Android 4.3mouseover > mousemove > touchstart > touchend >

mousedown > mouseup > click

Browser/Blackberry PlayBook 2.0touchstart > mouseover > mousemove > mousedown >

touchend > mouseup > click

UC Browser 10.8/Android 6mouseover > mousemove > touchstart > (touchmove)+ > touchend >

mousedown > focus > mouseup > click

Touch/pointer events test results

shouldn't affect your code,unless you're expecting a very

specific sequence...

<interlude >simple feature detection for

touch events

/� feature detection for touch events */ if ( 'ontouchstart' in window ) { /* some clever stuff here */ } /* older browsers have flaky support so more hacky tests needed...use Modernizr.touch or similar */

patrickhlauke.github.io/touch/tests/touch-feature-detect.html

/* conditional "touch OR mouse/keyboard" event binding */ if ('ontouchstart' in window) { // set up event listeners for touch ... } else { // set up event listeners for mouse/keyboard ... }

don't make it touch-exclusive

hybrid devices touch + mouse + keyboard

@patrick_h_lauke showing a naive "touch or mouse" issue on Flickr (which has since been fixed)

Bug 888304 - touch-events on Firefox-desktop should be disabled until we can support themproperly

Issue 392584: TouchEvent API should be enabled consistently

Chrome now returns window.TouchEvent on non-touch devicespatrickhlauke.github.io/touch/tests/touch-feature-detect.html

even on "mobile" we can havemultiple inputs...

Android + mouse – like touch (mouse emulating touch)touchstart > touchend > mouseover > mousemove > mousedown >

(focus) > mouseup > click

Blackberry PlayBook 2.0 + mouse – like desktopmouseover > mousedown > (mousemove)+ > mouseup > click

Blackberry Leap (BBOS 10.1) + mouse – like desktopmouseover > mousedown > (mousemove)+ > mouseup > click

Windows 10 Mobile/Microsoft Edge + mouse – like desktopmouse events (+ pointer events) + click

Windows 10 Mobile/Microsoft Edge + keyboard – like desktopfocus > click

Android + keyboard – like desktopfocus > click

iOS keyboard only works insame situations as on-screen

keyboard (e.g. text inputs, URL entry)

VoiceOver enables full keyboard access on iOS

iOS + keyboard – similar to touchfocus � touchstart > touchend > (mouseenter) > mouseover >

mousemove > mousedown > blur > mouseup > click

further scenarios?•   desktop with external touchscreen

•   touchscreen laptop with non-touch second screen

•   touchscreen laptop with trackpad/mouse

•   ...and other permutations?

no way to detect these cases...

Modernizr.touch detects touch events not touch devices

Stu Cox: “ou can't detect a touchscreen

hacks.mozilla.org - Detecting touch [...]

/* feature detection for touch events */ if ('ontouchstart' in window) { /* browser supports touch events but user is not necessarily using touch (exclusively) */ /* it could be a mobile, tablet, desktop, fridge ... */ }

touch or mouse or keyboard

touch and mouse and keyboard

what about CSS4 Media Queries?

W3C Media Queries Level 4 (Editor's Draft)

/* MQ4 Interaction Media Features*/ pointer: none | coarse | fine hover: none | hover any-pointer: none | coarse | fine any-hover: none | hover

hover: on-demand / any-hover: on-demand removed in recent drafts

dev.opera - Interaction Media Features and their potential (for incorrect assumptions)

patrickhlauke.github.io/touch/pointer-hover-any-pointer-any-hoverprimary input is unchanged (and Chrome/Android required a full restart)

/* Naive uses of Interaction Media Features */ @media (pointer: fine) { /* primary input has fine pointer precision... so make all buttons/controls small? */ } @media (hover: hover) { /* primary input has hover...so we can rely on it? */ } /* pointer and hover only check "primary" input, but what if there's a secondary input that lacks capabilities? */

/* Better uses of Interaction Media Features */ @media (any-pointer: coarse) { /* at least one input has coarse pointer precision... provide larger buttons/controls for touch */ } /* test for *any* "least capable" inputs (primary or not) */

Limitation: [mediaqueries-4] any-hover can't be used to detect mixed hover and non-hover

capable pointers. Also, pointer / hover / any-pointer / any-hover don't cover non-pointerinputs (e.g. keyboards) – always assume non-hover-capable inputs

@media (any-hover: none) {/* at least one input lacks hover capability...

don't rely on it or avoid altogether */}

detect which input the users isusing right now...

GitHub: ten1seven / what-input

Demo: What Input?

if in doubt, offer a way to switch interfaces... or just always use a touch-optimised interface

<� interlude >

touch events vs

limitations/problems

1.  delayed event dispatch2.  mousemove doesn't track

1.  delayed event dispatch2.  mousemove doesn't track

patrickhlauke.github.io/touch/tests/event-listener_show-delay.htmlless of a problem in modern browsers, but for iOS < 9.3 or older Androids still relevant

why the delay? double-tap to zoom

(mostly anyway)

when does the delay happen?

patrickhlauke.github.io/touch/tests/event-listener.html

touch / mouse events delaytouchstart > [touchmove]+ > touchend >

[300ms delay] (mouseenter) > mouseover > mousemove > mousedown >

(focus) > mouseup > click

how can we make it feelresponsive like a native app?

react to events fired before the300ms delay...

touchstart for animmediate control (e.g. fire/jump button on a game)

touchend for a control thatfires after finger lifted

(but this can result in events firing after zoom/scroll)

don't make it touch-exclusive

/* DON'T DO THIS: conditional "touch OR mouse/keyboard" event binding */ if ('ontouchstart' in window) { // set up event listeners for touch foo.addEventListener('touchend', ...); ... } else { // set up event listeners for mouse/keyboard foo.addEventListener('click', ...); ... }

patrickhlauke.github.io/touch/tests/event-listener_naive-touch-or-mouse.html

/* DO THIS: doubled-up "touch AND mouse/keyboard" event binding */ // set up event listeners for touch foo.addEventListener('touchend', ...); // set up event listeners for mouse/keyboard foo.addEventListener('click', ...); /* but this would fire our function twice for touch? */

patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling.html

/* DO THIS: doubled-up "touch AND mouse/keyboard" event binding */ // set up event listeners for touch foo.addEventListener('touchend', function(e) { // prevent compatibility mouse events and click e.preventDefault(); ... }); // set up event listeners for mouse/keyboard foo.addEventListener('click', ...);

patrickhlauke.github.io/touch/tests/event-listener_naive-event-doubling-fixed.html

preventDefault() kills scrolling, pinch/zoom, etc

apply preventDefault()carefully

(just on buttons/links, not entire page)

github.com/ftlabs/fastclick

patrickhlauke.github.io/touch/fastclick“ouTube: iOS/Safari 300ms click delay: vanilla Bootstrap and using fastclick.js

patrickhlauke.github.io/touch/fastclick/fastclick.html“ouTube: iOS/Safari 300ms click delay: vanilla Bootstrap and using fastclick.js

browsers working to removedouble-tap to zoom delay

non-scalable/zoomableviewport and

"double-tap to zoom"

<meta name="viewport" content="user-scalable=no">patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html

Changeset 191072 - Web pages with unscalable viewports shouldn't have a single tap delay(from iOS 9.3 onwards)

what about accessibility?

Chrome: Settings > Accessibility > Force enable zoom

Opera: Settings > Force enable zoom

Firefox: Settings > Accessibility > Always enable zoom

Samsung Internet: Internet settings > Manual zoom

"Force enable zoom" reintroduces delay – a fair compromise?patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html

@thomasfuchs - Safari/iOS10beta3 ignores unscalable viewports(no official Apple documentation about the change...but the 300ms delay is back)

Windows 10 build 15007 on Mobile ignores unscalable viewports

"mobile optimised" viewportand

"double-tap to zoom"

Chrome 32+ / Android: content="width=device-width" suppresses double-tap-to-zoom, still allows pinch zoom

Google Developers: 300ms tap delay, gone away

Bug 941995 - Remove 300ms [...] on "responsive" pages[RESOLVED FIXED]

WebKit blog: More Responsive Tapping on iOS

patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay

suppressing 300ms delayif your code does rely on handling click / mouse events:

•   "mobile optimised" <meta name="viewport"content="width=device-width">

•   add touch-action:manipulation in CSS (part of Pointer Events)

•   use helper library like fastclick.js for older browsers

•   make your viewport non-scalable...

1.  delayed event dispatch2.  mousemove doesn't track

patrickhlauke.github.io/touch/particle/2

patrickhlauke.github.io/touch/particle/2

events fired on taptouchstart > [touchmove]+ > touchend >

(mouseenter) > mouseover > mousemove* > mousedown > (focus) >

mouseup > click* mouse event emulation fires only a single mousemove

too many touchmove events prevent mouse compatibility events after touchend

doubling up handling ofmousemove and touchmove

�ar posX, posY; function positionHandler(e) { posX = e.clientX ; posY = e.clientY ; } canvas.addEventListener(' mousemove ', positionHandler, false);

�ar posX, posY; function positionHandler(e) { posX = e.clientX ; posY = e.clientY ; } canvas.addEventListener(' mousemove ', positionHandler, false); canvas.addEventListener(' touchmove ', positionHandler, false); /* but this won't work for touch... */

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; // [DOM4] UI Events readonly attribute unsigned short buttons; };

www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEventwww.w3.org/TR/uievents/#events-mouseevents

partial interface MouseEvent { readonly attribute double screenX; readonly attribute double screenY; readonly attribute double pageX ; readonly attribute double pageY ; readonly attribute double clientX; readonly attribute double clientY; readonly attribute double x ; readonly attribute double y ; readonly attribute double offsetX ; readonly attribute double offsetY ; };

www.w3.org/TR/cssom-view/#extensions-to-the-mouseevent-interface

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; };

www.w3.org/TR/touch-events/#touchevent-interface

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 ; };

www.w3.org/TR/touch-events/#touch-interface

TouchList differencestouches

all touch points on screen

targetTouchesall touch points that started on the element

changedTouchestouch points that caused the event to fire

patrickhlauke.github.io/touch/touchlist-objects

�ar 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 );

patrickhlauke.github.io/touch/particle/3

patrickhlauke.github.io/touch/paranoid_0.5www.splintered.co.uk/experiments/archives/paranoid_0.5

patrickhlauke.github.io/touch/picture-slider

tracking finger movement overtime ... swipe gestures

patrickhlauke.github.io/touch/swipe

/* Swipe detection from basic principles */ Δt = end.time - start.time; Δx = end.x - start.x; Δy = end.y - start.y; if (( Δt > timeThreshold ) || ( (Δx + Δy) < distanceThreshold )) { /* too slow or movement too small */ } else { /* it's a swipe! - use �x and �y to determine direction - pythagoras √( �x² + �y² ) for distance - distance/�t to determine speed */ }

don't forget mouse/keyboard!

touchmove fires...a lot!

do absolute minimum on eachtouchmove

(usually: store coordinates)

do heavy lifting (drawing etc.)separately, avoid queueing

(e.g. using setTimeout and/or requestAnimationFrame )

debounce / throttle events

GitHub: m-gagne / limit.js

patrickhlauke.github.io/touch/touch-limit

why stop at a single point? multitouch support

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; };

www.w3.org/TR/touch-events/#touchevent-interface

/* iterate over relevant TouchList */ for (i=0; i< e.targetTouches .length; i++) { ... posX = e.targetTouches[i].clientX ; posY = e.targetTouches[i].clientY ; ... }

patrickhlauke.github.io/touch/tracker/multi-touch-tracker.html

iOS/iPad preventDefault()can't override 4-finger gestures

iOS7+ Safari/WebViewpreventDefault() can't

override edge swipes

multitouch gestures

/* iOS/Safari/WebView has gesture events for size/rotation, not part of the W3C Touch Events spec. */ /* gesturestart / gesturechange / gestureend */ foo.addEventListener('gesturechange', function(e) { /* e.scale e.rotation */ /* values can be plugged directly into CSS transforms etc */ }); /* not supported in Chrome/Firefox/Opera */

iOS Developer Library - Safari Web Content Guide - Handling gesture events

/* Pinch/rotation detection from basic principles */ Δx = x2 - x1; Δy = y2 - y1;

/* pythagoras √( �x² + �y² ) to calculate distance */ Δd = Math.sqrt( (Δx * Δx) + (Δy * Δy) );

/* trigonometry to calculate angle */ α = Math.atan2( Δy, Δx );

Mozilla Developer Network: Math.atan2()

patrickhlauke.github.io/touch/picture-organiser

Touch Events specification grey areas...

do touch events fire duringscroll/zoom?

not defined in spec (yet), but de facto yes in most modern browsers

patrickhlauke.github.io/touch/gesture-touch

Touch Events extensions...

W3C Touch Events Extensions WG Note

/* Extension to touch objects */ partial interface Touch { readonly attribute float radiusX; readonly attribute float radiusY; readonly attribute float rotationAngle; readonly attribute float force; };

/* Touch Events – contact geometry */ partial interface Touch { readonly attribute float radiusX ; readonly attribute float radiusY ; readonly attribute float rotationAngle ; readonly attribute float force; };

patrickhlauke.github.io/touch/tracker/tracker-radius-rotationangle.html“ouTube: Touch Events: radiusX, radius“ and rotationAngle

/* Touch Events – force */ partial interface Touch { readonly attribute float radiusX; readonly attribute float radiusY; readonly attribute float rotationAngle; readonly attribute float force ; };

force : value in range 0 – 1 . if no hardware support 0 (some devices, e.g. Nexus 10, "fake" force based on radiusX / radiusY )

patrickhlauke.github.io/touch/tracker/tracker-force-pressure.htmliPhone 6s with 3D Touch supports force ...

(Safari and WKWebView, e.g. Chrome/iOS, but not UIWebView, e.g. Firefox/iOS)

W3C Touch Events Level 2 (Editor's Draft)(merges errata, touch events extensions, fractional touch coordinates)

Pointer Events

up to IE9 (Win7 / WinPhone7.5)only mouse events

in IE10 Microsoft introducedPointer Events

unifies mouse, touch and pen input into a single event model

...and some new inputs (though currently mapped to mouse)Building Xbox One Apps using HTML and JavaScript

“ouTube: Xbox One Edge Browser sends Pointer Events

not just some not invented here

technology

submitted by Microsoft as W3C Candidate REC 09 May 2013

Pointer Events - W3C REC 24 February 2015

work now continues to enhance/expand Pointer Events...W3C Pointer Events Level 2 (Editor's Draft)

caniuse.com: Can I use pointer events?

Bug 822898 - Implement pointer events

about:config � dom.w3c_pointer_events.enabled

...what about Apple?

Microsoft submitted a proof of concept WebKit patchhtml5labs.interoperabilitybridges.com/prototypes/...

Bug 105463 - Implement pointer events RESOLVED WONTFIX

Maciej Stachowiak - [webkit-dev] pointer events specification - first editors draft

@patrick_h_lauke paraphrasing Apple's stance on Pointer Events...

Apple Pencil currentlyindistinguishable from touch

in browser / JavaScript (no tilt information, fires touch events)

the anatomy of Pointer Events (sequence, event object, ...)

patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html

events fired on tap (Edge)mousemove* >

pointerover > mouseover > pointerenter > mouseenter > pointerdown > mousedown >

focus gotpointercapture >

pointermove > mousemove > pointerup > mouseup > lostpointercapture >

click > pointerout > mouseout > pointerleave > mouseleave

mouse events fired inline with pointer events (for a primary pointer, e.g. first finger on screen)

IE10/IE11 quirks•   vendor-prefixed in IE10 ( MSPointerDown ...,

navigator.msMaxTouchPoints , -ms-touch-action )

•   unprefixed in IE11 (but prefixed versions mapped for compatibility)

•   event order (when click is fired) incorrect in IE10/IE11

see W3C Pointer Events WG mailing list - Jacob Rossi (Microsoft)

Chrome, Edge (on mobile), IE11 (Windows Phone 8.1update1) support both Touch Events and Pointer Events

w3c.github.io/pointerevents/#mapping-for-devices-that-do-not-support-hover

patrickhlauke.github.io/touch/tests/event-listener_all-no-timings.html

about:flags in Microsoft Edge to turn on touch events on desktop(e.g. touch-enabled laptops) – off by default for site compatibility

... when touch events alsosupported (Edge)

pointerover > pointerenter > pointerdown > touchstart > pointerup > touchend >

mouseover > mouseenter > mousemove > mousedown > focus > mouseup > click >

pointerout > pointerleaveSpecific order of events is not defined in the spec in this case – will vary between browsers...

only problem if handling both pointer events and mouse events (which is nonsensical)

/* Pointer Events extend Mouse Events vs Touch Events and their new objects / TouchLists / Touches */ interface PointerEvent : MouseEvent { readonly attribute long pointerId; readonly attribute long width; readonly attribute long height; readonly attribute float pressure; readonly attribute float tangentialPressure; /* Level 2 */ readonly attribute long tiltX; readonly attribute long tiltY; readonly attribute long twist; /* Level 2 */ readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }

/* plus all MouseEvent attributes: clientX , clientY , etc */

handling mouse input isexactly the same as traditional

mouse events (only change pointer* instead of mouse* event names)

handling touch or stylus isalso exactly the same astraditional mouse events

(mouse code can be adapted to touch/stylus quickly)

simple feature detection forpointer events

/* detecting pointer events support */ if ( window.PointerEvent ) { /* some clever stuff here but this covers touch, stylus, mouse, etc */ } /* still listen to click for keyboard! */

"don't forget about keyboard users" note in Pointer Events spec

/* detect maximum number of touch points */ if ( navigator.maxTouchPoints > 0 ) { /* device with a touchscreen */ } if ( navigator.maxTouchPoints > 1 ) { /* multitouch-capable device */ }

"you can detect a touchscreen" ...but user may still use other input mechanisms

patrickhlauke.github.io/touch/tests/pointer-multitouch-detect.html

do pointer events fire duringscroll/zoom?

w3c.github.io/pointerevents/#the-pointercancel-event

once a browser handles scrolling, it sends pointercancelpatrickhlauke.github.io/touch/gesture-touch/pointerevents.html

pointer events vs

limitations/problems of mouseevent emulation

1.  delayed event dispatch2.  mousemove doesn't track

1.  delayed event dispatch2.  mousemove doesn't track

patrickhlauke.github.io/touch/tests/event-listener.html

(IE11/WinPhone 8.1 Update no optimization for width=device-width )

patrickhlauke.github.io/touch/tests/event-listener.html(IE/Win8 has double-tap to zoom, so problem on desktop too)

patrickhlauke.github.io/touch/tests/event-listener.html(Microsoft Edge/Win10 has double-tap to zoom, so problem on desktop too)

pointer / mouse events and delay

[300ms delay] click ...

300ms delay just before click event

how can we make it feelresponsive like a native app?

we could try a similarapproach to touch events...

•   double-up pointerup and click listeners?

•   prevent code firing twice with preventDefault ?

won't work: preventDefault() stops mouse compatibility events, butclick is not considered mouse compatibility event

a more declarative approach with touch-action

CSS propertywhat action should the browser handle?

touch-action: auto | none | [ pan-x || pan-y ] | manipulationwww.w3.org/TR/pointerevents/#the-touch-action-css-property

only determines default touch action, does not stop compatibilitymouse events nor click

Pointer Events Level 2expanded set of values (useful for pull-to-refresh, carousels, etc)

touch-action: auto | none | [ [ pan-x | pan-left | pan-right ] || [ pan-y | pan-up | pan-down ] ] | manipulation

w3c.github.io/pointerevents/#the-touch-action-css-property

compat.spec.whatwg.org add extra value pinch-zoom

patrickhlauke.github.io/touch/touch-action-scrolling

touch-action:none(suppress all default browser behaviour)

patrickhlauke.github.io/touch/tests/event-listener_touch[...]

touch-action:none killsscrolling, long-press,

pinch/zoom

touch-action:manipulation(suppress double-tap-to-zoom)

patrickhlauke.github.io/touch/tests/event-listener_touch[...]

caniuse.com: Can I use touch-action?

browsers working to removedouble-tap to zoom delay

(when page not zoomable)

<meta name="viewport" content="user-scalable=no">patrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html

"Allow zooming on all web content" reintroduces delaypatrickhlauke.github.io/touch/tests/event-listener_user-scalable-no.html

"Allow zooming..." option currently missing in Win 10 Mobile

Windows 10 build 15007 on Mobile ignores unscalable viewportsno delay until user zooms for first time...

width=device-width still has delay in IE11/WinPhone 8.1 Updatepatrickhlauke.github.io/touch/tests/event-listener_width-device-width.html

Microsoft Edge removes delay for width=device-widthpatrickhlauke.github.io/touch/tests/event-listener_width-device-width.html

patrickhlauke.github.io/touch/tests/results/#suppressing-300ms-delay

1.  delayed event dispatch2.  mousemove doesn't track

just listen to pointermove ...

no need for separate mouse ortouch event listeners

/* touch events: separate handling */ foo.addEventListener('touchmove', ... , false); foo.addEventListener('mousemove', ... , false);

/* pointer events: single listener for mouse, stylus, touch */ foo.addEventListener(' pointermove ', ... , false);

no need for separate mouse ortouch code to get x / y coords

/* Reminder: Touch Events need separate code for x / y coords */ 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; ... } } canvas.addEventListener('mousemove', positionHandler, false ); canvas.addEventListener('touchmove', positionHandler, false );

/* Pointer Events extend Mouse Events */ foo.addEventListener(' pointermove ', function(e) { ... posX = e.clientX ; posY = e.clientY ; ... }, false);

www.w3.org/TR/pointerevents/#pointerevent-interface

3D Rotator by Creative Punchcoded to only use mouse events

3D Rotator modified to use Pointer Eventsminimal code changes, as Pointer Events extend mouse events

but you can distinguish mouse or touch or stylus

foo.addEventListener('pointermove', function(e) { ... switch( e.pointerType ) { case ' mouse ': ... break; case ' pen ': ... break; case ' touch ': ... break; default : /* future-proof */ } ... } , false);

what about multitouch?

/* PointerEvents don't have the handy TouchList objects, so we have to replicate something similar... */ ar 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 ': case ' pointercancel ': /* remove the relevant array entry */ break; }

patrickhlauke.github.io/touch/tracker/multi-touch-tracker-pointer-hud.html(note multiple isPrimary pointers, per pointer type)

/* like iOS/Safari, IE/Win has higher-level gestures , but these are not part of the W3C Pointer Events spec. Replicate these from basic principles again... */

MSDN IE10 Developer Guide: Gesture object and events

extended capabilities (if supported by hardware)

/* Pointer Events - pressure */ interface PointerEvent : MouseEvent { readonly attribute long pointerId; readonly attribute long width; readonly attribute long height; readonly attribute float pressure ; readonly attribute float tangentialPressure; readonly attribute long tiltX; readonly attribute long tiltY; readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }

pressure : value in range 0 – 1 . if no hardware support, 0.5 in active button state, 0 otherwise

patrickhlauke.github.io/touch/tracker/...“ouTube: Touch tracker with Surface 3 pen

hovering stylus•   hardware-dependant

•    pointermove fires

•    pressure == 0 (non-active button state)

•   track pointerdown / pointerup to be safe

/* Pointer Events - contact geometry */ interface PointerEvent : MouseEvent { readonly attribute long pointerId; readonly attribute long width ; readonly attribute long height ; readonly attribute float pressure; readonly attribute float tangentialPressure; readonly attribute long tiltX; readonly attribute long tiltY; readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }

if hardware can't detect contact geometry, either 0 or "best guess" (e.g. for mouse/stylus, return width / height of 1 )

patrickhlauke.github.io/touch/tracker/tracker-width-height.html“ouTube: Pointer Events width and height ...

/* Pointer Events - tilt */ interface PointerEvent : MouseEvent { readonly attribute long pointerId; readonly attribute long width; readonly attribute long height; readonly attribute float pressure; readonly attribute float tangentialPressure; readonly attribute long tiltX ; readonly attribute long tiltY ; readonly attribute long twist; readonly attribute DOMString pointerType; readonly attribute boolean isPrimary; }

tiltX / tiltY : value in degrees -90 – 90 . returns 0 if hardware does not support tilt

patrickhlauke.github.io/touch/pen-tracker“ouTube: ...pen with tilt, pressure and hover support

patrickhlauke.github.io/touch/pen-tracker“ouTube: Chrome on Samsung Galaxy Note 4 - Pointer Events and stylus

pointermove fires if anyproperty changes,

not just x/y position ( width , height , tiltX , tiltY , pressure )

pointer events as the future?

transitional event handling (until all browsers support pointer events)

/* cover all cases (hat-tip Stu Cox) */ if (window.PointerEvent) { /* bind to Pointer Events: pointerdown, pointerup, etc */ } else { /* bind to mouse events: mousedown, mouseup, etc */ if ('ontouchstart' in window) { /* bind to Touch Events: touchstart, touchend, etc */ } } /* bind to keyboard / click */

polyfills for pointer events (code for tomorrow, today)

GitHub - jQuery Pointer Events Polyfill (PEP)

�� adding jQuery PEP *� <script src="https:��code.jquery.com�pep�0.4.1�pep.js"><�script> �* need to use custom touch-action attribute, not CSS (yet) *� <button touch-action="none" >...<�div>

patrickhlauke.github.io/touch/pep-draw

patrickhlauke.github.io/touch/pep/listener/event-listener.html

debugging/testing

nothing beats having real devices...

Chrome DevTools / Device Mode & Mobile Emulationcorrectly emulates touch and pointer events

Firefox Developer Tools > Responsive Design Modecorrectly emulates touch events

no touch emulation, nor touch events + pointer events (like on realWindows 10 Mobile) emulation, in Edge/F12 Tools

no touch emulation in Safari "Responsive Design Mode"

youtube.com/watch?v=A”KpByV5764

get in touch@patrick_h_lauke

github.com/patrickhlauke/touch patrickhlauke.github.io/getting-touchy-presentation

slideshare.net/redux paciellogroup.com

splintered.co.uk

top related