diff --git a/packages/core/src/components/gesture/gesture.tsx b/packages/core/src/components/gesture/gesture.tsx index 60743de554..46ef5700ce 100644 --- a/packages/core/src/components/gesture/gesture.tsx +++ b/packages/core/src/components/gesture/gesture.tsx @@ -156,9 +156,6 @@ export class Gesture { if (this.canStart && this.canStart(detail) === false) { return false; } - - this.positions.push(detail.currentX, detail.currentY, timeStamp); - // Release fallback this.gesture.release(); @@ -167,6 +164,7 @@ export class Gesture { return false; } + this.positions.push(detail.currentX, detail.currentY, timeStamp); if (this.pan) { this.hasStartedPan = true; this.pan.start(detail.startX, detail.startY); @@ -196,6 +194,8 @@ export class Gesture { private pointerMove(ev: UIEvent) { 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.isMoveQueued && this.hasFiredStart) { this.isMoveQueued = true; @@ -205,11 +205,12 @@ export class Gesture { return; } + // gesture is currently being detected const detail = this.detail; this.calcGestureData(ev); if (this.pan.detect(detail.currentX, detail.currentY)) { if (this.pan.isGesture() !== 0) { - if (!this.tryToCapturePan(ev)) { + if (!this.tryToCapturePan()) { this.abortGesture(); } } @@ -263,13 +264,24 @@ export class Gesture { positions.push(currentX, currentY, timestamp); } - private tryToCapturePan(ev: UIEvent): boolean { + private tryToCapturePan(): boolean { if (this.gesture && !this.gesture.capture()) { return false; } this.hasCapturedPan = true; 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) { this.onWillStart(this.detail).then(this.fireOnStart.bind(this)); } else { diff --git a/packages/core/src/components/menu/menu.tsx b/packages/core/src/components/menu/menu.tsx index 296016fed6..b633745476 100644 --- a/packages/core/src/components/menu/menu.tsx +++ b/packages/core/src/components/menu/menu.tsx @@ -199,7 +199,7 @@ export class Menu { 'gesturePriority': 10, 'type': 'pan', 'direction': 'x', - 'threshold': 5, + 'threshold': 10, 'attachTo': 'body', 'disableScroll': true, 'block': this._activeBlock @@ -328,17 +328,9 @@ export class Menu { return; } - // const isRTL = false; - const isRightSide = this.isRightSide; - 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; - + const delta = computeDelta(slide.deltaX, this._isOpen, this.isRightSide); + const stepValue = delta / this._width; this._animation.progressStep(stepValue); - // TODO: this.ionDrag.emit({ menu: this }); } _swipeEnd(slide: any) { @@ -348,9 +340,7 @@ export class Menu { return; } const isRightSide = this.isRightSide; - let delta = slide.deltaX; - delta = Math.max((isRightSide) ? -delta : delta); - + const delta = computeDelta(slide.deltaX, this._isOpen, isRightSide); const width = this._width; const stepValue = delta / width; 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';