Created
April 11, 2017 14:43
-
-
Save DimitryDushkin/a6425d4db9b42871b1b1aa8ee8e8ec44 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
type Props = { | |
el: EventTargetWithPointerEvents, | |
onDrag: Function, | |
onDragEnd: Function, | |
onClick: Function | |
}; | |
export type GestureEvent = { | |
deltaX: number | |
}; | |
export default class Gestures { | |
onDrag: (event: GestureEvent) => any; | |
onDragEnd: (event: GestureEvent) => any; | |
onClick: (event: PointerEvent) => any; | |
el: EventTargetWithPointerEvents; | |
dragInProgress: boolean; | |
firstDragEvent: boolean; | |
startPositionX: number; | |
currentPositionX: number; | |
constructor({ el, onDrag, onDragEnd, onClick }: Props) { | |
this.el = el; | |
this.onDrag = onDrag; | |
this.onDragEnd = onDragEnd; | |
this.onClick = onClick; | |
el.setAttribute('touch-action', 'none'); // for pointer-events polyfill | |
el.addEventListener('pointerdown', this.onPointerDown.bind(this)); | |
el.addEventListener('pointermove', this.onPointerMove.bind(this)); | |
el.addEventListener('pointerup', this.onPointerUp.bind(this)); | |
el.addEventListener('pointercancel', this.onPointerUp.bind(this)); | |
el.addEventListener('pointerleave', this.onPointerUp.bind(this)); | |
this.dragInProgress = false; | |
this.firstDragEvent = true; | |
} | |
onPointerDown(e: PointerEvent) { | |
this.dragInProgress = true; | |
this.el.setPointerCapture(e.pointerId); | |
console.log('pointer down'); | |
} | |
onPointerMove(e: PointerEvent) { | |
if (!this.dragInProgress) { | |
return; | |
} | |
console.log('pointer move', e); | |
// firstDragEvent solves problem of big diff between | |
// startPositionX and currentPositionX on first pointerMove | |
// if startPositionX is set in onPointerDown | |
if (this.firstDragEvent) { | |
this.startPositionX = this.currentPositionX = e.pageX; | |
this.firstDragEvent = false; | |
} else { | |
this.currentPositionX = e.pageX; | |
} | |
this.onDrag(this.getGestureEvent()); | |
} | |
onPointerUp(e: PointerEvent) { | |
if (!this.dragInProgress) { | |
return; | |
} | |
console.log('pointer up', e); | |
// do not send dragEnd is there was no pointer move events | |
// usefull to distinct between drag and click | |
if (!this.firstDragEvent) { | |
this.onDragEnd(this.getGestureEvent()); | |
} else { | |
this.onClick(e); | |
} | |
this.dragInProgress = false; | |
this.firstDragEvent = true; | |
} | |
getGestureEvent(): GestureEvent { | |
return { | |
deltaX: this.currentPositionX - this.startPositionX | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment