Skip to content

Commit 4be47bd

Browse files
committed
fix(animation): improve menu and go back swipe
1 parent 3b30497 commit 4be47bd

File tree

8 files changed

+49
-37
lines changed

8 files changed

+49
-37
lines changed

src/animations/animation.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export class Animation {
1313
private _fx: EffectProperty[];
1414
private _dur: number = null;
1515
private _es: string = null;
16+
private _rvEs: string = null;
1617
private _bfSty: { [property: string]: any; };
1718
private _bfAdd: string[];
1819
private _bfRm: string[];
@@ -114,6 +115,9 @@ export class Animation {
114115
* not have an easing, then it'll get the easing from its parent.
115116
*/
116117
getEasing(): string {
118+
if (this._rv && this._rvEs) {
119+
return this._rvEs;
120+
}
117121
return this._es !== null ? this._es : (this.parent && this.parent.getEasing()) || null;
118122
}
119123

@@ -125,6 +129,14 @@ export class Animation {
125129
return this;
126130
}
127131

132+
/**
133+
* Set the easing for this reversed animation.
134+
*/
135+
easingReverse(name: string): Animation {
136+
this._rvEs = name;
137+
return this;
138+
}
139+
128140
/**
129141
* Add the "from" value for a specific property.
130142
*/
@@ -996,14 +1008,15 @@ export class Animation {
9961008
/**
9971009
* End the progress animation.
9981010
*/
999-
progressEnd(shouldComplete: boolean, currentStepValue: number, maxDelta: number = 0) {
1011+
progressEnd(shouldComplete: boolean, currentStepValue: number, dur: number = -1) {
10001012
console.debug('Animation, progressEnd, shouldComplete', shouldComplete, 'currentStepValue', currentStepValue);
10011013

1002-
this._isAsync = (currentStepValue > 0.05 && currentStepValue < 0.95);
1003-
10041014
const stepValue = shouldComplete ? 1 : 0;
1005-
const factor = Math.max(Math.abs(currentStepValue - stepValue), 0.5) * 2;
1006-
const dur = 64 + factor * maxDelta;
1015+
1016+
if (dur < 0) {
1017+
dur = this._dur;
1018+
}
1019+
this._isAsync = (currentStepValue > 0.05 && currentStepValue < 0.95 && dur > 30);
10071020

10081021
this._progressEnd(shouldComplete, stepValue, dur, this._isAsync);
10091022

src/components/menu/menu-gestures.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export class MenuContentGesture extends SlideEdgeGesture {
7878
'shouldCompleteRight', shouldCompleteRight,
7979
'currentStepValue', currentStepValue);
8080

81-
this.menu.swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue);
81+
this.menu.swipeEnd(shouldCompleteLeft, shouldCompleteRight, currentStepValue, velocity);
8282
}
8383

8484
getElementStartPos(slide: SlideData, ev: any) {

src/components/menu/menu-types.ts

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,18 @@ export class MenuType {
1515
ani: Animation = new Animation();
1616
isOpening: boolean;
1717

18+
constructor() {
19+
this.ani
20+
.easing('cubic-bezier(0.0, 0.0, 0.2, 1)')
21+
.easingReverse('cubic-bezier(0.4, 0.0, 0.6, 1)')
22+
.duration(280);
23+
}
24+
1825
setOpen(shouldOpen: boolean, animated: boolean, done: Function) {
1926
let ani = this.ani
2027
.onFinish(done, true)
2128
.reverse(!shouldOpen);
29+
2230
if (animated) {
2331
ani.play();
2432
} else {
@@ -40,7 +48,7 @@ export class MenuType {
4048
this.ani.progressStep(stepValue);
4149
}
4250

43-
setProgressEnd(shouldComplete: boolean, currentStepValue: number, done: Function) {
51+
setProgressEnd(shouldComplete: boolean, currentStepValue: number, velocity: number, done: Function) {
4452
let isOpen = (this.isOpening && shouldComplete);
4553
if (!this.isOpening && !shouldComplete) {
4654
isOpen = true;
@@ -51,7 +59,9 @@ export class MenuType {
5159
done(isOpen);
5260
}, true);
5361

54-
this.ani.progressEnd(shouldComplete, currentStepValue);
62+
let dur = this.ani.getDuration() / (Math.abs(velocity) + 1);
63+
64+
this.ani.progressEnd(shouldComplete, currentStepValue, dur);
5565
}
5666

5767
destroy() {
@@ -72,11 +82,6 @@ class MenuRevealType extends MenuType {
7282
super();
7383

7484
let openedX = (menu.width() * (menu.side === 'right' ? -1 : 1)) + 'px';
75-
76-
this.ani
77-
.easing('ease')
78-
.duration(250);
79-
8085
let contentOpen = new Animation(menu.getContentElement());
8186
contentOpen.fromTo('translateX', '0px', openedX);
8287
this.ani.add(contentOpen);
@@ -95,10 +100,6 @@ class MenuPushType extends MenuType {
95100
constructor(menu: Menu, platform: Platform) {
96101
super();
97102

98-
this.ani
99-
.easing('ease')
100-
.duration(250);
101-
102103
let contentOpenedX: string, menuClosedX: string, menuOpenedX: string;
103104

104105
if (menu.side === 'right') {
@@ -135,10 +136,6 @@ class MenuOverlayType extends MenuType {
135136
constructor(menu: Menu, platform: Platform) {
136137
super();
137138

138-
this.ani
139-
.easing('ease')
140-
.duration(250);
141-
142139
let closedX: string, openedX: string;
143140
if (menu.side === 'right') {
144141
// right side

src/components/menu/menu.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ ion-menu ion-backdrop {
5858
transform: translate3d(0, 0, 0);
5959
}
6060

61+
.menu-content-open {
62+
cursor: pointer;
63+
64+
touch-action: manipulation;
65+
}
66+
6167
.menu-content-open ion-pane,
6268
.menu-content-open ion-content,
6369
.menu-content-open .toolbar {

src/components/menu/menu.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ export class Menu {
465465
/**
466466
* @private
467467
*/
468-
swipeEnd(shouldCompleteLeft: boolean, shouldCompleteRight: boolean, stepValue: number) {
468+
swipeEnd(shouldCompleteLeft: boolean, shouldCompleteRight: boolean, stepValue: number, velocity: number) {
469469
if (!this._isAnimating) {
470470
return;
471471
}
@@ -478,7 +478,7 @@ export class Menu {
478478
shouldComplete = (this.side === 'right') ? shouldCompleteRight : shouldCompleteLeft;
479479
}
480480

481-
this._getType().setProgressEnd(shouldComplete, stepValue, (isOpen: boolean) => {
481+
this._getType().setProgressEnd(shouldComplete, stepValue, velocity, (isOpen: boolean) => {
482482
console.debug('menu, swipeEnd', this.side);
483483
this._after(isOpen);
484484
});
@@ -512,14 +512,9 @@ export class Menu {
512512

513513
this._cntEle.classList.add('menu-content-open');
514514
let callback = this.onBackdropClick.bind(this);
515-
this._events.pointerEvents({
516-
element: this._cntEle,
517-
pointerDown: callback
518-
});
519-
this._events.pointerEvents({
520-
element: this.backdrop.getNativeElement(),
521-
pointerDown: callback
522-
});
515+
this._events.listen(this._cntEle, 'click', callback, true);
516+
this._events.listen(this.backdrop.getNativeElement(), 'click', callback, true);
517+
523518
this.ionOpen.emit(true);
524519

525520
} else {

src/navigation/nav-controller-base.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class NavControllerBase extends Ion implements NavController {
6565
super(config, elementRef, renderer);
6666

6767
this._sbEnabled = config.getBoolean('swipeBackEnabled');
68-
this._sbThreshold = config.getNumber('swipeBackThreshold', 40);
68+
this._sbThreshold = config.getNumber('swipeBackThreshold', 0);
6969

7070
this.id = 'n' + (++ctrlIds);
7171
}
@@ -918,10 +918,11 @@ export class NavControllerBase extends Ion implements NavController {
918918
}
919919
}
920920

921-
swipeBackEnd(shouldComplete: boolean, currentStepValue: number) {
921+
swipeBackEnd(shouldComplete: boolean, currentStepValue: number, velocity: number) {
922922
if (this._sbTrns && this._sbGesture) {
923923
// the swipe back gesture has ended
924-
this._sbTrns.progressEnd(shouldComplete, currentStepValue, 300);
924+
const dur = this._sbTrns.getDuration() / (Math.abs(velocity) + 1);
925+
this._sbTrns.progressEnd(shouldComplete, currentStepValue, dur);
925926
}
926927
}
927928

src/navigation/swipe-back.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ export class SwipeBackGesture extends SlideEdgeGesture {
5353
}
5454

5555
onSlideEnd(slide: SlideData, ev: any) {
56+
const velocity = slide.velocity;
5657
const currentStepValue = (slide.distance / slide.max);
57-
const isResetDirecction = slide.velocity < 0;
58+
const isResetDirecction = velocity < 0;
5859
const isMovingFast = Math.abs(slide.velocity) > 0.4;
5960
const isInResetZone = Math.abs(slide.delta) < Math.abs(slide.max) * 0.5;
6061
const shouldComplete = !swipeShouldReset(isResetDirecction, isMovingFast, isInResetZone);
6162

62-
this._nav.swipeBackEnd(shouldComplete, currentStepValue);
63+
this._nav.swipeBackEnd(shouldComplete, currentStepValue, velocity);
6364
}
6465
}

src/platform/platform-registry.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ export const PLATFORM_CONFIGS: {[key: string]: PlatformConfig} = {
109109
scrollAssist: isIOS,
110110
statusbarPadding: isCordova,
111111
swipeBackEnabled: isIOS,
112-
swipeBackThreshold: 40,
113112
tapPolyfill: isIOSUI,
114113
virtualScrollEventAssist: isIOSUI,
115114
disableScrollAssist: isIOS,

0 commit comments

Comments
 (0)