mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-23 14:01:20 +08:00
@ -6,33 +6,22 @@ import { Animation, AnimationBuilder, NavDirection, NavOptions } from '../interf
|
|||||||
const iosTransitionAnimation = () => import('./animations/ios.transition');
|
const iosTransitionAnimation = () => import('./animations/ios.transition');
|
||||||
const mdTransitionAnimation = () => import('./animations/md.transition');
|
const mdTransitionAnimation = () => import('./animations/md.transition');
|
||||||
|
|
||||||
export function transition(opts: TransitionOptions): Promise<Animation | null> {
|
export function transition(opts: TransitionOptions): Promise<TransitionResult> {
|
||||||
return new Promise(resolve => {
|
return new Promise((resolve, reject) => {
|
||||||
opts.queue.write(async () => {
|
opts.queue.write(() => {
|
||||||
beforeTransition(opts);
|
beforeTransition(opts);
|
||||||
|
runTransition(opts).then(result => {
|
||||||
const animationBuilder = await getAnimationBuilder(opts);
|
if (result.animation) {
|
||||||
const ani = (animationBuilder)
|
result.animation.destroy();
|
||||||
? animation(animationBuilder, opts)
|
}
|
||||||
: noAnimation(opts); // fast path for no animation
|
afterTransition(opts);
|
||||||
|
resolve(result);
|
||||||
resolve(ani);
|
}, error => {
|
||||||
|
afterTransition(opts);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
async function getAnimationBuilder(opts: TransitionOptions): Promise<AnimationBuilder | undefined> {
|
|
||||||
if (!opts.leavingEl || opts.animated === false || opts.duration === 0) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (opts.animationBuilder) {
|
|
||||||
return opts.animationBuilder;
|
|
||||||
}
|
|
||||||
const builder = (opts.mode === 'ios')
|
|
||||||
? (await iosTransitionAnimation()).iosTransitionAnimation
|
|
||||||
: (await mdTransitionAnimation()).mdTransitionAnimation;
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function beforeTransition(opts: TransitionOptions) {
|
function beforeTransition(opts: TransitionOptions) {
|
||||||
@ -52,46 +41,16 @@ function beforeTransition(opts: TransitionOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setPageHidden(el: HTMLElement, hidden: boolean) {
|
async function runTransition(opts: TransitionOptions): Promise<TransitionResult> {
|
||||||
if (hidden) {
|
const animationBuilder = await getAnimationBuilder(opts);
|
||||||
el.setAttribute('aria-hidden', 'true');
|
const ani = (animationBuilder)
|
||||||
el.classList.add('ion-page-hidden');
|
? animation(animationBuilder, opts)
|
||||||
} else {
|
: noAnimation(opts); // fast path for no animation
|
||||||
el.hidden = false;
|
|
||||||
el.removeAttribute('aria-hidden');
|
return ani;
|
||||||
el.classList.remove('ion-page-hidden');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function animation(animationBuilder: AnimationBuilder, opts: TransitionOptions): Promise<Animation> {
|
async function afterTransition(opts: TransitionOptions) {
|
||||||
await waitForReady(opts, true);
|
|
||||||
|
|
||||||
const trns = await opts.animationCtrl.create(animationBuilder, opts.baseEl, opts);
|
|
||||||
fireWillEvents(opts.window, opts.enteringEl, opts.leavingEl);
|
|
||||||
await playTransition(trns, opts);
|
|
||||||
|
|
||||||
markVisible(opts);
|
|
||||||
|
|
||||||
if (trns.hasCompleted) {
|
|
||||||
fireDidEvents(opts.window, opts.enteringEl, opts.leavingEl);
|
|
||||||
}
|
|
||||||
return trns;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function noAnimation(opts: TransitionOptions): Promise<null> {
|
|
||||||
const enteringEl = opts.enteringEl;
|
|
||||||
const leavingEl = opts.leavingEl;
|
|
||||||
|
|
||||||
await waitForReady(opts, false);
|
|
||||||
|
|
||||||
markVisible(opts);
|
|
||||||
|
|
||||||
fireWillEvents(opts.window, enteringEl, leavingEl);
|
|
||||||
fireDidEvents(opts.window, enteringEl, leavingEl);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function markVisible(opts: TransitionOptions) {
|
|
||||||
const enteringEl = opts.enteringEl;
|
const enteringEl = opts.enteringEl;
|
||||||
const leavingEl = opts.leavingEl;
|
const leavingEl = opts.leavingEl;
|
||||||
if (enteringEl) {
|
if (enteringEl) {
|
||||||
@ -102,6 +61,50 @@ async function markVisible(opts: TransitionOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAnimationBuilder(opts: TransitionOptions): Promise<AnimationBuilder | undefined> {
|
||||||
|
if (!opts.leavingEl || opts.animated === false || opts.duration === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (opts.animationBuilder) {
|
||||||
|
return opts.animationBuilder;
|
||||||
|
}
|
||||||
|
const builder = (opts.mode === 'ios')
|
||||||
|
? (await iosTransitionAnimation()).iosTransitionAnimation
|
||||||
|
: (await mdTransitionAnimation()).mdTransitionAnimation;
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function animation(animationBuilder: AnimationBuilder, opts: TransitionOptions): Promise<TransitionResult> {
|
||||||
|
await waitForReady(opts, true);
|
||||||
|
|
||||||
|
const trns = await opts.animationCtrl.create(animationBuilder, opts.baseEl, opts);
|
||||||
|
fireWillEvents(opts.window, opts.enteringEl, opts.leavingEl);
|
||||||
|
await playTransition(trns, opts);
|
||||||
|
|
||||||
|
if (trns.hasCompleted) {
|
||||||
|
fireDidEvents(opts.window, opts.enteringEl, opts.leavingEl);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
hasCompleted: trns.hasCompleted,
|
||||||
|
animation: trns
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function noAnimation(opts: TransitionOptions): Promise<TransitionResult> {
|
||||||
|
const enteringEl = opts.enteringEl;
|
||||||
|
const leavingEl = opts.leavingEl;
|
||||||
|
|
||||||
|
await waitForReady(opts, false);
|
||||||
|
|
||||||
|
fireWillEvents(opts.window, enteringEl, leavingEl);
|
||||||
|
fireDidEvents(opts.window, enteringEl, leavingEl);
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasCompleted: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function waitForReady(opts: TransitionOptions, defaultDeep: boolean) {
|
async function waitForReady(opts: TransitionOptions, defaultDeep: boolean) {
|
||||||
const deep = opts.deepWait != null ? opts.deepWait : defaultDeep;
|
const deep = opts.deepWait != null ? opts.deepWait : defaultDeep;
|
||||||
const promises = deep ? [
|
const promises = deep ? [
|
||||||
@ -184,6 +187,17 @@ async function deepReady(el: Element | undefined): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setPageHidden(el: HTMLElement, hidden: boolean) {
|
||||||
|
if (hidden) {
|
||||||
|
el.setAttribute('aria-hidden', 'true');
|
||||||
|
el.classList.add('ion-page-hidden');
|
||||||
|
} else {
|
||||||
|
el.hidden = false;
|
||||||
|
el.removeAttribute('aria-hidden');
|
||||||
|
el.classList.remove('ion-page-hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setZIndex(
|
function setZIndex(
|
||||||
enteringEl: HTMLElement | undefined,
|
enteringEl: HTMLElement | undefined,
|
||||||
leavingEl: HTMLElement | undefined,
|
leavingEl: HTMLElement | undefined,
|
||||||
@ -208,3 +222,8 @@ export interface TransitionOptions extends NavOptions {
|
|||||||
enteringEl: HTMLElement;
|
enteringEl: HTMLElement;
|
||||||
leavingEl: HTMLElement | undefined;
|
leavingEl: HTMLElement | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TransitionResult {
|
||||||
|
hasCompleted: boolean;
|
||||||
|
animation?: Animation;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user