fix(menu): improves swipe gesture

This commit is contained in:
Manuel Mtz-Almeida
2017-09-16 23:09:03 -04:00
parent 9e44b281e4
commit 0fca610b7d
2 changed files with 26 additions and 20 deletions

View File

@ -156,9 +156,6 @@ export class Gesture {
if (this.canStart && this.canStart(detail) === false) { if (this.canStart && this.canStart(detail) === false) {
return false; return false;
} }
this.positions.push(detail.currentX, detail.currentY, timeStamp);
// Release fallback // Release fallback
this.gesture.release(); this.gesture.release();
@ -167,6 +164,7 @@ export class Gesture {
return false; return false;
} }
this.positions.push(detail.currentX, detail.currentY, timeStamp);
if (this.pan) { if (this.pan) {
this.hasStartedPan = true; this.hasStartedPan = true;
this.pan.start(detail.startX, detail.startY); this.pan.start(detail.startX, detail.startY);
@ -196,6 +194,8 @@ export class Gesture {
private pointerMove(ev: UIEvent) { private pointerMove(ev: UIEvent) {
assert(!!this.pan, 'pan must be non null'); assert(!!this.pan, 'pan must be non null');
// fast path, if gesture is currently captured
// do minimun job to get user-land even dispatched
if (this.hasCapturedPan) { if (this.hasCapturedPan) {
if (!this.isMoveQueued && this.hasFiredStart) { if (!this.isMoveQueued && this.hasFiredStart) {
this.isMoveQueued = true; this.isMoveQueued = true;
@ -205,11 +205,12 @@ export class Gesture {
return; return;
} }
// gesture is currently being detected
const detail = this.detail; const detail = this.detail;
this.calcGestureData(ev); this.calcGestureData(ev);
if (this.pan.detect(detail.currentX, detail.currentY)) { if (this.pan.detect(detail.currentX, detail.currentY)) {
if (this.pan.isGesture() !== 0) { if (this.pan.isGesture() !== 0) {
if (!this.tryToCapturePan(ev)) { if (!this.tryToCapturePan()) {
this.abortGesture(); this.abortGesture();
} }
} }
@ -263,13 +264,24 @@ export class Gesture {
positions.push(currentX, currentY, timestamp); positions.push(currentX, currentY, timestamp);
} }
private tryToCapturePan(ev: UIEvent): boolean { private tryToCapturePan(): boolean {
if (this.gesture && !this.gesture.capture()) { if (this.gesture && !this.gesture.capture()) {
return false; return false;
} }
this.hasCapturedPan = true; this.hasCapturedPan = true;
this.hasFiredStart = false; this.hasFiredStart = false;
this.calcGestureData(ev);
// reset start position since the real user-land event starts here
// If the pan detector threshold is big, not reseting the start position
// will cause a jump in the animation equal to the detector threshold.
// the array of positions used to calculate the gesture velocity does not
// need to be cleaned, more points in the positions array always results in a
// more acurate value of the velocity.
const detail = this.detail;
detail.startX = detail.currentX;
detail.startY = detail.currentY;
detail.startTimeStamp = detail.timeStamp;
if (this.onWillStart) { if (this.onWillStart) {
this.onWillStart(this.detail).then(this.fireOnStart.bind(this)); this.onWillStart(this.detail).then(this.fireOnStart.bind(this));
} else { } else {

View File

@ -199,7 +199,7 @@ export class Menu {
'gesturePriority': 10, 'gesturePriority': 10,
'type': 'pan', 'type': 'pan',
'direction': 'x', 'direction': 'x',
'threshold': 5, 'threshold': 10,
'attachTo': 'body', 'attachTo': 'body',
'disableScroll': true, 'disableScroll': true,
'block': this._activeBlock 'block': this._activeBlock
@ -328,17 +328,9 @@ export class Menu {
return; return;
} }
// const isRTL = false; const delta = computeDelta(slide.deltaX, this._isOpen, this.isRightSide);
const isRightSide = this.isRightSide; const stepValue = delta / this._width;
const z = this._width;
let delta = slide.deltaX;
delta = Math.max((isRightSide) ? -delta : delta);
// const z = (this.isRightSide !== isRTL ? slide.min : slide.max);
const stepValue = delta / z;
this._animation.progressStep(stepValue); this._animation.progressStep(stepValue);
// TODO: this.ionDrag.emit({ menu: this });
} }
_swipeEnd(slide: any) { _swipeEnd(slide: any) {
@ -348,9 +340,7 @@ export class Menu {
return; return;
} }
const isRightSide = this.isRightSide; const isRightSide = this.isRightSide;
let delta = slide.deltaX; const delta = computeDelta(slide.deltaX, this._isOpen, isRightSide);
delta = Math.max((isRightSide) ? -delta : delta);
const width = this._width; const width = this._width;
const stepValue = delta / width; const stepValue = delta / width;
const velocity = slide.velocityX; const velocity = slide.velocityX;
@ -591,4 +581,8 @@ export class Menu {
} }
function computeDelta(deltaX: number, isOpen: boolean, isRightSide: boolean): number {
return Math.max(0, (isOpen !== isRightSide) ? -deltaX : deltaX);
}
const GESTURE_BLOCKER = 'goback-swipe'; const GESTURE_BLOCKER = 'goback-swipe';