diff --git a/packages/input/normalizer.js b/packages/input/normalizer.js index 26b9853..b27fd61 100644 --- a/packages/input/normalizer.js +++ b/packages/input/normalizer.js @@ -4,6 +4,28 @@ const decorate = compose( EventEmitter, ); +class PointerEvent { + + constructor(event) { + this.nativeEvent = event; + if (window.PointerEvent && event instanceof window.PointerEvent) { + this.position = [ + event.clientX, + event.clientY, + ]; + } + else if (window.TouchEvent && event instanceof window.TouchEvent) { + const touches = event.changedTouches; + const touch = touches[0]; + this.position = [ + touch.clientX, + touch.clientY, + ]; + } + } + +} + export class InputNormalizer extends decorate(class{}) { constructor() { @@ -18,12 +40,22 @@ export class InputNormalizer extends decorate(class{}) { this.onBlur = this.onBlur.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onKeyUp = this.onKeyUp.bind(this); + this.onPointerDown = this.onPointerDown.bind(this); + this.onPointerMove = this.onPointerMove.bind(this); + this.onPointerUp = this.onPointerUp.bind(this); + this.onTouchStart = this.onTouchStart.bind(this); + this.onTouchMove = this.onTouchMove.bind(this); + this.onTouchEnd = this.onTouchEnd.bind(this); } actionForKey(key) { return this.mapKeyToAction[key]; } + destroy() { + this.stopListening(); + } + listen(target = window.document, targetForKeyUp = window.document) { // Only listen once. if (this.target) { @@ -34,6 +66,18 @@ export class InputNormalizer extends decorate(class{}) { this.target.addEventListener('blur', this.onBlur); this.target.addEventListener('keydown', this.onKeyDown); this.targetForKeyUp.addEventListener('keyup', this.onKeyUp); + // Listen for pointer events if they exist. + if ('undefined' !== typeof window.PointerEvent) { + this.target.addEventListener('pointerdown', this.onPointerDown); + this.target.addEventListener('pointermove', this.onPointerMove); + window.addEventListener('pointerup', this.onPointerUp); + } + // Otherwise, use touch events. (lol Apple) + else { + this.target.addEventListener('touchstart', this.onTouchStart); + this.target.addEventListener('touchmove', this.onTouchMove); + window.addEventListener('touchend', this.onTouchEnd); + } } onBlur(event) { @@ -62,6 +106,30 @@ export class InputNormalizer extends decorate(class{}) { }, 20); } + onPointerDown(event) { + this.emit('pointerDown', new PointerEvent(event)); + } + + onPointerMove(event) { + this.emit('pointerMove', new PointerEvent(event)); + } + + onPointerUp(event) { + this.emit('pointerUp', new PointerEvent(event)); + } + + onTouchStart(event) { + this.emit('pointerDown', new PointerEvent(event)); + } + + onTouchMove(event) { + this.emit('pointerMove', new PointerEvent(event)); + } + + onTouchEnd(event) { + this.emit('pointerUp', new PointerEvent(event)); + } + setAllKeysUp() { this.keysDown = {}; for (const key in this.keyUpDelays) { @@ -80,6 +148,18 @@ export class InputNormalizer extends decorate(class{}) { this.target.removeEventListener('blur', this.onBlur); this.target.removeEventListener('keydown', this.onKeyDown); this.targetForKeyUp.removeEventListener('keyup', this.onKeyUp); + // Listen for pointer events if they exist. + if ('undefined' !== typeof window.PointerEvent) { + this.target.removeEventListener('pointerdown', this.onPointerDown); + this.target.removeEventListener('pointermove', this.onPointerMove); + window.removeEventListener('pointerup', this.onPointerUp); + } + // Otherwise, use touch events. (lol Apple) + else { + this.target.removeEventListener('touchstart', this.onTouchStart); + this.target.removeEventListener('touchmove', this.onTouchMove); + window.removeEventListener('touchend', this.onTouchEnd); + } this.target = undefined; this.targetForKeyUp = undefined; }