mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 20:33:32 +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,11 +1,14 @@
|
||||
import { writeTask } from '@stencil/core';
|
||||
|
||||
import { LIFECYCLE_DID_ENTER, LIFECYCLE_DID_LEAVE, LIFECYCLE_WILL_ENTER, LIFECYCLE_WILL_LEAVE } from '../../components/nav/constants';
|
||||
import { Animation, AnimationBuilder, NavDirection, NavOptions } from '../../interface';
|
||||
import { Animation, AnimationBuilder, IonicAnimation, NavDirection, NavOptions } from '../../interface';
|
||||
|
||||
const iosTransitionAnimation = () => import('./ios.transition');
|
||||
const mdTransitionAnimation = () => import('./md.transition');
|
||||
|
||||
// TODO: Remove when removing AnimationBuilder
|
||||
export type IonicAnimationInterface = (navEl: HTMLElement, opts: TransitionOptions) => IonicAnimation;
|
||||
|
||||
export const transition = (opts: TransitionOptions): Promise<TransitionResult> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
writeTask(() => {
|
||||
@ -43,6 +46,7 @@ const beforeTransition = (opts: TransitionOptions) => {
|
||||
|
||||
const runTransition = async (opts: TransitionOptions): Promise<TransitionResult> => {
|
||||
const animationBuilder = await getAnimationBuilder(opts);
|
||||
|
||||
const ani = (animationBuilder)
|
||||
? animation(animationBuilder, opts)
|
||||
: noAnimation(opts); // fast path for no animation
|
||||
@ -59,35 +63,50 @@ const afterTransition = (opts: TransitionOptions) => {
|
||||
}
|
||||
};
|
||||
|
||||
const getAnimationBuilder = async (opts: TransitionOptions): Promise<AnimationBuilder | undefined> => {
|
||||
const getAnimationBuilder = async (opts: TransitionOptions): Promise<IonicAnimationInterface | AnimationBuilder | undefined> => {
|
||||
if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (opts.animationBuilder) {
|
||||
return opts.animationBuilder;
|
||||
}
|
||||
const builder = (opts.mode === 'ios')
|
||||
|
||||
const getAnimation = (opts.mode === 'ios')
|
||||
? (await iosTransitionAnimation()).iosTransitionAnimation
|
||||
: (await mdTransitionAnimation()).mdTransitionAnimation;
|
||||
|
||||
return builder;
|
||||
return getAnimation;
|
||||
};
|
||||
|
||||
const animation = async (animationBuilder: AnimationBuilder, opts: TransitionOptions): Promise<TransitionResult> => {
|
||||
const animation = async (animationBuilder: IonicAnimationInterface | AnimationBuilder, opts: TransitionOptions): Promise<TransitionResult> => {
|
||||
await waitForReady(opts, true);
|
||||
|
||||
const trans = await import('../animation').then(mod => mod.create(animationBuilder, opts.baseEl, opts));
|
||||
let trans: Animation | IonicAnimation;
|
||||
|
||||
try {
|
||||
trans = await import('../animation/old-animation').then(mod => mod.create(animationBuilder as AnimationBuilder, opts.baseEl, opts));
|
||||
} catch (err) {
|
||||
trans = (animationBuilder as IonicAnimationInterface)(opts.baseEl, opts);
|
||||
}
|
||||
|
||||
fireWillEvents(opts.enteringEl, opts.leavingEl);
|
||||
await playTransition(trans, opts);
|
||||
|
||||
const didComplete = await playTransition(trans, opts);
|
||||
|
||||
// TODO: Remove AnimationBuilder
|
||||
(trans as any).hasCompleted = didComplete;
|
||||
|
||||
if (opts.progressCallback) {
|
||||
opts.progressCallback(undefined);
|
||||
}
|
||||
|
||||
if (trans.hasCompleted) {
|
||||
if ((trans as any).hasCompleted) {
|
||||
fireDidEvents(opts.enteringEl, opts.leavingEl);
|
||||
}
|
||||
|
||||
return {
|
||||
hasCompleted: trans.hasCompleted,
|
||||
hasCompleted: (trans as any).hasCompleted,
|
||||
animation: trans
|
||||
};
|
||||
};
|
||||
@ -126,15 +145,17 @@ const notifyViewReady = async (viewIsReady: undefined | ((enteringEl: HTMLElemen
|
||||
}
|
||||
};
|
||||
|
||||
const playTransition = (trans: Animation, opts: TransitionOptions): Promise<Animation> => {
|
||||
const playTransition = (trans: IonicAnimation | Animation, opts: TransitionOptions): Promise<Animation | boolean> => {
|
||||
const progressCallback = opts.progressCallback;
|
||||
const promise = new Promise<Animation>(resolve => trans.onFinish(resolve));
|
||||
|
||||
// TODO: Remove AnimationBuilder
|
||||
const promise = new Promise<Animation | boolean>(resolve => trans.onFinish(resolve));
|
||||
|
||||
// cool, let's do this, start the transition
|
||||
if (progressCallback) {
|
||||
// this is a swipe to go back, just get the transition progress ready
|
||||
// kick off the swipe animation start
|
||||
trans.progressStart();
|
||||
trans.progressStart(true);
|
||||
progressCallback(trans);
|
||||
|
||||
} else {
|
||||
@ -214,7 +235,7 @@ const setZIndex = (
|
||||
};
|
||||
|
||||
export interface TransitionOptions extends NavOptions {
|
||||
progressCallback?: ((ani: Animation | undefined) => void);
|
||||
progressCallback?: ((ani: IonicAnimation | Animation | undefined) => void);
|
||||
baseEl: any;
|
||||
enteringEl: HTMLElement;
|
||||
leavingEl: HTMLElement | undefined;
|
||||
@ -222,5 +243,5 @@ export interface TransitionOptions extends NavOptions {
|
||||
|
||||
export interface TransitionResult {
|
||||
hasCompleted: boolean;
|
||||
animation?: Animation;
|
||||
animation?: Animation | IonicAnimation;
|
||||
}
|
||||
|
Reference in New Issue
Block a user