diff --git a/src/animations/animation.ts b/src/animations/animation.ts index 430a8728285..5d2ff897049 100644 --- a/src/animations/animation.ts +++ b/src/animations/animation.ts @@ -13,6 +13,7 @@ export class Animation { private _fx: EffectProperty[]; private _dur: number = null; private _es: string = null; + private _rvEs: string = null; private _bfSty: { [property: string]: any; }; private _bfAdd: string[]; private _bfRm: string[]; @@ -114,6 +115,9 @@ export class Animation { * not have an easing, then it'll get the easing from its parent. */ getEasing(): string { + if (this._rv && this._rvEs) { + return this._rvEs; + } return this._es !== null ? this._es : (this.parent && this.parent.getEasing()) || null; } @@ -125,6 +129,14 @@ export class Animation { return this; } + /** + * Set the easing for this reversed animation. + */ + easingReverse(name: string): Animation { + this._rvEs = name; + return this; + } + /** * Add the "from" value for a specific property. */ @@ -996,14 +1008,15 @@ export class Animation { /** * End the progress animation. */ - progressEnd(shouldComplete: boolean, currentStepValue: number, maxDelta: number = 0) { + progressEnd(shouldComplete: boolean, currentStepValue: number, dur: number = -1) { console.debug('Animation, progressEnd, shouldComplete', shouldComplete, 'currentStepValue', currentStepValue); - this._isAsync = (currentStepValue > 0.05 && currentStepValue < 0.95); - const stepValue = shouldComplete ? 1 : 0; - const factor = Math.max(Math.abs(currentStepValue - stepValue), 0.5) * 2; - const dur = 64 + factor * maxDelta; + + if (dur < 0) { + dur = this._dur; + } + this._isAsync = (currentStepValue > 0.05 && currentStepValue < 0.95 && dur > 30); this._progressEnd(shouldComplete, stepValue, dur, this._isAsync); diff --git a/src/components/menu/menu-gestures.ts b/src/components/menu/menu-gestures.ts index 7a3ae1c41fd..836ca631002 100644 --- a/src/components/menu/menu-gestures.ts +++ b/src/components/menu/menu-gestures.ts @@ -78,7 +78,7 @@ export class MenuContentGesture extends SlideEdgeGesture { 'shouldCompleteRight', shouldCompleteRight, 'currentStepValue', currentStepValue); - this.menu.swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue); + this.menu.swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue, velocity); } getElementStartPos(slide: SlideData, ev: any) { diff --git a/src/components/menu/menu-types.ts b/src/components/menu/menu-types.ts index f4ddb538916..4c4714376d3 100644 --- a/src/components/menu/menu-types.ts +++ b/src/components/menu/menu-types.ts @@ -15,10 +15,18 @@ export class MenuType { ani: Animation = new Animation(); isOpening: boolean; + constructor() { + this.ani + .easing('cubic-bezier(0.0, 0.0, 0.2, 1)') + .easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)') + .duration(280); + } + setOpen(shouldOpen: boolean, animated: boolean, done: Function) { let ani = this.ani .onFinish(done, true) .reverse(!shouldOpen); + if (animated) { ani.play(); } else { @@ -40,7 +48,7 @@ export class MenuType { this.ani.progressStep(stepValue); } - setProgressEnd(shouldComplete: boolean, currentStepValue: number, done: Function) { + setProgressEnd(shouldComplete: boolean, currentStepValue: number, velocity: number, done: Function) { let isOpen = (this.isOpening && shouldComplete); if (!this.isOpening && !shouldComplete) { isOpen = true; @@ -51,7 +59,9 @@ export class MenuType { done(isOpen); }, true); - this.ani.progressEnd(shouldComplete, currentStepValue); + let dur = this.ani.getDuration() / (Math.abs(velocity) + 1); + + this.ani.progressEnd(shouldComplete, currentStepValue, dur); } destroy() { @@ -72,11 +82,6 @@ class MenuRevealType extends MenuType { super(); let openedX = (menu.width() * (menu.side === 'right' ? -1 : 1)) + 'px'; - - this.ani - .easing('ease') - .duration(250); - let contentOpen = new Animation(menu.getContentElement()); contentOpen.fromTo('translateX', '0px', openedX); this.ani.add(contentOpen); @@ -95,10 +100,6 @@ class MenuPushType extends MenuType { constructor(menu: Menu, platform: Platform) { super(); - this.ani - .easing('ease') - .duration(250); - let contentOpenedX: string, menuClosedX: string, menuOpenedX: string; if (menu.side === 'right') { @@ -135,10 +136,6 @@ class MenuOverlayType extends MenuType { constructor(menu: Menu, platform: Platform) { super(); - this.ani - .easing('ease') - .duration(250); - let closedX: string, openedX: string; if (menu.side === 'right') { // right side diff --git a/src/components/menu/menu.scss b/src/components/menu/menu.scss index 2dcce6bfc17..8d592d4ccbe 100644 --- a/src/components/menu/menu.scss +++ b/src/components/menu/menu.scss @@ -58,6 +58,12 @@ ion-menu ion-backdrop { transform: translate3d(0, 0, 0); } +.menu-content-open { + cursor: pointer; + + touch-action: manipulation; +} + .menu-content-open ion-pane, .menu-content-open ion-content, .menu-content-open .toolbar { diff --git a/src/components/menu/menu.ts b/src/components/menu/menu.ts index 05726a87a94..52f7a202ed3 100644 --- a/src/components/menu/menu.ts +++ b/src/components/menu/menu.ts @@ -465,7 +465,7 @@ export class Menu { /** * @private */ - swipeEnd(shouldCompleteLeft: boolean, shouldCompleteRight: boolean, stepValue: number) { + swipeEnd(shouldCompleteLeft: boolean, shouldCompleteRight: boolean, stepValue: number, velocity: number) { if (!this._isAnimating) { return; } @@ -478,7 +478,7 @@ export class Menu { shouldComplete = (this.side === 'right') ? shouldCompleteRight : shouldCompleteLeft; } - this._getType().setProgressEnd(shouldComplete, stepValue, (isOpen: boolean) => { + this._getType().setProgressEnd(shouldComplete, stepValue, velocity, (isOpen: boolean) => { console.debug('menu, swipeEnd', this.side); this._after(isOpen); }); @@ -512,14 +512,9 @@ export class Menu { this._cntEle.classList.add('menu-content-open'); let callback = this.onBackdropClick.bind(this); - this._events.pointerEvents({ - element: this._cntEle, - pointerDown: callback - }); - this._events.pointerEvents({ - element: this.backdrop.getNativeElement(), - pointerDown: callback - }); + this._events.listen(this._cntEle, 'click', callback, true); + this._events.listen(this.backdrop.getNativeElement(), 'click', callback, true); + this.ionOpen.emit(true); } else { diff --git a/src/navigation/nav-controller-base.ts b/src/navigation/nav-controller-base.ts index 31e10769457..baf1b41cbcb 100644 --- a/src/navigation/nav-controller-base.ts +++ b/src/navigation/nav-controller-base.ts @@ -65,7 +65,7 @@ export class NavControllerBase extends Ion implements NavController { super(config, elementRef, renderer); this._sbEnabled = config.getBoolean('swipeBackEnabled'); - this._sbThreshold = config.getNumber('swipeBackThreshold', 40); + this._sbThreshold = config.getNumber('swipeBackThreshold', 0); this.id = 'n' + (++ctrlIds); } @@ -918,10 +918,11 @@ export class NavControllerBase extends Ion implements NavController { } } - swipeBackEnd(shouldComplete: boolean, currentStepValue: number) { + swipeBackEnd(shouldComplete: boolean, currentStepValue: number, velocity: number) { if (this._sbTrns && this._sbGesture) { // the swipe back gesture has ended - this._sbTrns.progressEnd(shouldComplete, currentStepValue, 300); + const dur = this._sbTrns.getDuration() / (Math.abs(velocity) + 1); + this._sbTrns.progressEnd(shouldComplete, currentStepValue, dur); } } diff --git a/src/navigation/swipe-back.ts b/src/navigation/swipe-back.ts index 44674c1205c..60f1afc309e 100644 --- a/src/navigation/swipe-back.ts +++ b/src/navigation/swipe-back.ts @@ -53,12 +53,13 @@ export class SwipeBackGesture extends SlideEdgeGesture { } onSlideEnd(slide: SlideData, ev: any) { + const velocity = slide.velocity; const currentStepValue = (slide.distance / slide.max); - const isResetDirecction = slide.velocity < 0; + const isResetDirecction = velocity < 0; const isMovingFast = Math.abs(slide.velocity) > 0.4; const isInResetZone = Math.abs(slide.delta) < Math.abs(slide.max) * 0.5; const shouldComplete = !swipeShouldReset(isResetDirecction, isMovingFast, isInResetZone); - this._nav.swipeBackEnd(shouldComplete, currentStepValue); + this._nav.swipeBackEnd(shouldComplete, currentStepValue, velocity); } } diff --git a/src/platform/platform-registry.ts b/src/platform/platform-registry.ts index 0f2c7e42286..18628fed19a 100644 --- a/src/platform/platform-registry.ts +++ b/src/platform/platform-registry.ts @@ -109,7 +109,6 @@ export const PLATFORM_CONFIGS: {[key: string]: PlatformConfig} = { scrollAssist: isIOS, statusbarPadding: isCordova, swipeBackEnabled: isIOS, - swipeBackThreshold: 40, tapPolyfill: isIOSUI, virtualScrollEventAssist: isIOSUI, disableScrollAssist: isIOS,