mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
feat(animation): add animation utility (#18918)
* Add new keyframes proof of concept * update esm import * add base before and after methods, add tests * add base before and after hooks * update clean up methods, add tests * add web animations support, change to arrow functions * remove console logs * add from, to, fromTo, and other properties * add more tests, fix onFinish functionality, being testing with nav transitions * add progress methods, use force linear * run linter * Add playSync * integrate animations with framework components * onFinish now supports multiple callbacks * change const to let * testing reverse * add support for both animation utilities * bug fix * export createAnimation, a few tweaks * add base tests * fix issue with onFinish being called out of order. added tests * fix race conditions in tests * clean up * fix bug where onFinish not calling for empty elements array, update test * clean up * fix treeshaking, remove old comments * remove old tests * Add test for animationbuilder backwards compat * update typings for menu controller * mock web animations in tests * run build * fix type errors * sync with master * use requestAnimationFrame instead of writeTask * fix flaky tests, fix menu * fix ordering * update webdriver * fix wrong version * Revert "fix wrong version" This reverts commit be91296e9701399f8d784b08d09a3c475ca15df7. Revert chromedriver update * Revert "update webdriver" This reverts commit e49bc9d76e335a0af5828725065399bd6795fa37. Revert chromedriver update * expose raw animation object, add tests * add stylesheet recycling * finalize before and after hook tests * a few styling changes * fix lint warnings * get rid of old code * Fix progressStep overflow bug * disable reuse stylesheet * small updates * fix old animation create * setStyleProperty helper * reuse keyframe styles * keyframes * fix css animation issue with display: none, add tests * add comment * fix issue with progress animations and css animations * clean up * clean up pt2 * fix tests * fix linter * add fill for overlays * fix swipe to go back * clean up css animations when done * fix edge cases with css animations * fix menu open and close * add reset function * clean up reset fn * Fix issue where animation always being reset * allow updating animations on the fly * add clear onfinish method * fix linter * add callback options, expand force direction * ensure opts is defined * fix css animations open and close for menus * remove test * add extra check * clean up * fix css anim bug swipe to go back * fix pause * setup alt animation to avoid flickering * clean up * reset flags on destroy * add ability to change duration on progressEnd * fix flicker on duration change for css animations * fix ios transition * remove unneeded recursion * increase durability of updating css animations on the fly * fix gesture anim * fix web anim as well. more work for cleanup * simplify progressEnd for css animations * fix swipe to go back race condition * clean up * Add todo * fix one more bug
This commit is contained in:
@ -1,78 +1,78 @@
|
||||
import { Animation } from '../../interface';
|
||||
import { IonicAnimation } from '../../interface';
|
||||
import { createAnimation } from '../animation/animation';
|
||||
import { TransitionOptions } from '../transition';
|
||||
|
||||
export const shadow = <T extends Element>(el: T): ShadowRoot | T => {
|
||||
return el.shadowRoot || el;
|
||||
};
|
||||
|
||||
export const iosTransitionAnimation = (AnimationC: Animation, navEl: HTMLElement, opts: TransitionOptions): Promise<Animation> => {
|
||||
export const iosTransitionAnimation = (navEl: HTMLElement, opts: TransitionOptions): IonicAnimation => {
|
||||
try {
|
||||
const DURATION = 540;
|
||||
const EASING = 'cubic-bezier(0.32,0.72,0,1)';
|
||||
const OPACITY = 'opacity';
|
||||
const TRANSFORM = 'transform';
|
||||
const CENTER = '0%';
|
||||
const OFF_OPACITY = 0.8;
|
||||
|
||||
const DURATION = 540;
|
||||
const EASING = 'cubic-bezier(0.32,0.72,0,1)';
|
||||
const OPACITY = 'opacity';
|
||||
const TRANSFORM = 'transform';
|
||||
const TRANSLATEX = 'translateX';
|
||||
const CENTER = '0%';
|
||||
const OFF_OPACITY = 0.8;
|
||||
const isRTL = (navEl.ownerDocument as any).dir === 'rtl';
|
||||
const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
|
||||
const OFF_LEFT = isRTL ? '33%' : '-33%';
|
||||
|
||||
const backDirection = (opts.direction === 'back');
|
||||
const isRTL = (navEl.ownerDocument as any).dir === 'rtl';
|
||||
const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
|
||||
const OFF_LEFT = isRTL ? '33%' : '-33%';
|
||||
const enteringEl = opts.enteringEl;
|
||||
const leavingEl = opts.leavingEl;
|
||||
|
||||
const enteringEl = opts.enteringEl;
|
||||
const leavingEl = opts.leavingEl;
|
||||
const contentEl = enteringEl.querySelector(':scope > ion-content');
|
||||
const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
|
||||
const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
|
||||
const enteringContent = new AnimationC();
|
||||
const backDirection = (opts.direction === 'back');
|
||||
const contentEl = enteringEl.querySelector(':scope > ion-content');
|
||||
const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
|
||||
const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
|
||||
|
||||
const rootTransition = new AnimationC();
|
||||
rootTransition
|
||||
.addElement(enteringEl)
|
||||
.duration(opts.duration || DURATION)
|
||||
.easing(opts.easing || EASING)
|
||||
.beforeRemoveClass('ion-page-invisible');
|
||||
const rootAnimation = createAnimation();
|
||||
const enteringContentAnimation = createAnimation();
|
||||
|
||||
if (leavingEl && navEl) {
|
||||
const navDecor = new AnimationC();
|
||||
navDecor
|
||||
.addElement(navEl);
|
||||
rootAnimation
|
||||
.addElement(enteringEl)
|
||||
.duration(opts.duration || DURATION)
|
||||
.easing(opts.easing || EASING)
|
||||
.fill('both')
|
||||
.beforeRemoveClass('ion-page-invisible');
|
||||
|
||||
rootTransition.add(navDecor);
|
||||
}
|
||||
if (leavingEl && navEl) {
|
||||
const navDecorAnimation = createAnimation();
|
||||
navDecorAnimation.addElement(navEl);
|
||||
rootAnimation.addAnimation(navDecorAnimation);
|
||||
}
|
||||
|
||||
if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
|
||||
enteringContent.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs'));
|
||||
} else {
|
||||
enteringContent
|
||||
.addElement(contentEl)
|
||||
.addElement(headerEls);
|
||||
}
|
||||
if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
|
||||
enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs'));
|
||||
} else {
|
||||
enteringContentAnimation.addElement(contentEl);
|
||||
enteringContentAnimation.addElement(headerEls);
|
||||
}
|
||||
|
||||
rootTransition.add(enteringContent);
|
||||
rootAnimation.addAnimation(enteringContentAnimation);
|
||||
|
||||
if (backDirection) {
|
||||
enteringContent
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true)
|
||||
.fromTo(OPACITY, OFF_OPACITY, 1, true);
|
||||
} else {
|
||||
// entering content, forward direction
|
||||
enteringContent
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
|
||||
if (backDirection) {
|
||||
enteringContentAnimation
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
|
||||
.fromTo(OPACITY, OFF_OPACITY, 1);
|
||||
} else {
|
||||
// entering content, forward direction
|
||||
enteringContentAnimation
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
|
||||
}
|
||||
|
||||
if (contentEl) {
|
||||
const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
|
||||
|
||||
if (enteringTransitionEffectEl) {
|
||||
const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
|
||||
const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
|
||||
|
||||
const enteringTransitionEffect = new AnimationC();
|
||||
const enteringTransitionCover = new AnimationC();
|
||||
const enteringTransitionShadow = new AnimationC();
|
||||
const enteringTransitionEffect = createAnimation();
|
||||
const enteringTransitionCover = createAnimation();
|
||||
const enteringTransitionShadow = createAnimation();
|
||||
|
||||
enteringTransitionEffect
|
||||
.addElement(enteringTransitionEffectEl)
|
||||
@ -82,113 +82,111 @@ export const iosTransitionAnimation = (AnimationC: Animation, navEl: HTMLElement
|
||||
enteringTransitionCover
|
||||
.addElement(enteringTransitionCoverEl)
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0, 0.1, true);
|
||||
.fromTo(OPACITY, 0, 0.1);
|
||||
|
||||
enteringTransitionShadow
|
||||
.addElement(enteringTransitionShadowEl)
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0.70, 0.03, true);
|
||||
.fromTo(OPACITY, 0.03, 0.70);
|
||||
|
||||
enteringContent
|
||||
.add(enteringTransitionEffect)
|
||||
.add(enteringTransitionCover)
|
||||
.add(enteringTransitionShadow);
|
||||
enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
|
||||
enteringContentAnimation.addAnimation([enteringTransitionEffect]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enteringToolBarEls.forEach(enteringToolBarEl => {
|
||||
const enteringToolBar = new AnimationC();
|
||||
const enteringTitle = new AnimationC();
|
||||
const enteringToolBarButtons = new AnimationC();
|
||||
const enteringToolBarItems = new AnimationC();
|
||||
const enteringToolBarBg = new AnimationC();
|
||||
const enteringBackButton = new AnimationC();
|
||||
const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
|
||||
enteringToolBarEls.forEach(enteringToolBarEl => {
|
||||
const enteringToolBar = createAnimation();
|
||||
enteringToolBar.addElement(enteringToolBarEl);
|
||||
rootAnimation.addAnimation(enteringToolBar);
|
||||
|
||||
enteringToolBar.addElement(enteringToolBarEl);
|
||||
rootTransition.add(enteringToolBar);
|
||||
const enteringTitle = createAnimation();
|
||||
enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title'));
|
||||
|
||||
enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title'));
|
||||
const enteringToolBarButtons = createAnimation();
|
||||
enteringToolBarButtons.addElement(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
|
||||
|
||||
enteringToolBarButtons.addElement(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
|
||||
const enteringToolBarItems = createAnimation();
|
||||
enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
|
||||
|
||||
enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
|
||||
const enteringToolBarBg = createAnimation();
|
||||
enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background'));
|
||||
|
||||
enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background'));
|
||||
|
||||
if (backButtonEl) {
|
||||
enteringBackButton.addElement(backButtonEl);
|
||||
}
|
||||
|
||||
enteringToolBar
|
||||
.add(enteringTitle)
|
||||
.add(enteringToolBarButtons)
|
||||
.add(enteringToolBarItems)
|
||||
.add(enteringToolBarBg)
|
||||
.add(enteringBackButton);
|
||||
|
||||
enteringTitle.fromTo(OPACITY, 0.01, 1, true);
|
||||
enteringToolBarButtons.fromTo(OPACITY, 0.01, 1, true);
|
||||
enteringToolBarItems.fromTo(OPACITY, 0.01, 1, true);
|
||||
|
||||
if (backDirection) {
|
||||
enteringTitle.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true);
|
||||
|
||||
enteringToolBarItems.fromTo(TRANSLATEX, OFF_LEFT, CENTER, true);
|
||||
|
||||
// back direction, entering page has a back button
|
||||
enteringBackButton.fromTo(OPACITY, 0.01, 1, true);
|
||||
} else {
|
||||
// entering toolbar, forward direction
|
||||
enteringTitle.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
|
||||
|
||||
enteringToolBarItems.fromTo(TRANSLATEX, OFF_RIGHT, CENTER, true);
|
||||
|
||||
enteringToolBarBg
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0.01, 1, true);
|
||||
|
||||
// forward direction, entering page has a back button
|
||||
enteringBackButton.fromTo(OPACITY, 0.01, 1, true);
|
||||
const enteringBackButton = createAnimation();
|
||||
const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
|
||||
|
||||
if (backButtonEl) {
|
||||
const enteringBackBtnText = new AnimationC();
|
||||
enteringBackBtnText
|
||||
.addElement(shadow(backButtonEl).querySelector('.button-text'))
|
||||
.fromTo(TRANSLATEX, (isRTL ? '-100px' : '100px'), '0px');
|
||||
|
||||
enteringToolBar.add(enteringBackBtnText);
|
||||
enteringBackButton.addElement(backButtonEl);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// setup leaving view
|
||||
if (leavingEl) {
|
||||
const leavingContent = new AnimationC();
|
||||
const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
|
||||
enteringToolBar.addAnimation([enteringTitle, enteringToolBarButtons, enteringToolBarItems, enteringToolBarBg, enteringBackButton]);
|
||||
enteringTitle.fromTo(OPACITY, 0.01, 1);
|
||||
enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
|
||||
enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
|
||||
|
||||
leavingContent
|
||||
.addElement(leavingContentEl)
|
||||
.addElement(leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *'));
|
||||
if (backDirection) {
|
||||
enteringTitle.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
|
||||
|
||||
rootTransition.add(leavingContent);
|
||||
enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
|
||||
|
||||
if (backDirection) {
|
||||
// leaving content, back direction
|
||||
leavingContent
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(TRANSLATEX, CENTER, (isRTL ? '-100%' : '100%'));
|
||||
// back direction, entering page has a back button
|
||||
enteringBackButton.fromTo(OPACITY, 0.01, 1);
|
||||
} else {
|
||||
// entering toolbar, forward direction
|
||||
enteringTitle.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
|
||||
|
||||
enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
|
||||
|
||||
enteringToolBarBg
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0.01, 1);
|
||||
|
||||
// forward direction, entering page has a back button
|
||||
enteringBackButton.fromTo(OPACITY, 0.01, 1);
|
||||
|
||||
if (backButtonEl) {
|
||||
const enteringBackBtnText = createAnimation();
|
||||
enteringBackBtnText
|
||||
.addElement(shadow(backButtonEl).querySelector('.button-text'))
|
||||
.fromTo(`transform`, (isRTL ? 'translateX(-100px)' : 'translateX(100px)'), 'translateX(0px)');
|
||||
|
||||
enteringToolBar.addAnimation(enteringBackBtnText);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// setup leaving view
|
||||
if (leavingEl) {
|
||||
|
||||
const leavingContent = createAnimation();
|
||||
const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
|
||||
|
||||
leavingContent.addElement(leavingContentEl);
|
||||
leavingContent.addElement(leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *'));
|
||||
rootAnimation.addAnimation(leavingContent);
|
||||
|
||||
if (backDirection) {
|
||||
// leaving content, back direction
|
||||
leavingContent
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo('transform', `translateX(${CENTER})`, (isRTL ? 'translateX(-100%)' : 'translateX(100%)'));
|
||||
|
||||
} else {
|
||||
// leaving content, forward direction
|
||||
leavingContent
|
||||
.fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
|
||||
.fromTo(OPACITY, 1, OFF_OPACITY);
|
||||
}
|
||||
|
||||
if (leavingContentEl) {
|
||||
const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
|
||||
|
||||
if (leavingTransitionEffectEl) {
|
||||
const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
|
||||
const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
|
||||
|
||||
const leavingTransitionEffect = new AnimationC();
|
||||
const leavingTransitionCover = new AnimationC();
|
||||
const leavingTransitionShadow = new AnimationC();
|
||||
const leavingTransitionEffect = createAnimation();
|
||||
const leavingTransitionCover = createAnimation();
|
||||
const leavingTransitionShadow = createAnimation();
|
||||
|
||||
leavingTransitionEffect
|
||||
.addElement(leavingTransitionEffectEl)
|
||||
@ -198,104 +196,89 @@ export const iosTransitionAnimation = (AnimationC: Animation, navEl: HTMLElement
|
||||
leavingTransitionCover
|
||||
.addElement(leavingTransitionCoverEl)
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0.1, 0, true);
|
||||
.fromTo(OPACITY, 0.1, 0);
|
||||
|
||||
leavingTransitionShadow
|
||||
.addElement(leavingTransitionShadowEl)
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 0.70, 0.03, true);
|
||||
.fromTo(OPACITY, 0.70, 0.03);
|
||||
|
||||
leavingContent
|
||||
.add(leavingTransitionEffect)
|
||||
.add(leavingTransitionCover)
|
||||
.add(leavingTransitionShadow);
|
||||
leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
|
||||
leavingContent.addAnimation([leavingTransitionEffect]);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// leaving content, forward direction
|
||||
leavingContent
|
||||
.fromTo(TRANSLATEX, CENTER, OFF_LEFT, true)
|
||||
.fromTo(OPACITY, 1, OFF_OPACITY, true);
|
||||
const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
|
||||
leavingToolBarEls.forEach(leavingToolBarEl => {
|
||||
const leavingToolBar = createAnimation();
|
||||
leavingToolBar.addElement(leavingToolBarEl);
|
||||
|
||||
const leavingTitle = createAnimation();
|
||||
leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title'));
|
||||
|
||||
const leavingToolBarButtons = createAnimation();
|
||||
leavingToolBarButtons.addElement(leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
|
||||
|
||||
const leavingToolBarItems = createAnimation();
|
||||
const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
|
||||
if (leavingToolBarItemEls.length > 0) {
|
||||
leavingToolBarItems.addElement(leavingToolBarItemEls);
|
||||
}
|
||||
|
||||
const leavingToolBarBg = createAnimation();
|
||||
leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background'));
|
||||
|
||||
const leavingBackButton = createAnimation();
|
||||
const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
|
||||
if (backButtonEl) {
|
||||
leavingBackButton.addElement(backButtonEl);
|
||||
}
|
||||
|
||||
leavingToolBar.addAnimation([leavingTitle, leavingToolBarButtons, leavingToolBarItems, leavingBackButton, leavingToolBarBg]);
|
||||
rootAnimation.addAnimation(leavingToolBar);
|
||||
|
||||
// fade out leaving toolbar items
|
||||
leavingBackButton.fromTo(OPACITY, 0.99, 0);
|
||||
leavingTitle.fromTo(OPACITY, 0.99, 0);
|
||||
leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
|
||||
leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
|
||||
|
||||
if (backDirection) {
|
||||
// leaving toolbar, back direction
|
||||
leavingTitle.fromTo('transform', `translateX(${CENTER})`, (isRTL ? 'translateX(-100%)' : 'translateX(100%)'));
|
||||
leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, (isRTL ? 'translateX(-100%)' : 'translateX(100%)'));
|
||||
|
||||
// leaving toolbar, back direction, and there's no entering toolbar
|
||||
// should just slide out, no fading out
|
||||
leavingToolBarBg
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 1, 0.01);
|
||||
|
||||
if (backButtonEl) {
|
||||
const leavingBackBtnText = createAnimation();
|
||||
leavingBackBtnText.addElement(shadow(backButtonEl).querySelector('.button-text'));
|
||||
leavingBackBtnText.fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
|
||||
leavingToolBar.addAnimation(leavingBackBtnText);
|
||||
}
|
||||
|
||||
} else {
|
||||
// leaving toolbar, forward direction
|
||||
leavingTitle
|
||||
.fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
|
||||
.afterClearStyles([TRANSFORM]);
|
||||
leavingToolBarItems
|
||||
.fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
|
||||
.afterClearStyles([TRANSFORM, OPACITY]);
|
||||
|
||||
leavingBackButton.afterClearStyles([OPACITY]);
|
||||
leavingTitle.afterClearStyles([OPACITY]);
|
||||
leavingToolBarButtons.afterClearStyles([OPACITY]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
|
||||
leavingToolBarEls.forEach(leavingToolBarEl => {
|
||||
const leavingToolBar = new AnimationC();
|
||||
const leavingTitle = new AnimationC();
|
||||
const leavingToolBarButtons = new AnimationC();
|
||||
const leavingToolBarItems = new AnimationC();
|
||||
const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
|
||||
const leavingToolBarBg = new AnimationC();
|
||||
const leavingBackButton = new AnimationC();
|
||||
const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
|
||||
|
||||
leavingToolBar.addElement(leavingToolBarEl);
|
||||
|
||||
leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title'));
|
||||
|
||||
leavingToolBarButtons.addElement(leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
|
||||
|
||||
if (leavingToolBarItemEls.length > 0) {
|
||||
leavingToolBarItems.addElement(leavingToolBarItemEls);
|
||||
}
|
||||
|
||||
leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background'));
|
||||
|
||||
if (backButtonEl) {
|
||||
leavingBackButton.addElement(backButtonEl);
|
||||
}
|
||||
|
||||
leavingToolBar
|
||||
.add(leavingTitle)
|
||||
.add(leavingToolBarButtons)
|
||||
.add(leavingToolBarItems)
|
||||
.add(leavingBackButton)
|
||||
.add(leavingToolBarBg);
|
||||
|
||||
rootTransition.add(leavingToolBar);
|
||||
|
||||
// fade out leaving toolbar items
|
||||
leavingBackButton.fromTo(OPACITY, 0.99, 0);
|
||||
leavingTitle.fromTo(OPACITY, 0.99, 0);
|
||||
leavingToolBarButtons.fromTo(OPACITY, 0.99, 0, 0);
|
||||
leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
|
||||
|
||||
if (backDirection) {
|
||||
// leaving toolbar, back direction
|
||||
leavingTitle.fromTo(TRANSLATEX, CENTER, (isRTL ? '-100%' : '100%'));
|
||||
leavingToolBarItems.fromTo(TRANSLATEX, CENTER, (isRTL ? '-100%' : '100%'));
|
||||
|
||||
// leaving toolbar, back direction, and there's no entering toolbar
|
||||
// should just slide out, no fading out
|
||||
leavingToolBarBg
|
||||
.beforeClearStyles([OPACITY])
|
||||
.fromTo(OPACITY, 1, 0.01);
|
||||
|
||||
if (backButtonEl) {
|
||||
const leavingBackBtnText = new AnimationC();
|
||||
leavingBackBtnText.addElement(shadow(backButtonEl).querySelector('.button-text'));
|
||||
leavingBackBtnText.fromTo(TRANSLATEX, CENTER, (isRTL ? -124 : 124) + 'px');
|
||||
leavingToolBar.add(leavingBackBtnText);
|
||||
}
|
||||
|
||||
} else {
|
||||
// leaving toolbar, forward direction
|
||||
leavingTitle
|
||||
.fromTo(TRANSLATEX, CENTER, OFF_LEFT)
|
||||
.afterClearStyles([TRANSFORM]);
|
||||
|
||||
leavingToolBarItems
|
||||
.fromTo(TRANSLATEX, CENTER, OFF_LEFT)
|
||||
.afterClearStyles([TRANSFORM, OPACITY]);
|
||||
|
||||
leavingBackButton.afterClearStyles([OPACITY]);
|
||||
leavingTitle.afterClearStyles([OPACITY]);
|
||||
leavingToolBarButtons.afterClearStyles([OPACITY]);
|
||||
}
|
||||
});
|
||||
return rootAnimation;
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Return the rootTransition promise
|
||||
return Promise.resolve(rootTransition);
|
||||
};
|
||||
|
Reference in New Issue
Block a user