mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
refactor(animation): update animation API (#19529)
This commit is contained in:
@ -2,21 +2,40 @@
|
||||
|
||||
import { raf } from '../helpers';
|
||||
|
||||
import { Animation, AnimationDirection, AnimationFill, AnimationOnFinishCallback, AnimationOnFinishOptions } from './animation-interface';
|
||||
import { Animation, AnimationDirection, AnimationFill, AnimationKeyFrame, AnimationKeyFrames, AnimationLifecycle, AnimationOnFinishOptions, AnimationPlayOptions } from './animation-interface';
|
||||
import { addClassToArray, animationEnd, createKeyframeStylesheet, generateKeyframeName, generateKeyframeRules, removeStyleProperty, setStyleProperty } from './animation-utils';
|
||||
|
||||
export const createAnimation = () => {
|
||||
interface AnimationOnFinishCallback {
|
||||
c: AnimationLifecycle;
|
||||
o?: AnimationOnFinishOptions;
|
||||
}
|
||||
|
||||
interface AnimationInternal extends Animation {
|
||||
/**
|
||||
* Sets the parent animation.
|
||||
*/
|
||||
parent(animation: Animation): Animation;
|
||||
|
||||
/**
|
||||
* Updates any existing animations.
|
||||
*/
|
||||
update(deep: boolean): Animation;
|
||||
|
||||
animationFinish(): void;
|
||||
}
|
||||
|
||||
export const createAnimation = (): Animation => {
|
||||
let _delay: number | undefined;
|
||||
let _duration: number | undefined;
|
||||
let _easing: string | undefined;
|
||||
let _iterations: number | undefined;
|
||||
let _fill: AnimationFill | undefined;
|
||||
let _direction: AnimationDirection | undefined;
|
||||
let _keyframes: any[] = [];
|
||||
let _keyframes: AnimationKeyFrames = [];
|
||||
let beforeAddClasses: string[] = [];
|
||||
let beforeRemoveClasses: string[] = [];
|
||||
let initialized = false;
|
||||
let parentAnimation: Animation | undefined;
|
||||
let parentAnimation: AnimationInternal | undefined;
|
||||
let beforeStylesValue: { [property: string]: any } = {};
|
||||
let afterAddClasses: string[] = [];
|
||||
let afterRemoveClasses: string[] = [];
|
||||
@ -32,12 +51,12 @@ export const createAnimation = () => {
|
||||
let finished = false;
|
||||
let shouldCalculateNumAnimations = true;
|
||||
let keyframeName: string | undefined;
|
||||
let ani: Animation;
|
||||
let ani: AnimationInternal;
|
||||
|
||||
const onFinishCallbacks: AnimationOnFinishCallback[] = [];
|
||||
const onFinishOneTimeCallbacks: AnimationOnFinishCallback[] = [];
|
||||
const elements: HTMLElement[] = [];
|
||||
const childAnimations: Animation[] = [];
|
||||
const childAnimations: AnimationInternal[] = [];
|
||||
const stylesheets: HTMLElement[] = [];
|
||||
const _beforeAddReadFunctions: any[] = [];
|
||||
const _beforeAddWriteFunctions: any[] = [];
|
||||
@ -48,20 +67,10 @@ export const createAnimation = () => {
|
||||
const supportsWebAnimations = (typeof (Element as any) === 'function') && (typeof (Element as any).prototype!.animate === 'function') && supportsAnimationEffect;
|
||||
const ANIMATION_END_FALLBACK_PADDING_MS = 100;
|
||||
|
||||
/**
|
||||
* Returns the raw Web Animations object
|
||||
* for all elements in an Animation.
|
||||
* This will return an empty array on
|
||||
* browsers that do not support
|
||||
* the Web Animations API.
|
||||
*/
|
||||
const getWebAnimations = () => {
|
||||
return webAnimations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the animation and all child animations.
|
||||
*/
|
||||
const destroy = () => {
|
||||
childAnimations.forEach(childAnimation => {
|
||||
childAnimation.destroy();
|
||||
@ -92,20 +101,13 @@ export const createAnimation = () => {
|
||||
cleanUpStyleSheets();
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a callback to be run
|
||||
* upon the animation ending
|
||||
*/
|
||||
const onFinish = (callback: any, opts?: AnimationOnFinishOptions) => {
|
||||
const onFinish = (callback: AnimationLifecycle, opts?: AnimationOnFinishOptions) => {
|
||||
const callbacks = (opts && opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
|
||||
callbacks.push({ callback, opts } as AnimationOnFinishCallback);
|
||||
callbacks.push({ c: callback, o: opts });
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears all callbacks
|
||||
*/
|
||||
const clearOnFinish = () => {
|
||||
onFinishCallbacks.length = 0;
|
||||
onFinishOneTimeCallbacks.length = 0;
|
||||
@ -120,7 +122,7 @@ export const createAnimation = () => {
|
||||
*/
|
||||
const cleanUpElements = () => {
|
||||
if (supportsWebAnimations) {
|
||||
getWebAnimations().forEach(animation => {
|
||||
webAnimations.forEach(animation => {
|
||||
animation.cancel();
|
||||
});
|
||||
|
||||
@ -160,64 +162,36 @@ export const createAnimation = () => {
|
||||
stylesheets.length = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a function that performs a
|
||||
* DOM read to be run before the
|
||||
* animation starts
|
||||
*/
|
||||
const beforeAddRead = (readFn: () => void) => {
|
||||
_beforeAddReadFunctions.push(readFn);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a function that performs a
|
||||
* DOM write to be run before the
|
||||
* animation starts
|
||||
*/
|
||||
const beforeAddWrite = (writeFn: () => void) => {
|
||||
_beforeAddWriteFunctions.push(writeFn);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a function that performs a
|
||||
* DOM read to be run after the
|
||||
* animation end
|
||||
*/
|
||||
const afterAddRead = (readFn: () => void) => {
|
||||
_afterAddReadFunctions.push(readFn);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a function that performs a
|
||||
* DOM write to be run after the
|
||||
* animation end
|
||||
*/
|
||||
const afterAddWrite = (writeFn: () => void) => {
|
||||
_afterAddWriteFunctions.push(writeFn);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a class to the animation's
|
||||
* elements before the animation starts
|
||||
*/
|
||||
const beforeAddClass = (className: string | string[] | undefined) => {
|
||||
beforeAddClasses = addClassToArray(beforeAddClasses, className);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a class from the animation's
|
||||
* elements before the animation starts
|
||||
*/
|
||||
const beforeRemoveClass = (className: string | string[] | undefined) => {
|
||||
beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
|
||||
|
||||
@ -245,40 +219,24 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add CSS class to the animation's
|
||||
* elements after the animation ends.
|
||||
*/
|
||||
const afterAddClass = (className: string | string[] | undefined) => {
|
||||
afterAddClasses = addClassToArray(afterAddClasses, className);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove CSS class from the animation's
|
||||
* elements after the animation ends.
|
||||
*/
|
||||
const afterRemoveClass = (className: string | string[] | undefined) => {
|
||||
afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set CSS inline styles to the animation's
|
||||
* elements after the animation ends.
|
||||
*/
|
||||
const afterStyles = (styles: { [property: string]: any } = {}) => {
|
||||
afterStylesValue = styles;
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clear CSS inline styles from the animation's
|
||||
* elements after the animation ends.
|
||||
*/
|
||||
const afterClearStyles = (propertyNames: string[] = []) => {
|
||||
for (const property of propertyNames) {
|
||||
afterStylesValue[property] = '';
|
||||
@ -287,9 +245,6 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the animation's fill mode.
|
||||
*/
|
||||
const getFill = () => {
|
||||
if (_fill !== undefined) { return _fill; }
|
||||
if (parentAnimation) { return parentAnimation.getFill(); }
|
||||
@ -297,9 +252,6 @@ export const createAnimation = () => {
|
||||
return 'both';
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the animation's direction.
|
||||
*/
|
||||
const getDirection = () => {
|
||||
if (forceDirectionValue !== undefined) { return forceDirectionValue; }
|
||||
if (_direction !== undefined) { return _direction; }
|
||||
@ -309,9 +261,6 @@ export const createAnimation = () => {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the animation's easing.
|
||||
*/
|
||||
const getEasing = () => {
|
||||
if (shouldForceLinearEasing) { return 'linear'; }
|
||||
if (_easing !== undefined) { return _easing; }
|
||||
@ -320,9 +269,6 @@ export const createAnimation = () => {
|
||||
return 'linear';
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the animation's duration in milliseconds.
|
||||
*/
|
||||
const getDuration = () => {
|
||||
if (shouldForceSyncPlayback) { return 0; }
|
||||
if (forceDurationValue !== undefined) { return forceDurationValue; }
|
||||
@ -332,9 +278,6 @@ export const createAnimation = () => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the number of iterations the animation will run.
|
||||
*/
|
||||
const getIterations = () => {
|
||||
if (_iterations !== undefined) { return _iterations; }
|
||||
if (parentAnimation) { return parentAnimation.getIterations(); }
|
||||
@ -342,9 +285,6 @@ export const createAnimation = () => {
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the animation's delay in milliseconds.
|
||||
*/
|
||||
const getDelay = () => {
|
||||
if (forceDelayValue !== undefined) { return forceDelayValue; }
|
||||
if (_delay !== undefined) { return _delay; }
|
||||
@ -353,17 +293,10 @@ export const createAnimation = () => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an array of keyframes for the animation.
|
||||
*/
|
||||
const getKeyframes = () => {
|
||||
return _keyframes;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether the animation should play forwards,
|
||||
* backwards, or alternating back and forth.
|
||||
*/
|
||||
const direction = (animationDirection: AnimationDirection) => {
|
||||
_direction = animationDirection;
|
||||
|
||||
@ -372,22 +305,14 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets how the animation applies styles to its
|
||||
* elements before and after the animation's execution.
|
||||
*/
|
||||
const fill = (animationFill: AnimationFill) => {
|
||||
_fill = animationFill;
|
||||
|
||||
update(true);
|
||||
|
||||
return ani;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets when an animation starts (in milliseconds).
|
||||
*/
|
||||
const delay = (animationDelay: number) => {
|
||||
_delay = animationDelay;
|
||||
|
||||
@ -396,10 +321,6 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets how the animation progresses through the
|
||||
* duration of each cycle.
|
||||
*/
|
||||
const easing = (animationEasing: string) => {
|
||||
_easing = animationEasing;
|
||||
|
||||
@ -408,10 +329,6 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the length of time the animation takes
|
||||
* to complete one cycle.
|
||||
*/
|
||||
const duration = (animationDuration: number) => {
|
||||
/**
|
||||
* CSS Animation Durations of 0ms work fine on Chrome
|
||||
@ -429,10 +346,6 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the number of times the animation cycle
|
||||
* should be played before stopping.
|
||||
*/
|
||||
const iterations = (animationIterations: number) => {
|
||||
_iterations = animationIterations;
|
||||
|
||||
@ -441,18 +354,12 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the parent animation.
|
||||
*/
|
||||
const parent = (animation: Animation) => {
|
||||
const parent = (animation: AnimationInternal) => {
|
||||
parentAnimation = animation;
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add one or more elements to the animation
|
||||
*/
|
||||
const addElement = (el: Element | Element[] | Node | Node[] | NodeList | undefined | null) => {
|
||||
if (el != null) {
|
||||
|
||||
@ -470,31 +377,22 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Group one or more animations together to be controlled by a parent animation.
|
||||
*/
|
||||
const addAnimation = (animationToAdd: Animation | Animation[] | undefined | null) => {
|
||||
if (animationToAdd != null) {
|
||||
const parentAnim = ani;
|
||||
const animationsToAdd = animationToAdd as Animation[];
|
||||
if (animationsToAdd.length >= 0) {
|
||||
for (const animation of animationsToAdd) {
|
||||
animation.parent(parentAnim);
|
||||
const addAnimation = (animationToAdd: AnimationInternal | AnimationInternal[]) => {
|
||||
if ((animationToAdd as any) != null) {
|
||||
if (Array.isArray(animationToAdd)) {
|
||||
for (const animation of animationToAdd) {
|
||||
animation.parent(ani);
|
||||
childAnimations.push(animation);
|
||||
}
|
||||
} else {
|
||||
(animationToAdd as Animation).parent(parentAnim);
|
||||
childAnimations.push(animationToAdd as Animation);
|
||||
animationToAdd.parent(ani);
|
||||
childAnimations.push(animationToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the keyframes for the animation.
|
||||
*/
|
||||
const keyframes = (keyframeValues: any[]) => {
|
||||
const keyframes = (keyframeValues: AnimationKeyFrames) => {
|
||||
_keyframes = keyframeValues;
|
||||
|
||||
return ani;
|
||||
@ -526,7 +424,7 @@ export const createAnimation = () => {
|
||||
const removeClasses = beforeRemoveClasses;
|
||||
const styles = beforeStylesValue;
|
||||
|
||||
elements.forEach((el: HTMLElement) => {
|
||||
elements.forEach(el => {
|
||||
const elementClassList = el.classList;
|
||||
|
||||
addClasses.forEach(c => elementClassList.add(c));
|
||||
@ -575,7 +473,7 @@ export const createAnimation = () => {
|
||||
const removeClasses = afterRemoveClasses;
|
||||
const styles = afterStylesValue;
|
||||
|
||||
elements.forEach((el: HTMLElement) => {
|
||||
elements.forEach(el => {
|
||||
const elementClassList = el.classList;
|
||||
|
||||
addClasses.forEach(c => elementClassList.add(c));
|
||||
@ -598,14 +496,14 @@ export const createAnimation = () => {
|
||||
runAfterWrite();
|
||||
runAfterStyles();
|
||||
|
||||
const didComplete = willComplete;
|
||||
const currentStep = willComplete ? 1 : 0;
|
||||
|
||||
onFinishCallbacks.forEach(onFinishCallback => {
|
||||
onFinishCallback.callback(didComplete, ani);
|
||||
return onFinishCallback.c(currentStep, ani);
|
||||
});
|
||||
|
||||
onFinishOneTimeCallbacks.forEach(onFinishCallback => {
|
||||
onFinishCallback.callback(didComplete, ani);
|
||||
return onFinishCallback.c(currentStep, ani);
|
||||
});
|
||||
|
||||
onFinishOneTimeCallbacks.length = 0;
|
||||
@ -637,16 +535,15 @@ export const createAnimation = () => {
|
||||
const stylesheet = createKeyframeStylesheet(keyframeName, keyframeRules, element);
|
||||
stylesheets.push(stylesheet);
|
||||
|
||||
setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null);
|
||||
setStyleProperty(element, 'animation-timing-function', getEasing() || null);
|
||||
setStyleProperty(element, 'animation-delay', (getDelay() !== undefined) ? `${getDelay()}ms` : null);
|
||||
setStyleProperty(element, 'animation-fill-mode', getFill() || null);
|
||||
setStyleProperty(element, 'animation-direction', getDirection() || null);
|
||||
setStyleProperty(element, 'animation-duration', `${getDuration()}ms`);
|
||||
setStyleProperty(element, 'animation-timing-function', getEasing());
|
||||
setStyleProperty(element, 'animation-delay', `${getDelay()}ms`);
|
||||
setStyleProperty(element, 'animation-fill-mode', getFill());
|
||||
setStyleProperty(element, 'animation-direction', getDirection());
|
||||
|
||||
const iterationsCount =
|
||||
(getIterations() !== undefined) ?
|
||||
(getIterations() === Infinity) ? 'infinite' : getIterations()!.toString()
|
||||
: null;
|
||||
const iterationsCount = (getIterations() === Infinity)
|
||||
? 'infinite'
|
||||
: getIterations().toString();
|
||||
|
||||
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
|
||||
setStyleProperty(element, 'animation-play-state', 'paused');
|
||||
@ -678,7 +575,7 @@ export const createAnimation = () => {
|
||||
webAnimations.push(animation);
|
||||
});
|
||||
|
||||
if (getWebAnimations().length > 0) {
|
||||
if (webAnimations.length > 0) {
|
||||
webAnimations[0].onfinish = () => {
|
||||
animationFinish();
|
||||
};
|
||||
@ -703,7 +600,7 @@ export const createAnimation = () => {
|
||||
const setAnimationStep = (step: number) => {
|
||||
step = Math.min(Math.max(step, 0), 0.999);
|
||||
if (supportsWebAnimations) {
|
||||
getWebAnimations().forEach(animation => {
|
||||
webAnimations.forEach(animation => {
|
||||
animation.currentTime = animation.effect.getComputedTiming().delay + (getDuration()! * step);
|
||||
animation.pause();
|
||||
});
|
||||
@ -722,7 +619,7 @@ export const createAnimation = () => {
|
||||
};
|
||||
|
||||
const updateWebAnimation = () => {
|
||||
getWebAnimations().forEach(animation => {
|
||||
webAnimations.forEach(animation => {
|
||||
animation.effect.updateTiming({
|
||||
delay: getDelay(),
|
||||
duration: getDuration(),
|
||||
@ -738,16 +635,15 @@ export const createAnimation = () => {
|
||||
elements.forEach(element => {
|
||||
raf(() => {
|
||||
setStyleProperty(element, 'animation-name', keyframeName || null);
|
||||
setStyleProperty(element, 'animation-duration', (getDuration() !== undefined) ? `${getDuration()}ms` : null);
|
||||
setStyleProperty(element, 'animation-timing-function', getEasing() || null);
|
||||
setStyleProperty(element, 'animation-delay', (getDelay() !== undefined) ? `${getDelay()}ms` : null);
|
||||
setStyleProperty(element, 'animation-duration', `${getDuration()}ms`);
|
||||
setStyleProperty(element, 'animation-timing-function', getEasing());
|
||||
setStyleProperty(element, 'animation-delay', `${getDelay()}ms`);
|
||||
setStyleProperty(element, 'animation-fill-mode', getFill() || null);
|
||||
setStyleProperty(element, 'animation-direction', getDirection() || null);
|
||||
|
||||
const iterationsCount =
|
||||
(getIterations() !== undefined) ?
|
||||
(getIterations() === Infinity) ? 'infinite' : getIterations()!.toString()
|
||||
: null;
|
||||
const iterationsCount = (getIterations() === Infinity)
|
||||
? 'infinite'
|
||||
: getIterations().toString();
|
||||
|
||||
setStyleProperty(element, 'animation-iteration-count', iterationsCount);
|
||||
|
||||
@ -762,9 +658,6 @@ export const createAnimation = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates any existing animations.
|
||||
*/
|
||||
const update = (deep = false, toggleAnimationName = true) => {
|
||||
if (deep) {
|
||||
childAnimations.forEach(animation => {
|
||||
@ -803,19 +696,15 @@ export const createAnimation = () => {
|
||||
childAnimations.forEach(animation => {
|
||||
animation.progressStep(step);
|
||||
});
|
||||
|
||||
if (getDuration() !== undefined) {
|
||||
setAnimationStep(step);
|
||||
}
|
||||
|
||||
setAnimationStep(step);
|
||||
return ani;
|
||||
};
|
||||
|
||||
const progressEnd = (shouldComplete: boolean, step: number, dur: number | undefined) => {
|
||||
const progressEnd = (playTo: 0 | 1 | undefined, step: number, dur?: number) => {
|
||||
shouldForceLinearEasing = false;
|
||||
|
||||
childAnimations.forEach(animation => {
|
||||
animation.progressEnd(shouldComplete, step, dur);
|
||||
animation.progressEnd(playTo, step, dur);
|
||||
});
|
||||
|
||||
if (dur !== undefined) {
|
||||
@ -824,9 +713,9 @@ export const createAnimation = () => {
|
||||
|
||||
finished = false;
|
||||
|
||||
willComplete = shouldComplete;
|
||||
willComplete = playTo === 1;
|
||||
|
||||
if (!shouldComplete) {
|
||||
if (!willComplete) {
|
||||
forceDirectionValue = (getDirection() === 'reverse') ? 'normal' : 'reverse';
|
||||
|
||||
if (supportsWebAnimations) {
|
||||
@ -862,7 +751,7 @@ export const createAnimation = () => {
|
||||
const pauseAnimation = () => {
|
||||
if (initialized) {
|
||||
if (supportsWebAnimations) {
|
||||
getWebAnimations().forEach(animation => {
|
||||
webAnimations.forEach(animation => {
|
||||
animation.pause();
|
||||
});
|
||||
} else {
|
||||
@ -873,9 +762,6 @@ export const createAnimation = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pause the animation.
|
||||
*/
|
||||
const pause = () => {
|
||||
childAnimations.forEach(animation => {
|
||||
animation.pause();
|
||||
@ -886,30 +772,12 @@ export const createAnimation = () => {
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Play the animation asynchronously.
|
||||
* This returns a promise that resolves
|
||||
* when the animation has ended.
|
||||
*/
|
||||
const playAsync = () => {
|
||||
return new Promise(resolve => {
|
||||
onFinish(resolve, { oneTimeCallback: true });
|
||||
play();
|
||||
|
||||
return ani;
|
||||
});
|
||||
return play();
|
||||
};
|
||||
|
||||
/**
|
||||
* Play the animation synchronously. This
|
||||
* is the equivalent of running the animation
|
||||
* with a duration of 0ms.
|
||||
*/
|
||||
const playSync = () => {
|
||||
shouldForceSyncPlayback = true;
|
||||
|
||||
onFinish(() => shouldForceSyncPlayback = false, { oneTimeCallback: true });
|
||||
play();
|
||||
play({ sync: true });
|
||||
|
||||
return ani;
|
||||
};
|
||||
@ -984,7 +852,7 @@ export const createAnimation = () => {
|
||||
};
|
||||
|
||||
const playWebAnimations = () => {
|
||||
getWebAnimations().forEach(animation => {
|
||||
webAnimations.forEach(animation => {
|
||||
animation.play();
|
||||
});
|
||||
|
||||
@ -1001,41 +869,41 @@ export const createAnimation = () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Play the animation
|
||||
*/
|
||||
const play = () => {
|
||||
if (!initialized) {
|
||||
initializeAnimation();
|
||||
}
|
||||
const play = (opts?: AnimationPlayOptions) => {
|
||||
return new Promise<void>(resolve => {
|
||||
if (opts && opts.sync) {
|
||||
shouldForceSyncPlayback = true;
|
||||
|
||||
if (finished) {
|
||||
resetAnimation();
|
||||
finished = false;
|
||||
}
|
||||
onFinish(() => shouldForceSyncPlayback = false, { oneTimeCallback: true });
|
||||
}
|
||||
if (!initialized) {
|
||||
initializeAnimation();
|
||||
}
|
||||
|
||||
if (shouldCalculateNumAnimations) {
|
||||
numAnimationsRunning = childAnimations.length + 1;
|
||||
shouldCalculateNumAnimations = false;
|
||||
}
|
||||
if (finished) {
|
||||
resetAnimation();
|
||||
finished = false;
|
||||
}
|
||||
|
||||
childAnimations.forEach(animation => {
|
||||
animation.play();
|
||||
if (shouldCalculateNumAnimations) {
|
||||
numAnimationsRunning = childAnimations.length + 1;
|
||||
shouldCalculateNumAnimations = false;
|
||||
}
|
||||
|
||||
onFinish(() => resolve(), { oneTimeCallback: true });
|
||||
|
||||
childAnimations.forEach(animation => {
|
||||
animation.play();
|
||||
});
|
||||
|
||||
if (supportsWebAnimations) {
|
||||
playWebAnimations();
|
||||
} else {
|
||||
playCSSAnimations();
|
||||
}
|
||||
});
|
||||
|
||||
if (supportsWebAnimations) {
|
||||
playWebAnimations();
|
||||
} else {
|
||||
playCSSAnimations();
|
||||
}
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stop the animation and reset
|
||||
* all elements to their initial state
|
||||
*/
|
||||
const stop = () => {
|
||||
childAnimations.forEach(animation => {
|
||||
animation.stop();
|
||||
@ -1045,14 +913,12 @@ export const createAnimation = () => {
|
||||
cleanUpElements();
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
return ani;
|
||||
};
|
||||
|
||||
const from = (property: string, value: any) => {
|
||||
const firstFrame = _keyframes[0];
|
||||
const firstFrame = _keyframes[0] as AnimationKeyFrame | undefined;
|
||||
|
||||
if (firstFrame != null && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
|
||||
if (firstFrame !== undefined && firstFrame.offset === 0) {
|
||||
firstFrame[property] = value;
|
||||
} else {
|
||||
_keyframes = [
|
||||
@ -1065,9 +931,9 @@ export const createAnimation = () => {
|
||||
};
|
||||
|
||||
const to = (property: string, value: any) => {
|
||||
const lastFrame = _keyframes[_keyframes.length - 1];
|
||||
const lastFrame = _keyframes[_keyframes.length - 1] as AnimationKeyFrame | undefined;
|
||||
|
||||
if (lastFrame != null && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
|
||||
if (lastFrame !== undefined && lastFrame.offset === 1) {
|
||||
lastFrame[property] = value;
|
||||
} else {
|
||||
_keyframes = [
|
||||
@ -1128,10 +994,9 @@ export const createAnimation = () => {
|
||||
beforeRemoveClass,
|
||||
beforeAddClass,
|
||||
onFinish,
|
||||
clearOnFinish,
|
||||
|
||||
progressStart,
|
||||
progressStep,
|
||||
progressEnd
|
||||
} as Animation;
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user