123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820 |
- /*!
- * (C) Ionic http://ionicframework.com - MIT License
- */
- import { p as printIonError } from './index4.js';
- import { w as win } from './index6.js';
- let animationPrefix;
- const getAnimationPrefix = (el) => {
- if (animationPrefix === undefined) {
- const supportsUnprefixed = el.style.animationName !== undefined;
- const supportsWebkitPrefix = el.style.webkitAnimationName !== undefined;
- animationPrefix = !supportsUnprefixed && supportsWebkitPrefix ? '-webkit-' : '';
- }
- return animationPrefix;
- };
- const setStyleProperty = (element, propertyName, value) => {
- const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
- element.style.setProperty(prefix + propertyName, value);
- };
- const addClassToArray = (classes = [], className) => {
- if (className !== undefined) {
- const classNameToAppend = Array.isArray(className) ? className : [className];
- return [...classes, ...classNameToAppend];
- }
- return classes;
- };
- const createAnimation = (animationId) => {
- let _delay;
- let _duration;
- let _easing;
- let _iterations;
- let _fill;
- let _direction;
- let _keyframes = [];
- let beforeAddClasses = [];
- let beforeRemoveClasses = [];
- let initialized = false;
- let parentAnimation;
- let beforeStylesValue = {};
- let afterAddClasses = [];
- let afterRemoveClasses = [];
- let afterStylesValue = {};
- let numAnimationsRunning = 0;
- let shouldForceLinearEasing = false;
- let shouldForceSyncPlayback = false;
- let forceDirectionValue;
- let forceDurationValue;
- let forceDelayValue;
- let willComplete = true;
- let finished = false;
- let shouldCalculateNumAnimations = true;
- let ani;
- let paused = false;
- const id = animationId;
- const onFinishCallbacks = [];
- const onFinishOneTimeCallbacks = [];
- const onStopOneTimeCallbacks = [];
- const elements = [];
- const childAnimations = [];
- const stylesheets = [];
- const _beforeAddReadFunctions = [];
- const _beforeAddWriteFunctions = [];
- const _afterAddReadFunctions = [];
- const _afterAddWriteFunctions = [];
- const webAnimations = [];
- const supportsAnimationEffect = typeof AnimationEffect === 'function' ||
- (win !== undefined && typeof win.AnimationEffect === 'function');
- /**
- * This is a feature detection for Web Animations.
- *
- * Certain environments such as emulated browser environments for testing,
- * do not support Web Animations. As a result, we need to check for support
- * and provide a fallback to test certain functionality related to Web Animations.
- */
- const supportsWebAnimations = typeof Element === 'function' &&
- typeof Element.prototype.animate === 'function' &&
- supportsAnimationEffect;
- const getWebAnimations = () => {
- return webAnimations;
- };
- const destroy = (clearStyleSheets) => {
- childAnimations.forEach((childAnimation) => {
- childAnimation.destroy(clearStyleSheets);
- });
- cleanUp(clearStyleSheets);
- elements.length = 0;
- childAnimations.length = 0;
- _keyframes.length = 0;
- clearOnFinish();
- initialized = false;
- shouldCalculateNumAnimations = true;
- return ani;
- };
- /**
- * Cancels any Web Animations, removes
- * any animation properties from the
- * animation's elements, and removes the
- * animation's stylesheets from the DOM.
- */
- const cleanUp = (clearStyleSheets) => {
- cleanUpElements();
- if (clearStyleSheets) {
- cleanUpStyleSheets();
- }
- };
- const resetFlags = () => {
- shouldForceLinearEasing = false;
- shouldForceSyncPlayback = false;
- shouldCalculateNumAnimations = true;
- forceDirectionValue = undefined;
- forceDurationValue = undefined;
- forceDelayValue = undefined;
- numAnimationsRunning = 0;
- finished = false;
- willComplete = true;
- paused = false;
- };
- const isRunning = () => {
- return numAnimationsRunning !== 0 && !paused;
- };
- /**
- * @internal
- * Remove a callback from a chosen callback array
- * @param callbackToRemove: A reference to the callback that should be removed
- * @param callbackObjects: An array of callbacks that callbackToRemove should be removed from.
- */
- const clearCallback = (callbackToRemove, callbackObjects) => {
- const index = callbackObjects.findIndex((callbackObject) => callbackObject.c === callbackToRemove);
- if (index > -1) {
- callbackObjects.splice(index, 1);
- }
- };
- /**
- * @internal
- * Add a callback to be fired when an animation is stopped/cancelled.
- * @param callback: A reference to the callback that should be fired
- * @param opts: Any options associated with this particular callback
- */
- const onStop = (callback, opts) => {
- onStopOneTimeCallbacks.push({ c: callback, o: opts });
- return ani;
- };
- const onFinish = (callback, opts) => {
- const callbacks = (opts === null || opts === void 0 ? void 0 : opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
- callbacks.push({ c: callback, o: opts });
- return ani;
- };
- const clearOnFinish = () => {
- onFinishCallbacks.length = 0;
- onFinishOneTimeCallbacks.length = 0;
- return ani;
- };
- /**
- * Cancels any Web Animations and removes
- * any animation properties from the
- * the animation's elements.
- */
- const cleanUpElements = () => {
- if (supportsWebAnimations) {
- webAnimations.forEach((animation) => {
- animation.cancel();
- });
- webAnimations.length = 0;
- }
- };
- /**
- * Removes the animation's stylesheets
- * from the DOM.
- */
- const cleanUpStyleSheets = () => {
- stylesheets.forEach((stylesheet) => {
- /**
- * When sharing stylesheets, it's possible
- * for another animation to have already
- * cleaned up a particular stylesheet
- */
- if (stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.parentNode) {
- stylesheet.parentNode.removeChild(stylesheet);
- }
- });
- stylesheets.length = 0;
- };
- const beforeAddRead = (readFn) => {
- _beforeAddReadFunctions.push(readFn);
- return ani;
- };
- const beforeAddWrite = (writeFn) => {
- _beforeAddWriteFunctions.push(writeFn);
- return ani;
- };
- const afterAddRead = (readFn) => {
- _afterAddReadFunctions.push(readFn);
- return ani;
- };
- const afterAddWrite = (writeFn) => {
- _afterAddWriteFunctions.push(writeFn);
- return ani;
- };
- const beforeAddClass = (className) => {
- beforeAddClasses = addClassToArray(beforeAddClasses, className);
- return ani;
- };
- const beforeRemoveClass = (className) => {
- beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
- return ani;
- };
- /**
- * Set CSS inline styles to the animation's
- * elements before the animation begins.
- */
- const beforeStyles = (styles = {}) => {
- beforeStylesValue = styles;
- return ani;
- };
- /**
- * Clear CSS inline styles from the animation's
- * elements before the animation begins.
- */
- const beforeClearStyles = (propertyNames = []) => {
- for (const property of propertyNames) {
- beforeStylesValue[property] = '';
- }
- return ani;
- };
- const afterAddClass = (className) => {
- afterAddClasses = addClassToArray(afterAddClasses, className);
- return ani;
- };
- const afterRemoveClass = (className) => {
- afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
- return ani;
- };
- const afterStyles = (styles = {}) => {
- afterStylesValue = styles;
- return ani;
- };
- const afterClearStyles = (propertyNames = []) => {
- for (const property of propertyNames) {
- afterStylesValue[property] = '';
- }
- return ani;
- };
- const getFill = () => {
- if (_fill !== undefined) {
- return _fill;
- }
- if (parentAnimation) {
- return parentAnimation.getFill();
- }
- return 'both';
- };
- const getDirection = () => {
- if (forceDirectionValue !== undefined) {
- return forceDirectionValue;
- }
- if (_direction !== undefined) {
- return _direction;
- }
- if (parentAnimation) {
- return parentAnimation.getDirection();
- }
- return 'normal';
- };
- const getEasing = () => {
- if (shouldForceLinearEasing) {
- return 'linear';
- }
- if (_easing !== undefined) {
- return _easing;
- }
- if (parentAnimation) {
- return parentAnimation.getEasing();
- }
- return 'linear';
- };
- const getDuration = () => {
- if (shouldForceSyncPlayback) {
- return 0;
- }
- if (forceDurationValue !== undefined) {
- return forceDurationValue;
- }
- if (_duration !== undefined) {
- return _duration;
- }
- if (parentAnimation) {
- return parentAnimation.getDuration();
- }
- return 0;
- };
- const getIterations = () => {
- if (_iterations !== undefined) {
- return _iterations;
- }
- if (parentAnimation) {
- return parentAnimation.getIterations();
- }
- return 1;
- };
- const getDelay = () => {
- if (forceDelayValue !== undefined) {
- return forceDelayValue;
- }
- if (_delay !== undefined) {
- return _delay;
- }
- if (parentAnimation) {
- return parentAnimation.getDelay();
- }
- return 0;
- };
- const getKeyframes = () => {
- return _keyframes;
- };
- const direction = (animationDirection) => {
- _direction = animationDirection;
- update(true);
- return ani;
- };
- const fill = (animationFill) => {
- _fill = animationFill;
- update(true);
- return ani;
- };
- const delay = (animationDelay) => {
- _delay = animationDelay;
- update(true);
- return ani;
- };
- const easing = (animationEasing) => {
- _easing = animationEasing;
- update(true);
- return ani;
- };
- const duration = (animationDuration) => {
- /**
- * CSS Animation Durations of 0ms work fine on Chrome
- * but do not run on Safari, so force it to 1ms to
- * get it to run on both platforms.
- */
- if (!supportsWebAnimations && animationDuration === 0) {
- animationDuration = 1;
- }
- _duration = animationDuration;
- update(true);
- return ani;
- };
- const iterations = (animationIterations) => {
- _iterations = animationIterations;
- update(true);
- return ani;
- };
- const parent = (animation) => {
- parentAnimation = animation;
- return ani;
- };
- const addElement = (el) => {
- if (el != null) {
- if (el.nodeType === 1) {
- elements.push(el);
- }
- else if (el.length >= 0) {
- for (let i = 0; i < el.length; i++) {
- elements.push(el[i]);
- }
- }
- else {
- printIonError('createAnimation - Invalid addElement value.');
- }
- }
- return ani;
- };
- const addAnimation = (animationToAdd) => {
- if (animationToAdd != null) {
- if (Array.isArray(animationToAdd)) {
- for (const animation of animationToAdd) {
- animation.parent(ani);
- childAnimations.push(animation);
- }
- }
- else {
- animationToAdd.parent(ani);
- childAnimations.push(animationToAdd);
- }
- }
- return ani;
- };
- const keyframes = (keyframeValues) => {
- const different = _keyframes !== keyframeValues;
- _keyframes = keyframeValues;
- if (different) {
- updateKeyframes(_keyframes);
- }
- return ani;
- };
- const updateKeyframes = (keyframeValues) => {
- if (supportsWebAnimations) {
- getWebAnimations().forEach((animation) => {
- /**
- * animation.effect's type is AnimationEffect.
- * However, in this case we have a more specific
- * type of AnimationEffect called KeyframeEffect which
- * inherits from AnimationEffect. As a result,
- * we cast animation.effect to KeyframeEffect.
- */
- const keyframeEffect = animation.effect;
- /**
- * setKeyframes is not supported in all browser
- * versions that Ionic supports, so we need to
- * check for support before using it.
- */
- // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
- if (keyframeEffect.setKeyframes) {
- keyframeEffect.setKeyframes(keyframeValues);
- }
- else {
- const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
- animation.effect = newEffect;
- }
- });
- }
- };
- /**
- * Run all "before" animation hooks.
- */
- const beforeAnimation = () => {
- // Runs all before read callbacks
- _beforeAddReadFunctions.forEach((callback) => callback());
- // Runs all before write callbacks
- _beforeAddWriteFunctions.forEach((callback) => callback());
- // Updates styles and classes before animation runs
- const addClasses = beforeAddClasses;
- const removeClasses = beforeRemoveClasses;
- const styles = beforeStylesValue;
- elements.forEach((el) => {
- const elementClassList = el.classList;
- addClasses.forEach((c) => elementClassList.add(c));
- removeClasses.forEach((c) => elementClassList.remove(c));
- for (const property in styles) {
- // eslint-disable-next-line no-prototype-builtins
- if (styles.hasOwnProperty(property)) {
- setStyleProperty(el, property, styles[property]);
- }
- }
- });
- };
- /**
- * Run all "after" animation hooks.
- */
- const afterAnimation = () => {
- // Runs all after read callbacks
- _afterAddReadFunctions.forEach((callback) => callback());
- // Runs all after write callbacks
- _afterAddWriteFunctions.forEach((callback) => callback());
- // Updates styles and classes before animation ends
- const currentStep = willComplete ? 1 : 0;
- const addClasses = afterAddClasses;
- const removeClasses = afterRemoveClasses;
- const styles = afterStylesValue;
- elements.forEach((el) => {
- const elementClassList = el.classList;
- addClasses.forEach((c) => elementClassList.add(c));
- removeClasses.forEach((c) => elementClassList.remove(c));
- for (const property in styles) {
- // eslint-disable-next-line no-prototype-builtins
- if (styles.hasOwnProperty(property)) {
- setStyleProperty(el, property, styles[property]);
- }
- }
- });
- /**
- * Clean up any value coercion before
- * the user callbacks fire otherwise
- * they may get stale values. For example,
- * if someone calls progressStart(0) the
- * animation may still be reversed.
- */
- forceDurationValue = undefined;
- forceDirectionValue = undefined;
- forceDelayValue = undefined;
- onFinishCallbacks.forEach((onFinishCallback) => {
- return onFinishCallback.c(currentStep, ani);
- });
- onFinishOneTimeCallbacks.forEach((onFinishCallback) => {
- return onFinishCallback.c(currentStep, ani);
- });
- onFinishOneTimeCallbacks.length = 0;
- shouldCalculateNumAnimations = true;
- if (willComplete) {
- finished = true;
- }
- willComplete = true;
- };
- const animationFinish = () => {
- if (numAnimationsRunning === 0) {
- return;
- }
- numAnimationsRunning--;
- if (numAnimationsRunning === 0) {
- afterAnimation();
- if (parentAnimation) {
- parentAnimation.animationFinish();
- }
- }
- };
- const initializeWebAnimation = () => {
- elements.forEach((element) => {
- const animation = element.animate(_keyframes, {
- id,
- delay: getDelay(),
- duration: getDuration(),
- easing: getEasing(),
- iterations: getIterations(),
- fill: getFill(),
- direction: getDirection(),
- });
- animation.pause();
- webAnimations.push(animation);
- });
- if (webAnimations.length > 0) {
- webAnimations[0].onfinish = () => {
- animationFinish();
- };
- }
- };
- const initializeAnimation = () => {
- beforeAnimation();
- if (_keyframes.length > 0) {
- if (supportsWebAnimations) {
- initializeWebAnimation();
- }
- }
- initialized = true;
- };
- const setAnimationStep = (step) => {
- step = Math.min(Math.max(step, 0), 0.9999);
- if (supportsWebAnimations) {
- webAnimations.forEach((animation) => {
- // When creating the animation the delay is guaranteed to be set to a number.
- animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
- animation.pause();
- });
- }
- };
- const updateWebAnimation = (step) => {
- webAnimations.forEach((animation) => {
- animation.effect.updateTiming({
- delay: getDelay(),
- duration: getDuration(),
- easing: getEasing(),
- iterations: getIterations(),
- fill: getFill(),
- direction: getDirection(),
- });
- });
- if (step !== undefined) {
- setAnimationStep(step);
- }
- };
- const update = (deep = false, toggleAnimationName = true, step) => {
- if (deep) {
- childAnimations.forEach((animation) => {
- animation.update(deep, toggleAnimationName, step);
- });
- }
- if (supportsWebAnimations) {
- updateWebAnimation(step);
- }
- return ani;
- };
- const progressStart = (forceLinearEasing = false, step) => {
- childAnimations.forEach((animation) => {
- animation.progressStart(forceLinearEasing, step);
- });
- pauseAnimation();
- shouldForceLinearEasing = forceLinearEasing;
- if (!initialized) {
- initializeAnimation();
- }
- update(false, true, step);
- return ani;
- };
- const progressStep = (step) => {
- childAnimations.forEach((animation) => {
- animation.progressStep(step);
- });
- setAnimationStep(step);
- return ani;
- };
- const progressEnd = (playTo, step, dur) => {
- shouldForceLinearEasing = false;
- childAnimations.forEach((animation) => {
- animation.progressEnd(playTo, step, dur);
- });
- if (dur !== undefined) {
- forceDurationValue = dur;
- }
- finished = false;
- willComplete = true;
- if (playTo === 0) {
- forceDirectionValue = getDirection() === 'reverse' ? 'normal' : 'reverse';
- if (forceDirectionValue === 'reverse') {
- willComplete = false;
- }
- if (supportsWebAnimations) {
- update();
- setAnimationStep(1 - step);
- }
- else {
- forceDelayValue = (1 - step) * getDuration() * -1;
- update(false, false);
- }
- }
- else if (playTo === 1) {
- if (supportsWebAnimations) {
- update();
- setAnimationStep(step);
- }
- else {
- forceDelayValue = step * getDuration() * -1;
- update(false, false);
- }
- }
- if (playTo !== undefined && !parentAnimation) {
- play();
- }
- return ani;
- };
- const pauseAnimation = () => {
- if (initialized) {
- if (supportsWebAnimations) {
- webAnimations.forEach((animation) => {
- animation.pause();
- });
- }
- else {
- elements.forEach((element) => {
- setStyleProperty(element, 'animation-play-state', 'paused');
- });
- }
- paused = true;
- }
- };
- const pause = () => {
- childAnimations.forEach((animation) => {
- animation.pause();
- });
- pauseAnimation();
- return ani;
- };
- const playCSSAnimations = () => {
- animationFinish();
- };
- const playWebAnimations = () => {
- webAnimations.forEach((animation) => {
- animation.play();
- });
- if (_keyframes.length === 0 || elements.length === 0) {
- animationFinish();
- }
- };
- const resetAnimation = () => {
- if (supportsWebAnimations) {
- setAnimationStep(0);
- updateWebAnimation();
- }
- };
- const play = (opts) => {
- return new Promise((resolve) => {
- if (opts === null || opts === void 0 ? void 0 : opts.sync) {
- shouldForceSyncPlayback = true;
- onFinish(() => (shouldForceSyncPlayback = false), { oneTimeCallback: true });
- }
- if (!initialized) {
- initializeAnimation();
- }
- if (finished) {
- resetAnimation();
- finished = false;
- }
- if (shouldCalculateNumAnimations) {
- numAnimationsRunning = childAnimations.length + 1;
- shouldCalculateNumAnimations = false;
- }
- /**
- * When one of these callbacks fires we
- * need to clear the other's callback otherwise
- * you can potentially get these callbacks
- * firing multiple times if the play method
- * is subsequently called.
- * Example:
- * animation.play() (onStop and onFinish callbacks are registered)
- * animation.stop() (onStop callback is fired, onFinish is not)
- * animation.play() (onStop and onFinish callbacks are registered)
- * Total onStop callbacks: 1
- * Total onFinish callbacks: 2
- */
- const onStopCallback = () => {
- clearCallback(onFinishCallback, onFinishOneTimeCallbacks);
- resolve();
- };
- const onFinishCallback = () => {
- clearCallback(onStopCallback, onStopOneTimeCallbacks);
- resolve();
- };
- /**
- * The play method resolves when an animation
- * run either finishes or is cancelled.
- */
- onFinish(onFinishCallback, { oneTimeCallback: true });
- onStop(onStopCallback, { oneTimeCallback: true });
- childAnimations.forEach((animation) => {
- animation.play();
- });
- if (supportsWebAnimations) {
- playWebAnimations();
- }
- else {
- playCSSAnimations();
- }
- paused = false;
- });
- };
- /**
- * Stops an animation and resets it state to the
- * beginning. This does not fire any onFinish
- * callbacks because the animation did not finish.
- * However, since the animation was not destroyed
- * (i.e. the animation could run again) we do not
- * clear the onFinish callbacks.
- */
- const stop = () => {
- childAnimations.forEach((animation) => {
- animation.stop();
- });
- if (initialized) {
- cleanUpElements();
- initialized = false;
- }
- resetFlags();
- onStopOneTimeCallbacks.forEach((onStopCallback) => onStopCallback.c(0, ani));
- onStopOneTimeCallbacks.length = 0;
- };
- const from = (property, value) => {
- const firstFrame = _keyframes[0];
- if (firstFrame !== undefined && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
- firstFrame[property] = value;
- }
- else {
- _keyframes = [{ offset: 0, [property]: value }, ..._keyframes];
- }
- return ani;
- };
- const to = (property, value) => {
- const lastFrame = _keyframes[_keyframes.length - 1];
- if (lastFrame !== undefined && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
- lastFrame[property] = value;
- }
- else {
- _keyframes = [..._keyframes, { offset: 1, [property]: value }];
- }
- return ani;
- };
- const fromTo = (property, fromValue, toValue) => {
- return from(property, fromValue).to(property, toValue);
- };
- return (ani = {
- parentAnimation,
- elements,
- childAnimations,
- id,
- animationFinish,
- from,
- to,
- fromTo,
- parent,
- play,
- pause,
- stop,
- destroy,
- keyframes,
- addAnimation,
- addElement,
- update,
- fill,
- direction,
- iterations,
- duration,
- easing,
- delay,
- getWebAnimations,
- getKeyframes,
- getFill,
- getDirection,
- getDelay,
- getIterations,
- getEasing,
- getDuration,
- afterAddRead,
- afterAddWrite,
- afterClearStyles,
- afterStyles,
- afterRemoveClass,
- afterAddClass,
- beforeAddRead,
- beforeAddWrite,
- beforeClearStyles,
- beforeStyles,
- beforeRemoveClass,
- beforeAddClass,
- onFinish,
- isRunning,
- progressStart,
- progressStep,
- progressEnd,
- });
- };
- export { createAnimation as c };
|