animation-ab2d3449.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. 'use strict';
  5. const index = require('./index-cc858e97.js');
  6. const index$1 = require('./index-c8d52405.js');
  7. let animationPrefix;
  8. const getAnimationPrefix = (el) => {
  9. if (animationPrefix === undefined) {
  10. const supportsUnprefixed = el.style.animationName !== undefined;
  11. const supportsWebkitPrefix = el.style.webkitAnimationName !== undefined;
  12. animationPrefix = !supportsUnprefixed && supportsWebkitPrefix ? '-webkit-' : '';
  13. }
  14. return animationPrefix;
  15. };
  16. const setStyleProperty = (element, propertyName, value) => {
  17. const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
  18. element.style.setProperty(prefix + propertyName, value);
  19. };
  20. const addClassToArray = (classes = [], className) => {
  21. if (className !== undefined) {
  22. const classNameToAppend = Array.isArray(className) ? className : [className];
  23. return [...classes, ...classNameToAppend];
  24. }
  25. return classes;
  26. };
  27. const createAnimation = (animationId) => {
  28. let _delay;
  29. let _duration;
  30. let _easing;
  31. let _iterations;
  32. let _fill;
  33. let _direction;
  34. let _keyframes = [];
  35. let beforeAddClasses = [];
  36. let beforeRemoveClasses = [];
  37. let initialized = false;
  38. let parentAnimation;
  39. let beforeStylesValue = {};
  40. let afterAddClasses = [];
  41. let afterRemoveClasses = [];
  42. let afterStylesValue = {};
  43. let numAnimationsRunning = 0;
  44. let shouldForceLinearEasing = false;
  45. let shouldForceSyncPlayback = false;
  46. let forceDirectionValue;
  47. let forceDurationValue;
  48. let forceDelayValue;
  49. let willComplete = true;
  50. let finished = false;
  51. let shouldCalculateNumAnimations = true;
  52. let ani;
  53. let paused = false;
  54. const id = animationId;
  55. const onFinishCallbacks = [];
  56. const onFinishOneTimeCallbacks = [];
  57. const onStopOneTimeCallbacks = [];
  58. const elements = [];
  59. const childAnimations = [];
  60. const stylesheets = [];
  61. const _beforeAddReadFunctions = [];
  62. const _beforeAddWriteFunctions = [];
  63. const _afterAddReadFunctions = [];
  64. const _afterAddWriteFunctions = [];
  65. const webAnimations = [];
  66. const supportsAnimationEffect = typeof AnimationEffect === 'function' ||
  67. (index$1.win !== undefined && typeof index$1.win.AnimationEffect === 'function');
  68. /**
  69. * This is a feature detection for Web Animations.
  70. *
  71. * Certain environments such as emulated browser environments for testing,
  72. * do not support Web Animations. As a result, we need to check for support
  73. * and provide a fallback to test certain functionality related to Web Animations.
  74. */
  75. const supportsWebAnimations = typeof Element === 'function' &&
  76. typeof Element.prototype.animate === 'function' &&
  77. supportsAnimationEffect;
  78. const getWebAnimations = () => {
  79. return webAnimations;
  80. };
  81. const destroy = (clearStyleSheets) => {
  82. childAnimations.forEach((childAnimation) => {
  83. childAnimation.destroy(clearStyleSheets);
  84. });
  85. cleanUp(clearStyleSheets);
  86. elements.length = 0;
  87. childAnimations.length = 0;
  88. _keyframes.length = 0;
  89. clearOnFinish();
  90. initialized = false;
  91. shouldCalculateNumAnimations = true;
  92. return ani;
  93. };
  94. /**
  95. * Cancels any Web Animations, removes
  96. * any animation properties from the
  97. * animation's elements, and removes the
  98. * animation's stylesheets from the DOM.
  99. */
  100. const cleanUp = (clearStyleSheets) => {
  101. cleanUpElements();
  102. if (clearStyleSheets) {
  103. cleanUpStyleSheets();
  104. }
  105. };
  106. const resetFlags = () => {
  107. shouldForceLinearEasing = false;
  108. shouldForceSyncPlayback = false;
  109. shouldCalculateNumAnimations = true;
  110. forceDirectionValue = undefined;
  111. forceDurationValue = undefined;
  112. forceDelayValue = undefined;
  113. numAnimationsRunning = 0;
  114. finished = false;
  115. willComplete = true;
  116. paused = false;
  117. };
  118. const isRunning = () => {
  119. return numAnimationsRunning !== 0 && !paused;
  120. };
  121. /**
  122. * @internal
  123. * Remove a callback from a chosen callback array
  124. * @param callbackToRemove: A reference to the callback that should be removed
  125. * @param callbackObjects: An array of callbacks that callbackToRemove should be removed from.
  126. */
  127. const clearCallback = (callbackToRemove, callbackObjects) => {
  128. const index = callbackObjects.findIndex((callbackObject) => callbackObject.c === callbackToRemove);
  129. if (index > -1) {
  130. callbackObjects.splice(index, 1);
  131. }
  132. };
  133. /**
  134. * @internal
  135. * Add a callback to be fired when an animation is stopped/cancelled.
  136. * @param callback: A reference to the callback that should be fired
  137. * @param opts: Any options associated with this particular callback
  138. */
  139. const onStop = (callback, opts) => {
  140. onStopOneTimeCallbacks.push({ c: callback, o: opts });
  141. return ani;
  142. };
  143. const onFinish = (callback, opts) => {
  144. const callbacks = (opts === null || opts === void 0 ? void 0 : opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
  145. callbacks.push({ c: callback, o: opts });
  146. return ani;
  147. };
  148. const clearOnFinish = () => {
  149. onFinishCallbacks.length = 0;
  150. onFinishOneTimeCallbacks.length = 0;
  151. return ani;
  152. };
  153. /**
  154. * Cancels any Web Animations and removes
  155. * any animation properties from the
  156. * the animation's elements.
  157. */
  158. const cleanUpElements = () => {
  159. if (supportsWebAnimations) {
  160. webAnimations.forEach((animation) => {
  161. animation.cancel();
  162. });
  163. webAnimations.length = 0;
  164. }
  165. };
  166. /**
  167. * Removes the animation's stylesheets
  168. * from the DOM.
  169. */
  170. const cleanUpStyleSheets = () => {
  171. stylesheets.forEach((stylesheet) => {
  172. /**
  173. * When sharing stylesheets, it's possible
  174. * for another animation to have already
  175. * cleaned up a particular stylesheet
  176. */
  177. if (stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.parentNode) {
  178. stylesheet.parentNode.removeChild(stylesheet);
  179. }
  180. });
  181. stylesheets.length = 0;
  182. };
  183. const beforeAddRead = (readFn) => {
  184. _beforeAddReadFunctions.push(readFn);
  185. return ani;
  186. };
  187. const beforeAddWrite = (writeFn) => {
  188. _beforeAddWriteFunctions.push(writeFn);
  189. return ani;
  190. };
  191. const afterAddRead = (readFn) => {
  192. _afterAddReadFunctions.push(readFn);
  193. return ani;
  194. };
  195. const afterAddWrite = (writeFn) => {
  196. _afterAddWriteFunctions.push(writeFn);
  197. return ani;
  198. };
  199. const beforeAddClass = (className) => {
  200. beforeAddClasses = addClassToArray(beforeAddClasses, className);
  201. return ani;
  202. };
  203. const beforeRemoveClass = (className) => {
  204. beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
  205. return ani;
  206. };
  207. /**
  208. * Set CSS inline styles to the animation's
  209. * elements before the animation begins.
  210. */
  211. const beforeStyles = (styles = {}) => {
  212. beforeStylesValue = styles;
  213. return ani;
  214. };
  215. /**
  216. * Clear CSS inline styles from the animation's
  217. * elements before the animation begins.
  218. */
  219. const beforeClearStyles = (propertyNames = []) => {
  220. for (const property of propertyNames) {
  221. beforeStylesValue[property] = '';
  222. }
  223. return ani;
  224. };
  225. const afterAddClass = (className) => {
  226. afterAddClasses = addClassToArray(afterAddClasses, className);
  227. return ani;
  228. };
  229. const afterRemoveClass = (className) => {
  230. afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
  231. return ani;
  232. };
  233. const afterStyles = (styles = {}) => {
  234. afterStylesValue = styles;
  235. return ani;
  236. };
  237. const afterClearStyles = (propertyNames = []) => {
  238. for (const property of propertyNames) {
  239. afterStylesValue[property] = '';
  240. }
  241. return ani;
  242. };
  243. const getFill = () => {
  244. if (_fill !== undefined) {
  245. return _fill;
  246. }
  247. if (parentAnimation) {
  248. return parentAnimation.getFill();
  249. }
  250. return 'both';
  251. };
  252. const getDirection = () => {
  253. if (forceDirectionValue !== undefined) {
  254. return forceDirectionValue;
  255. }
  256. if (_direction !== undefined) {
  257. return _direction;
  258. }
  259. if (parentAnimation) {
  260. return parentAnimation.getDirection();
  261. }
  262. return 'normal';
  263. };
  264. const getEasing = () => {
  265. if (shouldForceLinearEasing) {
  266. return 'linear';
  267. }
  268. if (_easing !== undefined) {
  269. return _easing;
  270. }
  271. if (parentAnimation) {
  272. return parentAnimation.getEasing();
  273. }
  274. return 'linear';
  275. };
  276. const getDuration = () => {
  277. if (shouldForceSyncPlayback) {
  278. return 0;
  279. }
  280. if (forceDurationValue !== undefined) {
  281. return forceDurationValue;
  282. }
  283. if (_duration !== undefined) {
  284. return _duration;
  285. }
  286. if (parentAnimation) {
  287. return parentAnimation.getDuration();
  288. }
  289. return 0;
  290. };
  291. const getIterations = () => {
  292. if (_iterations !== undefined) {
  293. return _iterations;
  294. }
  295. if (parentAnimation) {
  296. return parentAnimation.getIterations();
  297. }
  298. return 1;
  299. };
  300. const getDelay = () => {
  301. if (forceDelayValue !== undefined) {
  302. return forceDelayValue;
  303. }
  304. if (_delay !== undefined) {
  305. return _delay;
  306. }
  307. if (parentAnimation) {
  308. return parentAnimation.getDelay();
  309. }
  310. return 0;
  311. };
  312. const getKeyframes = () => {
  313. return _keyframes;
  314. };
  315. const direction = (animationDirection) => {
  316. _direction = animationDirection;
  317. update(true);
  318. return ani;
  319. };
  320. const fill = (animationFill) => {
  321. _fill = animationFill;
  322. update(true);
  323. return ani;
  324. };
  325. const delay = (animationDelay) => {
  326. _delay = animationDelay;
  327. update(true);
  328. return ani;
  329. };
  330. const easing = (animationEasing) => {
  331. _easing = animationEasing;
  332. update(true);
  333. return ani;
  334. };
  335. const duration = (animationDuration) => {
  336. /**
  337. * CSS Animation Durations of 0ms work fine on Chrome
  338. * but do not run on Safari, so force it to 1ms to
  339. * get it to run on both platforms.
  340. */
  341. if (!supportsWebAnimations && animationDuration === 0) {
  342. animationDuration = 1;
  343. }
  344. _duration = animationDuration;
  345. update(true);
  346. return ani;
  347. };
  348. const iterations = (animationIterations) => {
  349. _iterations = animationIterations;
  350. update(true);
  351. return ani;
  352. };
  353. const parent = (animation) => {
  354. parentAnimation = animation;
  355. return ani;
  356. };
  357. const addElement = (el) => {
  358. if (el != null) {
  359. if (el.nodeType === 1) {
  360. elements.push(el);
  361. }
  362. else if (el.length >= 0) {
  363. for (let i = 0; i < el.length; i++) {
  364. elements.push(el[i]);
  365. }
  366. }
  367. else {
  368. index.printIonError('createAnimation - Invalid addElement value.');
  369. }
  370. }
  371. return ani;
  372. };
  373. const addAnimation = (animationToAdd) => {
  374. if (animationToAdd != null) {
  375. if (Array.isArray(animationToAdd)) {
  376. for (const animation of animationToAdd) {
  377. animation.parent(ani);
  378. childAnimations.push(animation);
  379. }
  380. }
  381. else {
  382. animationToAdd.parent(ani);
  383. childAnimations.push(animationToAdd);
  384. }
  385. }
  386. return ani;
  387. };
  388. const keyframes = (keyframeValues) => {
  389. const different = _keyframes !== keyframeValues;
  390. _keyframes = keyframeValues;
  391. if (different) {
  392. updateKeyframes(_keyframes);
  393. }
  394. return ani;
  395. };
  396. const updateKeyframes = (keyframeValues) => {
  397. if (supportsWebAnimations) {
  398. getWebAnimations().forEach((animation) => {
  399. /**
  400. * animation.effect's type is AnimationEffect.
  401. * However, in this case we have a more specific
  402. * type of AnimationEffect called KeyframeEffect which
  403. * inherits from AnimationEffect. As a result,
  404. * we cast animation.effect to KeyframeEffect.
  405. */
  406. const keyframeEffect = animation.effect;
  407. /**
  408. * setKeyframes is not supported in all browser
  409. * versions that Ionic supports, so we need to
  410. * check for support before using it.
  411. */
  412. // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
  413. if (keyframeEffect.setKeyframes) {
  414. keyframeEffect.setKeyframes(keyframeValues);
  415. }
  416. else {
  417. const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
  418. animation.effect = newEffect;
  419. }
  420. });
  421. }
  422. };
  423. /**
  424. * Run all "before" animation hooks.
  425. */
  426. const beforeAnimation = () => {
  427. // Runs all before read callbacks
  428. _beforeAddReadFunctions.forEach((callback) => callback());
  429. // Runs all before write callbacks
  430. _beforeAddWriteFunctions.forEach((callback) => callback());
  431. // Updates styles and classes before animation runs
  432. const addClasses = beforeAddClasses;
  433. const removeClasses = beforeRemoveClasses;
  434. const styles = beforeStylesValue;
  435. elements.forEach((el) => {
  436. const elementClassList = el.classList;
  437. addClasses.forEach((c) => elementClassList.add(c));
  438. removeClasses.forEach((c) => elementClassList.remove(c));
  439. for (const property in styles) {
  440. // eslint-disable-next-line no-prototype-builtins
  441. if (styles.hasOwnProperty(property)) {
  442. setStyleProperty(el, property, styles[property]);
  443. }
  444. }
  445. });
  446. };
  447. /**
  448. * Run all "after" animation hooks.
  449. */
  450. const afterAnimation = () => {
  451. // Runs all after read callbacks
  452. _afterAddReadFunctions.forEach((callback) => callback());
  453. // Runs all after write callbacks
  454. _afterAddWriteFunctions.forEach((callback) => callback());
  455. // Updates styles and classes before animation ends
  456. const currentStep = willComplete ? 1 : 0;
  457. const addClasses = afterAddClasses;
  458. const removeClasses = afterRemoveClasses;
  459. const styles = afterStylesValue;
  460. elements.forEach((el) => {
  461. const elementClassList = el.classList;
  462. addClasses.forEach((c) => elementClassList.add(c));
  463. removeClasses.forEach((c) => elementClassList.remove(c));
  464. for (const property in styles) {
  465. // eslint-disable-next-line no-prototype-builtins
  466. if (styles.hasOwnProperty(property)) {
  467. setStyleProperty(el, property, styles[property]);
  468. }
  469. }
  470. });
  471. /**
  472. * Clean up any value coercion before
  473. * the user callbacks fire otherwise
  474. * they may get stale values. For example,
  475. * if someone calls progressStart(0) the
  476. * animation may still be reversed.
  477. */
  478. forceDurationValue = undefined;
  479. forceDirectionValue = undefined;
  480. forceDelayValue = undefined;
  481. onFinishCallbacks.forEach((onFinishCallback) => {
  482. return onFinishCallback.c(currentStep, ani);
  483. });
  484. onFinishOneTimeCallbacks.forEach((onFinishCallback) => {
  485. return onFinishCallback.c(currentStep, ani);
  486. });
  487. onFinishOneTimeCallbacks.length = 0;
  488. shouldCalculateNumAnimations = true;
  489. if (willComplete) {
  490. finished = true;
  491. }
  492. willComplete = true;
  493. };
  494. const animationFinish = () => {
  495. if (numAnimationsRunning === 0) {
  496. return;
  497. }
  498. numAnimationsRunning--;
  499. if (numAnimationsRunning === 0) {
  500. afterAnimation();
  501. if (parentAnimation) {
  502. parentAnimation.animationFinish();
  503. }
  504. }
  505. };
  506. const initializeWebAnimation = () => {
  507. elements.forEach((element) => {
  508. const animation = element.animate(_keyframes, {
  509. id,
  510. delay: getDelay(),
  511. duration: getDuration(),
  512. easing: getEasing(),
  513. iterations: getIterations(),
  514. fill: getFill(),
  515. direction: getDirection(),
  516. });
  517. animation.pause();
  518. webAnimations.push(animation);
  519. });
  520. if (webAnimations.length > 0) {
  521. webAnimations[0].onfinish = () => {
  522. animationFinish();
  523. };
  524. }
  525. };
  526. const initializeAnimation = () => {
  527. beforeAnimation();
  528. if (_keyframes.length > 0) {
  529. if (supportsWebAnimations) {
  530. initializeWebAnimation();
  531. }
  532. }
  533. initialized = true;
  534. };
  535. const setAnimationStep = (step) => {
  536. step = Math.min(Math.max(step, 0), 0.9999);
  537. if (supportsWebAnimations) {
  538. webAnimations.forEach((animation) => {
  539. // When creating the animation the delay is guaranteed to be set to a number.
  540. animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
  541. animation.pause();
  542. });
  543. }
  544. };
  545. const updateWebAnimation = (step) => {
  546. webAnimations.forEach((animation) => {
  547. animation.effect.updateTiming({
  548. delay: getDelay(),
  549. duration: getDuration(),
  550. easing: getEasing(),
  551. iterations: getIterations(),
  552. fill: getFill(),
  553. direction: getDirection(),
  554. });
  555. });
  556. if (step !== undefined) {
  557. setAnimationStep(step);
  558. }
  559. };
  560. const update = (deep = false, toggleAnimationName = true, step) => {
  561. if (deep) {
  562. childAnimations.forEach((animation) => {
  563. animation.update(deep, toggleAnimationName, step);
  564. });
  565. }
  566. if (supportsWebAnimations) {
  567. updateWebAnimation(step);
  568. }
  569. return ani;
  570. };
  571. const progressStart = (forceLinearEasing = false, step) => {
  572. childAnimations.forEach((animation) => {
  573. animation.progressStart(forceLinearEasing, step);
  574. });
  575. pauseAnimation();
  576. shouldForceLinearEasing = forceLinearEasing;
  577. if (!initialized) {
  578. initializeAnimation();
  579. }
  580. update(false, true, step);
  581. return ani;
  582. };
  583. const progressStep = (step) => {
  584. childAnimations.forEach((animation) => {
  585. animation.progressStep(step);
  586. });
  587. setAnimationStep(step);
  588. return ani;
  589. };
  590. const progressEnd = (playTo, step, dur) => {
  591. shouldForceLinearEasing = false;
  592. childAnimations.forEach((animation) => {
  593. animation.progressEnd(playTo, step, dur);
  594. });
  595. if (dur !== undefined) {
  596. forceDurationValue = dur;
  597. }
  598. finished = false;
  599. willComplete = true;
  600. if (playTo === 0) {
  601. forceDirectionValue = getDirection() === 'reverse' ? 'normal' : 'reverse';
  602. if (forceDirectionValue === 'reverse') {
  603. willComplete = false;
  604. }
  605. if (supportsWebAnimations) {
  606. update();
  607. setAnimationStep(1 - step);
  608. }
  609. else {
  610. forceDelayValue = (1 - step) * getDuration() * -1;
  611. update(false, false);
  612. }
  613. }
  614. else if (playTo === 1) {
  615. if (supportsWebAnimations) {
  616. update();
  617. setAnimationStep(step);
  618. }
  619. else {
  620. forceDelayValue = step * getDuration() * -1;
  621. update(false, false);
  622. }
  623. }
  624. if (playTo !== undefined && !parentAnimation) {
  625. play();
  626. }
  627. return ani;
  628. };
  629. const pauseAnimation = () => {
  630. if (initialized) {
  631. if (supportsWebAnimations) {
  632. webAnimations.forEach((animation) => {
  633. animation.pause();
  634. });
  635. }
  636. else {
  637. elements.forEach((element) => {
  638. setStyleProperty(element, 'animation-play-state', 'paused');
  639. });
  640. }
  641. paused = true;
  642. }
  643. };
  644. const pause = () => {
  645. childAnimations.forEach((animation) => {
  646. animation.pause();
  647. });
  648. pauseAnimation();
  649. return ani;
  650. };
  651. const playCSSAnimations = () => {
  652. animationFinish();
  653. };
  654. const playWebAnimations = () => {
  655. webAnimations.forEach((animation) => {
  656. animation.play();
  657. });
  658. if (_keyframes.length === 0 || elements.length === 0) {
  659. animationFinish();
  660. }
  661. };
  662. const resetAnimation = () => {
  663. if (supportsWebAnimations) {
  664. setAnimationStep(0);
  665. updateWebAnimation();
  666. }
  667. };
  668. const play = (opts) => {
  669. return new Promise((resolve) => {
  670. if (opts === null || opts === void 0 ? void 0 : opts.sync) {
  671. shouldForceSyncPlayback = true;
  672. onFinish(() => (shouldForceSyncPlayback = false), { oneTimeCallback: true });
  673. }
  674. if (!initialized) {
  675. initializeAnimation();
  676. }
  677. if (finished) {
  678. resetAnimation();
  679. finished = false;
  680. }
  681. if (shouldCalculateNumAnimations) {
  682. numAnimationsRunning = childAnimations.length + 1;
  683. shouldCalculateNumAnimations = false;
  684. }
  685. /**
  686. * When one of these callbacks fires we
  687. * need to clear the other's callback otherwise
  688. * you can potentially get these callbacks
  689. * firing multiple times if the play method
  690. * is subsequently called.
  691. * Example:
  692. * animation.play() (onStop and onFinish callbacks are registered)
  693. * animation.stop() (onStop callback is fired, onFinish is not)
  694. * animation.play() (onStop and onFinish callbacks are registered)
  695. * Total onStop callbacks: 1
  696. * Total onFinish callbacks: 2
  697. */
  698. const onStopCallback = () => {
  699. clearCallback(onFinishCallback, onFinishOneTimeCallbacks);
  700. resolve();
  701. };
  702. const onFinishCallback = () => {
  703. clearCallback(onStopCallback, onStopOneTimeCallbacks);
  704. resolve();
  705. };
  706. /**
  707. * The play method resolves when an animation
  708. * run either finishes or is cancelled.
  709. */
  710. onFinish(onFinishCallback, { oneTimeCallback: true });
  711. onStop(onStopCallback, { oneTimeCallback: true });
  712. childAnimations.forEach((animation) => {
  713. animation.play();
  714. });
  715. if (supportsWebAnimations) {
  716. playWebAnimations();
  717. }
  718. else {
  719. playCSSAnimations();
  720. }
  721. paused = false;
  722. });
  723. };
  724. /**
  725. * Stops an animation and resets it state to the
  726. * beginning. This does not fire any onFinish
  727. * callbacks because the animation did not finish.
  728. * However, since the animation was not destroyed
  729. * (i.e. the animation could run again) we do not
  730. * clear the onFinish callbacks.
  731. */
  732. const stop = () => {
  733. childAnimations.forEach((animation) => {
  734. animation.stop();
  735. });
  736. if (initialized) {
  737. cleanUpElements();
  738. initialized = false;
  739. }
  740. resetFlags();
  741. onStopOneTimeCallbacks.forEach((onStopCallback) => onStopCallback.c(0, ani));
  742. onStopOneTimeCallbacks.length = 0;
  743. };
  744. const from = (property, value) => {
  745. const firstFrame = _keyframes[0];
  746. if (firstFrame !== undefined && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
  747. firstFrame[property] = value;
  748. }
  749. else {
  750. _keyframes = [{ offset: 0, [property]: value }, ..._keyframes];
  751. }
  752. return ani;
  753. };
  754. const to = (property, value) => {
  755. const lastFrame = _keyframes[_keyframes.length - 1];
  756. if (lastFrame !== undefined && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
  757. lastFrame[property] = value;
  758. }
  759. else {
  760. _keyframes = [..._keyframes, { offset: 1, [property]: value }];
  761. }
  762. return ani;
  763. };
  764. const fromTo = (property, fromValue, toValue) => {
  765. return from(property, fromValue).to(property, toValue);
  766. };
  767. return (ani = {
  768. parentAnimation,
  769. elements,
  770. childAnimations,
  771. id,
  772. animationFinish,
  773. from,
  774. to,
  775. fromTo,
  776. parent,
  777. play,
  778. pause,
  779. stop,
  780. destroy,
  781. keyframes,
  782. addAnimation,
  783. addElement,
  784. update,
  785. fill,
  786. direction,
  787. iterations,
  788. duration,
  789. easing,
  790. delay,
  791. getWebAnimations,
  792. getKeyframes,
  793. getFill,
  794. getDirection,
  795. getDelay,
  796. getIterations,
  797. getEasing,
  798. getDuration,
  799. afterAddRead,
  800. afterAddWrite,
  801. afterClearStyles,
  802. afterStyles,
  803. afterRemoveClass,
  804. afterAddClass,
  805. beforeAddRead,
  806. beforeAddWrite,
  807. beforeClearStyles,
  808. beforeStyles,
  809. beforeRemoveClass,
  810. beforeAddClass,
  811. onFinish,
  812. isRunning,
  813. progressStart,
  814. progressStep,
  815. progressEnd,
  816. });
  817. };
  818. exports.createAnimation = createAnimation;