Skip to content

Instantly share code, notes, and snippets.

@DimitryDushkin
Created April 11, 2017 14:43
Show Gist options
  • Save DimitryDushkin/a6425d4db9b42871b1b1aa8ee8e8ec44 to your computer and use it in GitHub Desktop.
Save DimitryDushkin/a6425d4db9b42871b1b1aa8ee8e8ec44 to your computer and use it in GitHub Desktop.
// @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