mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
fix(nav): prevent completing transition from being interrupted (#19113)
* do not enable swipe to begin before previous one has ended * update defaults * use canStart instead * pause animations on finish * remove old pause code
This commit is contained in:
@ -18,6 +18,7 @@ export class Nav implements NavOutlet {
|
||||
|
||||
private transInstr: TransitionInstruction[] = [];
|
||||
private sbAni?: Animation | IonicAnimation;
|
||||
private animationEnabled = true;
|
||||
private useRouter = false;
|
||||
private isTransitioning = false;
|
||||
private destroyed = false;
|
||||
@ -937,6 +938,7 @@ export class Nav implements NavOutlet {
|
||||
!!this.swipeGesture &&
|
||||
!this.isTransitioning &&
|
||||
this.transInstr.length === 0 &&
|
||||
this.animationEnabled &&
|
||||
this.canGoBackSync()
|
||||
);
|
||||
}
|
||||
@ -960,6 +962,10 @@ export class Nav implements NavOutlet {
|
||||
|
||||
private onEnd(shouldComplete: boolean, stepValue: number, dur: number) {
|
||||
if (this.sbAni) {
|
||||
this.animationEnabled = false;
|
||||
this.sbAni.onFinish(() => {
|
||||
this.animationEnabled = true;
|
||||
}, { oneTimeCallback: true });
|
||||
this.sbAni.progressEnd(shouldComplete, stepValue, dur);
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
private waitPromise?: Promise<void>;
|
||||
private gesture?: Gesture;
|
||||
private ani?: IonicAnimation | Animation;
|
||||
private animationEnabled = true;
|
||||
|
||||
@Element() el!: HTMLElement;
|
||||
|
||||
@ -65,12 +66,18 @@ export class RouterOutlet implements ComponentInterface, NavOutlet {
|
||||
async componentDidLoad() {
|
||||
this.gesture = (await import('../../utils/gesture/swipe-back')).createSwipeBackGesture(
|
||||
this.el,
|
||||
() => !!this.swipeHandler && this.swipeHandler.canStart(),
|
||||
() => !!this.swipeHandler && this.swipeHandler.canStart() && this.animationEnabled,
|
||||
() => this.swipeHandler && this.swipeHandler.onStart(),
|
||||
step => this.ani && this.ani.progressStep(step),
|
||||
(shouldComplete, step, dur) => {
|
||||
if (this.ani) {
|
||||
this.animationEnabled = false;
|
||||
this.ani.onFinish(() => {
|
||||
this.animationEnabled = true;
|
||||
}, { oneTimeCallback: true });
|
||||
|
||||
this.ani.progressEnd(shouldComplete, step, dur);
|
||||
|
||||
}
|
||||
if (this.swipeHandler) {
|
||||
this.swipeHandler.onEnd(shouldComplete);
|
||||
|
@ -604,7 +604,7 @@ export const createAnimation = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const initializeCSSAnimation = () => {
|
||||
const initializeCSSAnimation = (toggleAnimationName = true) => {
|
||||
cleanUpStyleSheets();
|
||||
|
||||
elements.forEach(element => {
|
||||
@ -628,7 +628,10 @@ export const createAnimation = () => {
|
||||
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
|
||||
setStyleProperty(element, 'animation-play-state', 'paused');
|
||||
|
||||
setStyleProperty(element, 'animation-name', `${stylesheet.id}-alt`);
|
||||
if (toggleAnimationName) {
|
||||
setStyleProperty(element, 'animation-name', `${stylesheet.id}-alt`);
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
setStyleProperty(element, 'animation-name', stylesheet.id || null);
|
||||
});
|
||||
@ -660,14 +663,14 @@ export const createAnimation = () => {
|
||||
|
||||
};
|
||||
|
||||
const initializeAnimation = () => {
|
||||
const initializeAnimation = (toggleAnimationName = true) => {
|
||||
beforeAnimation();
|
||||
|
||||
if (_keyframes.length > 0) {
|
||||
if (supportsWebAnimations) {
|
||||
initializeWebAnimation();
|
||||
} else {
|
||||
initializeCSSAnimation();
|
||||
initializeCSSAnimation(toggleAnimationName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -968,7 +971,7 @@ export const createAnimation = () => {
|
||||
*/
|
||||
const play = () => {
|
||||
if (!initialized) {
|
||||
initializeAnimation();
|
||||
initializeAnimation(false);
|
||||
}
|
||||
|
||||
if (finished) {
|
||||
|
Reference in New Issue
Block a user