animations.mjs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /**
  2. * @license Angular v16.0.4
  3. * (c) 2010-2022 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. /**
  7. * An injectable service that produces an animation sequence programmatically within an
  8. * Angular component or directive.
  9. * Provided by the `BrowserAnimationsModule` or `NoopAnimationsModule`.
  10. *
  11. * @usageNotes
  12. *
  13. * To use this service, add it to your component or directive as a dependency.
  14. * The service is instantiated along with your component.
  15. *
  16. * Apps do not typically need to create their own animation players, but if you
  17. * do need to, follow these steps:
  18. *
  19. * 1. Use the <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code> method
  20. * to create a programmatic animation. The method returns an `AnimationFactory` instance.
  21. *
  22. * 2. Use the factory object to create an `AnimationPlayer` and attach it to a DOM element.
  23. *
  24. * 3. Use the player object to control the animation programmatically.
  25. *
  26. * For example:
  27. *
  28. * ```ts
  29. * // import the service from BrowserAnimationsModule
  30. * import {AnimationBuilder} from '@angular/animations';
  31. * // require the service as a dependency
  32. * class MyCmp {
  33. * constructor(private _builder: AnimationBuilder) {}
  34. *
  35. * makeAnimation(element: any) {
  36. * // first define a reusable animation
  37. * const myAnimation = this._builder.build([
  38. * style({ width: 0 }),
  39. * animate(1000, style({ width: '100px' }))
  40. * ]);
  41. *
  42. * // use the returned factory object to create a player
  43. * const player = myAnimation.create(element);
  44. *
  45. * player.play();
  46. * }
  47. * }
  48. * ```
  49. *
  50. * @publicApi
  51. */
  52. class AnimationBuilder {
  53. }
  54. /**
  55. * A factory object returned from the
  56. * <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code>
  57. * method.
  58. *
  59. * @publicApi
  60. */
  61. class AnimationFactory {
  62. }
  63. /**
  64. * Specifies automatic styling.
  65. *
  66. * @publicApi
  67. */
  68. const AUTO_STYLE = '*';
  69. /**
  70. * Creates a named animation trigger, containing a list of [`state()`](api/animations/state)
  71. * and `transition()` entries to be evaluated when the expression
  72. * bound to the trigger changes.
  73. *
  74. * @param name An identifying string.
  75. * @param definitions An animation definition object, containing an array of
  76. * [`state()`](api/animations/state) and `transition()` declarations.
  77. *
  78. * @return An object that encapsulates the trigger data.
  79. *
  80. * @usageNotes
  81. * Define an animation trigger in the `animations` section of `@Component` metadata.
  82. * In the template, reference the trigger by name and bind it to a trigger expression that
  83. * evaluates to a defined animation state, using the following format:
  84. *
  85. * `[@triggerName]="expression"`
  86. *
  87. * Animation trigger bindings convert all values to strings, and then match the
  88. * previous and current values against any linked transitions.
  89. * Booleans can be specified as `1` or `true` and `0` or `false`.
  90. *
  91. * ### Usage Example
  92. *
  93. * The following example creates an animation trigger reference based on the provided
  94. * name value.
  95. * The provided animation value is expected to be an array consisting of state and
  96. * transition declarations.
  97. *
  98. * ```typescript
  99. * @Component({
  100. * selector: "my-component",
  101. * templateUrl: "my-component-tpl.html",
  102. * animations: [
  103. * trigger("myAnimationTrigger", [
  104. * state(...),
  105. * state(...),
  106. * transition(...),
  107. * transition(...)
  108. * ])
  109. * ]
  110. * })
  111. * class MyComponent {
  112. * myStatusExp = "something";
  113. * }
  114. * ```
  115. *
  116. * The template associated with this component makes use of the defined trigger
  117. * by binding to an element within its template code.
  118. *
  119. * ```html
  120. * <!-- somewhere inside of my-component-tpl.html -->
  121. * <div [@myAnimationTrigger]="myStatusExp">...</div>
  122. * ```
  123. *
  124. * ### Using an inline function
  125. * The `transition` animation method also supports reading an inline function which can decide
  126. * if its associated animation should be run.
  127. *
  128. * ```typescript
  129. * // this method is run each time the `myAnimationTrigger` trigger value changes.
  130. * function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
  131. string]: any}): boolean {
  132. * // notice that `element` and `params` are also available here
  133. * return toState == 'yes-please-animate';
  134. * }
  135. *
  136. * @Component({
  137. * selector: 'my-component',
  138. * templateUrl: 'my-component-tpl.html',
  139. * animations: [
  140. * trigger('myAnimationTrigger', [
  141. * transition(myInlineMatcherFn, [
  142. * // the animation sequence code
  143. * ]),
  144. * ])
  145. * ]
  146. * })
  147. * class MyComponent {
  148. * myStatusExp = "yes-please-animate";
  149. * }
  150. * ```
  151. *
  152. * ### Disabling Animations
  153. * When true, the special animation control binding `@.disabled` binding prevents
  154. * all animations from rendering.
  155. * Place the `@.disabled` binding on an element to disable
  156. * animations on the element itself, as well as any inner animation triggers
  157. * within the element.
  158. *
  159. * The following example shows how to use this feature:
  160. *
  161. * ```typescript
  162. * @Component({
  163. * selector: 'my-component',
  164. * template: `
  165. * <div [@.disabled]="isDisabled">
  166. * <div [@childAnimation]="exp"></div>
  167. * </div>
  168. * `,
  169. * animations: [
  170. * trigger("childAnimation", [
  171. * // ...
  172. * ])
  173. * ]
  174. * })
  175. * class MyComponent {
  176. * isDisabled = true;
  177. * exp = '...';
  178. * }
  179. * ```
  180. *
  181. * When `@.disabled` is true, it prevents the `@childAnimation` trigger from animating,
  182. * along with any inner animations.
  183. *
  184. * ### Disable animations application-wide
  185. * When an area of the template is set to have animations disabled,
  186. * **all** inner components have their animations disabled as well.
  187. * This means that you can disable all animations for an app
  188. * by placing a host binding set on `@.disabled` on the topmost Angular component.
  189. *
  190. * ```typescript
  191. * import {Component, HostBinding} from '@angular/core';
  192. *
  193. * @Component({
  194. * selector: 'app-component',
  195. * templateUrl: 'app.component.html',
  196. * })
  197. * class AppComponent {
  198. * @HostBinding('@.disabled')
  199. * public animationsDisabled = true;
  200. * }
  201. * ```
  202. *
  203. * ### Overriding disablement of inner animations
  204. * Despite inner animations being disabled, a parent animation can `query()`
  205. * for inner elements located in disabled areas of the template and still animate
  206. * them if needed. This is also the case for when a sub animation is
  207. * queried by a parent and then later animated using `animateChild()`.
  208. *
  209. * ### Detecting when an animation is disabled
  210. * If a region of the DOM (or the entire application) has its animations disabled, the animation
  211. * trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
  212. * an instance of an `AnimationEvent`. If animations are disabled,
  213. * the `.disabled` flag on the event is true.
  214. *
  215. * @publicApi
  216. */
  217. function trigger(name, definitions) {
  218. return { type: 7 /* AnimationMetadataType.Trigger */, name, definitions, options: {} };
  219. }
  220. /**
  221. * Defines an animation step that combines styling information with timing information.
  222. *
  223. * @param timings Sets `AnimateTimings` for the parent animation.
  224. * A string in the format "duration [delay] [easing]".
  225. * - Duration and delay are expressed as a number and optional time unit,
  226. * such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
  227. * The default unit is milliseconds.
  228. * - The easing value controls how the animation accelerates and decelerates
  229. * during its runtime. Value is one of `ease`, `ease-in`, `ease-out`,
  230. * `ease-in-out`, or a `cubic-bezier()` function call.
  231. * If not supplied, no easing is applied.
  232. *
  233. * For example, the string "1s 100ms ease-out" specifies a duration of
  234. * 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
  235. * which decelerates near the end of the duration.
  236. * @param styles Sets AnimationStyles for the parent animation.
  237. * A function call to either `style()` or `keyframes()`
  238. * that returns a collection of CSS style entries to be applied to the parent animation.
  239. * When null, uses the styles from the destination state.
  240. * This is useful when describing an animation step that will complete an animation;
  241. * see "Animating to the final state" in `transitions()`.
  242. * @returns An object that encapsulates the animation step.
  243. *
  244. * @usageNotes
  245. * Call within an animation `sequence()`, `{@link animations/group group()}`, or
  246. * `transition()` call to specify an animation step
  247. * that applies given style data to the parent animation for a given amount of time.
  248. *
  249. * ### Syntax Examples
  250. * **Timing examples**
  251. *
  252. * The following examples show various `timings` specifications.
  253. * - `animate(500)` : Duration is 500 milliseconds.
  254. * - `animate("1s")` : Duration is 1000 milliseconds.
  255. * - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
  256. * - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
  257. * - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
  258. * milliseconds, easing according to a bezier curve.
  259. *
  260. * **Style examples**
  261. *
  262. * The following example calls `style()` to set a single CSS style.
  263. * ```typescript
  264. * animate(500, style({ background: "red" }))
  265. * ```
  266. * The following example calls `keyframes()` to set a CSS style
  267. * to different values for successive keyframes.
  268. * ```typescript
  269. * animate(500, keyframes(
  270. * [
  271. * style({ background: "blue" }),
  272. * style({ background: "red" })
  273. * ])
  274. * ```
  275. *
  276. * @publicApi
  277. */
  278. function animate(timings, styles = null) {
  279. return { type: 4 /* AnimationMetadataType.Animate */, styles, timings };
  280. }
  281. /**
  282. * @description Defines a list of animation steps to be run in parallel.
  283. *
  284. * @param steps An array of animation step objects.
  285. * - When steps are defined by `style()` or `animate()`
  286. * function calls, each call within the group is executed instantly.
  287. * - To specify offset styles to be applied at a later time, define steps with
  288. * `keyframes()`, or use `animate()` calls with a delay value.
  289. * For example:
  290. *
  291. * ```typescript
  292. * group([
  293. * animate("1s", style({ background: "black" })),
  294. * animate("2s", style({ color: "white" }))
  295. * ])
  296. * ```
  297. *
  298. * @param options An options object containing a delay and
  299. * developer-defined parameters that provide styling defaults and
  300. * can be overridden on invocation.
  301. *
  302. * @return An object that encapsulates the group data.
  303. *
  304. * @usageNotes
  305. * Grouped animations are useful when a series of styles must be
  306. * animated at different starting times and closed off at different ending times.
  307. *
  308. * When called within a `sequence()` or a
  309. * `transition()` call, does not continue to the next
  310. * instruction until all of the inner animation steps have completed.
  311. *
  312. * @publicApi
  313. */
  314. function group(steps, options = null) {
  315. return { type: 3 /* AnimationMetadataType.Group */, steps, options };
  316. }
  317. /**
  318. * Defines a list of animation steps to be run sequentially, one by one.
  319. *
  320. * @param steps An array of animation step objects.
  321. * - Steps defined by `style()` calls apply the styling data immediately.
  322. * - Steps defined by `animate()` calls apply the styling data over time
  323. * as specified by the timing data.
  324. *
  325. * ```typescript
  326. * sequence([
  327. * style({ opacity: 0 }),
  328. * animate("1s", style({ opacity: 1 }))
  329. * ])
  330. * ```
  331. *
  332. * @param options An options object containing a delay and
  333. * developer-defined parameters that provide styling defaults and
  334. * can be overridden on invocation.
  335. *
  336. * @return An object that encapsulates the sequence data.
  337. *
  338. * @usageNotes
  339. * When you pass an array of steps to a
  340. * `transition()` call, the steps run sequentially by default.
  341. * Compare this to the `{@link animations/group group()}` call, which runs animation steps in
  342. *parallel.
  343. *
  344. * When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
  345. * execution continues to the next instruction only after each of the inner animation
  346. * steps have completed.
  347. *
  348. * @publicApi
  349. **/
  350. function sequence(steps, options = null) {
  351. return { type: 2 /* AnimationMetadataType.Sequence */, steps, options };
  352. }
  353. /**
  354. * Declares a key/value object containing CSS properties/styles that
  355. * can then be used for an animation [`state`](api/animations/state), within an animation
  356. *`sequence`, or as styling data for calls to `animate()` and `keyframes()`.
  357. *
  358. * @param tokens A set of CSS styles or HTML styles associated with an animation state.
  359. * The value can be any of the following:
  360. * - A key-value style pair associating a CSS property with a value.
  361. * - An array of key-value style pairs.
  362. * - An asterisk (*), to use auto-styling, where styles are derived from the element
  363. * being animated and applied to the animation when it starts.
  364. *
  365. * Auto-styling can be used to define a state that depends on layout or other
  366. * environmental factors.
  367. *
  368. * @return An object that encapsulates the style data.
  369. *
  370. * @usageNotes
  371. * The following examples create animation styles that collect a set of
  372. * CSS property values:
  373. *
  374. * ```typescript
  375. * // string values for CSS properties
  376. * style({ background: "red", color: "blue" })
  377. *
  378. * // numerical pixel values
  379. * style({ width: 100, height: 0 })
  380. * ```
  381. *
  382. * The following example uses auto-styling to allow an element to animate from
  383. * a height of 0 up to its full height:
  384. *
  385. * ```
  386. * style({ height: 0 }),
  387. * animate("1s", style({ height: "*" }))
  388. * ```
  389. *
  390. * @publicApi
  391. **/
  392. function style(tokens) {
  393. return { type: 6 /* AnimationMetadataType.Style */, styles: tokens, offset: null };
  394. }
  395. /**
  396. * Declares an animation state within a trigger attached to an element.
  397. *
  398. * @param name One or more names for the defined state in a comma-separated string.
  399. * The following reserved state names can be supplied to define a style for specific use
  400. * cases:
  401. *
  402. * - `void` You can associate styles with this name to be used when
  403. * the element is detached from the application. For example, when an `ngIf` evaluates
  404. * to false, the state of the associated element is void.
  405. * - `*` (asterisk) Indicates the default state. You can associate styles with this name
  406. * to be used as the fallback when the state that is being animated is not declared
  407. * within the trigger.
  408. *
  409. * @param styles A set of CSS styles associated with this state, created using the
  410. * `style()` function.
  411. * This set of styles persists on the element once the state has been reached.
  412. * @param options Parameters that can be passed to the state when it is invoked.
  413. * 0 or more key-value pairs.
  414. * @return An object that encapsulates the new state data.
  415. *
  416. * @usageNotes
  417. * Use the `trigger()` function to register states to an animation trigger.
  418. * Use the `transition()` function to animate between states.
  419. * When a state is active within a component, its associated styles persist on the element,
  420. * even when the animation ends.
  421. *
  422. * @publicApi
  423. **/
  424. function state(name, styles, options) {
  425. return { type: 0 /* AnimationMetadataType.State */, name, styles, options };
  426. }
  427. /**
  428. * Defines a set of animation styles, associating each style with an optional `offset` value.
  429. *
  430. * @param steps A set of animation styles with optional offset data.
  431. * The optional `offset` value for a style specifies a percentage of the total animation
  432. * time at which that style is applied.
  433. * @returns An object that encapsulates the keyframes data.
  434. *
  435. * @usageNotes
  436. * Use with the `animate()` call. Instead of applying animations
  437. * from the current state
  438. * to the destination state, keyframes describe how each style entry is applied and at what point
  439. * within the animation arc.
  440. * Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
  441. *
  442. * ### Usage
  443. *
  444. * In the following example, the offset values describe
  445. * when each `backgroundColor` value is applied. The color is red at the start, and changes to
  446. * blue when 20% of the total time has elapsed.
  447. *
  448. * ```typescript
  449. * // the provided offset values
  450. * animate("5s", keyframes([
  451. * style({ backgroundColor: "red", offset: 0 }),
  452. * style({ backgroundColor: "blue", offset: 0.2 }),
  453. * style({ backgroundColor: "orange", offset: 0.3 }),
  454. * style({ backgroundColor: "black", offset: 1 })
  455. * ]))
  456. * ```
  457. *
  458. * If there are no `offset` values specified in the style entries, the offsets
  459. * are calculated automatically.
  460. *
  461. * ```typescript
  462. * animate("5s", keyframes([
  463. * style({ backgroundColor: "red" }) // offset = 0
  464. * style({ backgroundColor: "blue" }) // offset = 0.33
  465. * style({ backgroundColor: "orange" }) // offset = 0.66
  466. * style({ backgroundColor: "black" }) // offset = 1
  467. * ]))
  468. *```
  469. * @publicApi
  470. */
  471. function keyframes(steps) {
  472. return { type: 5 /* AnimationMetadataType.Keyframes */, steps };
  473. }
  474. /**
  475. * Declares an animation transition which is played when a certain specified condition is met.
  476. *
  477. * @param stateChangeExpr A string with a specific format or a function that specifies when the
  478. * animation transition should occur (see [State Change Expression](#state-change-expression)).
  479. *
  480. * @param steps One or more animation objects that represent the animation's instructions.
  481. *
  482. * @param options An options object that can be used to specify a delay for the animation or provide
  483. * custom parameters for it.
  484. *
  485. * @returns An object that encapsulates the transition data.
  486. *
  487. * @usageNotes
  488. *
  489. * ### State Change Expression
  490. *
  491. * The State Change Expression instructs Angular when to run the transition's animations, it can
  492. *either be
  493. * - a string with a specific syntax
  494. * - or a function that compares the previous and current state (value of the expression bound to
  495. * the element's trigger) and returns `true` if the transition should occur or `false` otherwise
  496. *
  497. * The string format can be:
  498. * - `fromState => toState`, which indicates that the transition's animations should occur then the
  499. * expression bound to the trigger's element goes from `fromState` to `toState`
  500. *
  501. * _Example:_
  502. * ```typescript
  503. * transition('open => closed', animate('.5s ease-out', style({ height: 0 }) ))
  504. * ```
  505. *
  506. * - `fromState <=> toState`, which indicates that the transition's animations should occur then
  507. * the expression bound to the trigger's element goes from `fromState` to `toState` or vice versa
  508. *
  509. * _Example:_
  510. * ```typescript
  511. * transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))
  512. * ```
  513. *
  514. * - `:enter`/`:leave`, which indicates that the transition's animations should occur when the
  515. * element enters or exists the DOM
  516. *
  517. * _Example:_
  518. * ```typescript
  519. * transition(':enter', [
  520. * style({ opacity: 0 }),
  521. * animate('500ms', style({ opacity: 1 }))
  522. * ])
  523. * ```
  524. *
  525. * - `:increment`/`:decrement`, which indicates that the transition's animations should occur when
  526. * the numerical expression bound to the trigger's element has increased in value or decreased
  527. *
  528. * _Example:_
  529. * ```typescript
  530. * transition(':increment', query('@counter', animateChild()))
  531. * ```
  532. *
  533. * - a sequence of any of the above divided by commas, which indicates that transition's animations
  534. * should occur whenever one of the state change expressions matches
  535. *
  536. * _Example:_
  537. * ```typescript
  538. * transition(':increment, * => enabled, :enter', animate('1s ease', keyframes([
  539. * style({ transform: 'scale(1)', offset: 0}),
  540. * style({ transform: 'scale(1.1)', offset: 0.7}),
  541. * style({ transform: 'scale(1)', offset: 1})
  542. * ]))),
  543. * ```
  544. *
  545. * Also note that in such context:
  546. * - `void` can be used to indicate the absence of the element
  547. * - asterisks can be used as wildcards that match any state
  548. * - (as a consequence of the above, `void => *` is equivalent to `:enter` and `* => void` is
  549. * equivalent to `:leave`)
  550. * - `true` and `false` also match expression values of `1` and `0` respectively (but do not match
  551. * _truthy_ and _falsy_ values)
  552. *
  553. * <div class="alert is-helpful">
  554. *
  555. * Be careful about entering end leaving elements as their transitions present a common
  556. * pitfall for developers.
  557. *
  558. * Note that when an element with a trigger enters the DOM its `:enter` transition always
  559. * gets executed, but its `:leave` transition will not be executed if the element is removed
  560. * alongside its parent (as it will be removed "without warning" before its transition has
  561. * a chance to be executed, the only way that such transition can occur is if the element
  562. * is exiting the DOM on its own).
  563. *
  564. *
  565. * </div>
  566. *
  567. * ### Animating to a Final State
  568. *
  569. * If the final step in a transition is a call to `animate()` that uses a timing value
  570. * with no `style` data, that step is automatically considered the final animation arc,
  571. * for the element to reach the final state, in such case Angular automatically adds or removes
  572. * CSS styles to ensure that the element is in the correct final state.
  573. *
  574. *
  575. * ### Usage Examples
  576. *
  577. * - Transition animations applied based on
  578. * the trigger's expression value
  579. *
  580. * ```HTML
  581. * <div [@myAnimationTrigger]="myStatusExp">
  582. * ...
  583. * </div>
  584. * ```
  585. *
  586. * ```typescript
  587. * trigger("myAnimationTrigger", [
  588. * ..., // states
  589. * transition("on => off, open => closed", animate(500)),
  590. * transition("* <=> error", query('.indicator', animateChild()))
  591. * ])
  592. * ```
  593. *
  594. * - Transition animations applied based on custom logic dependent
  595. * on the trigger's expression value and provided parameters
  596. *
  597. * ```HTML
  598. * <div [@myAnimationTrigger]="{
  599. * value: stepName,
  600. * params: { target: currentTarget }
  601. * }">
  602. * ...
  603. * </div>
  604. * ```
  605. *
  606. * ```typescript
  607. * trigger("myAnimationTrigger", [
  608. * ..., // states
  609. * transition(
  610. * (fromState, toState, _element, params) =>
  611. * ['firststep', 'laststep'].includes(fromState.toLowerCase())
  612. * && toState === params?.['target'],
  613. * animate('1s')
  614. * )
  615. * ])
  616. * ```
  617. *
  618. * @publicApi
  619. **/
  620. function transition(stateChangeExpr, steps, options = null) {
  621. return { type: 1 /* AnimationMetadataType.Transition */, expr: stateChangeExpr, animation: steps, options };
  622. }
  623. /**
  624. * Produces a reusable animation that can be invoked in another animation or sequence,
  625. * by calling the `useAnimation()` function.
  626. *
  627. * @param steps One or more animation objects, as returned by the `animate()`
  628. * or `sequence()` function, that form a transformation from one state to another.
  629. * A sequence is used by default when you pass an array.
  630. * @param options An options object that can contain a delay value for the start of the
  631. * animation, and additional developer-defined parameters.
  632. * Provided values for additional parameters are used as defaults,
  633. * and override values can be passed to the caller on invocation.
  634. * @returns An object that encapsulates the animation data.
  635. *
  636. * @usageNotes
  637. * The following example defines a reusable animation, providing some default parameter
  638. * values.
  639. *
  640. * ```typescript
  641. * var fadeAnimation = animation([
  642. * style({ opacity: '{{ start }}' }),
  643. * animate('{{ time }}',
  644. * style({ opacity: '{{ end }}'}))
  645. * ],
  646. * { params: { time: '1000ms', start: 0, end: 1 }});
  647. * ```
  648. *
  649. * The following invokes the defined animation with a call to `useAnimation()`,
  650. * passing in override parameter values.
  651. *
  652. * ```js
  653. * useAnimation(fadeAnimation, {
  654. * params: {
  655. * time: '2s',
  656. * start: 1,
  657. * end: 0
  658. * }
  659. * })
  660. * ```
  661. *
  662. * If any of the passed-in parameter values are missing from this call,
  663. * the default values are used. If one or more parameter values are missing before a step is
  664. * animated, `useAnimation()` throws an error.
  665. *
  666. * @publicApi
  667. */
  668. function animation(steps, options = null) {
  669. return { type: 8 /* AnimationMetadataType.Reference */, animation: steps, options };
  670. }
  671. /**
  672. * Executes a queried inner animation element within an animation sequence.
  673. *
  674. * @param options An options object that can contain a delay value for the start of the
  675. * animation, and additional override values for developer-defined parameters.
  676. * @return An object that encapsulates the child animation data.
  677. *
  678. * @usageNotes
  679. * Each time an animation is triggered in Angular, the parent animation
  680. * has priority and any child animations are blocked. In order
  681. * for a child animation to run, the parent animation must query each of the elements
  682. * containing child animations, and run them using this function.
  683. *
  684. * Note that this feature is designed to be used with `query()` and it will only work
  685. * with animations that are assigned using the Angular animation library. CSS keyframes
  686. * and transitions are not handled by this API.
  687. *
  688. * @publicApi
  689. */
  690. function animateChild(options = null) {
  691. return { type: 9 /* AnimationMetadataType.AnimateChild */, options };
  692. }
  693. /**
  694. * Starts a reusable animation that is created using the `animation()` function.
  695. *
  696. * @param animation The reusable animation to start.
  697. * @param options An options object that can contain a delay value for the start of
  698. * the animation, and additional override values for developer-defined parameters.
  699. * @return An object that contains the animation parameters.
  700. *
  701. * @publicApi
  702. */
  703. function useAnimation(animation, options = null) {
  704. return { type: 10 /* AnimationMetadataType.AnimateRef */, animation, options };
  705. }
  706. /**
  707. * Finds one or more inner elements within the current element that is
  708. * being animated within a sequence. Use with `animate()`.
  709. *
  710. * @param selector The element to query, or a set of elements that contain Angular-specific
  711. * characteristics, specified with one or more of the following tokens.
  712. * - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements (not
  713. * all elements can be queried via these tokens, see
  714. * [Entering and Leaving Elements](#entering-and-leaving-elements))
  715. * - `query(":animating")` : Query all currently animating elements.
  716. * - `query("@triggerName")` : Query elements that contain an animation trigger.
  717. * - `query("@*")` : Query all elements that contain an animation triggers.
  718. * - `query(":self")` : Include the current element into the animation sequence.
  719. *
  720. * @param animation One or more animation steps to apply to the queried element or elements.
  721. * An array is treated as an animation sequence.
  722. * @param options An options object. Use the 'limit' field to limit the total number of
  723. * items to collect.
  724. * @return An object that encapsulates the query data.
  725. *
  726. * @usageNotes
  727. *
  728. * ### Multiple Tokens
  729. *
  730. * Tokens can be merged into a combined query selector string. For example:
  731. *
  732. * ```typescript
  733. * query(':self, .record:enter, .record:leave, @subTrigger', [...])
  734. * ```
  735. *
  736. * The `query()` function collects multiple elements and works internally by using
  737. * `element.querySelectorAll`. Use the `limit` field of an options object to limit
  738. * the total number of items to be collected. For example:
  739. *
  740. * ```js
  741. * query('div', [
  742. * animate(...),
  743. * animate(...)
  744. * ], { limit: 1 })
  745. * ```
  746. *
  747. * By default, throws an error when zero items are found. Set the
  748. * `optional` flag to ignore this error. For example:
  749. *
  750. * ```js
  751. * query('.some-element-that-may-not-be-there', [
  752. * animate(...),
  753. * animate(...)
  754. * ], { optional: true })
  755. * ```
  756. *
  757. * ### Entering and Leaving Elements
  758. *
  759. * Not all elements can be queried via the `:enter` and `:leave` tokens, the only ones
  760. * that can are those that Angular assumes can enter/leave based on their own logic
  761. * (if their insertion/removal is simply a consequence of that of their parent they
  762. * should be queried via a different token in their parent's `:enter`/`:leave` transitions).
  763. *
  764. * The only elements Angular assumes can enter/leave based on their own logic (thus the only
  765. * ones that can be queried via the `:enter` and `:leave` tokens) are:
  766. * - Those inserted dynamically (via `ViewContainerRef`)
  767. * - Those that have a structural directive (which, under the hood, are a subset of the above ones)
  768. *
  769. * <div class="alert is-helpful">
  770. *
  771. * Note that elements will be successfully queried via `:enter`/`:leave` even if their
  772. * insertion/removal is not done manually via `ViewContainerRef`or caused by their structural
  773. * directive (e.g. they enter/exit alongside their parent).
  774. *
  775. * </div>
  776. *
  777. * <div class="alert is-important">
  778. *
  779. * There is an exception to what previously mentioned, besides elements entering/leaving based on
  780. * their own logic, elements with an animation trigger can always be queried via `:leave` when
  781. * their parent is also leaving.
  782. *
  783. * </div>
  784. *
  785. * ### Usage Example
  786. *
  787. * The following example queries for inner elements and animates them
  788. * individually using `animate()`.
  789. *
  790. * ```typescript
  791. * @Component({
  792. * selector: 'inner',
  793. * template: `
  794. * <div [@queryAnimation]="exp">
  795. * <h1>Title</h1>
  796. * <div class="content">
  797. * Blah blah blah
  798. * </div>
  799. * </div>
  800. * `,
  801. * animations: [
  802. * trigger('queryAnimation', [
  803. * transition('* => goAnimate', [
  804. * // hide the inner elements
  805. * query('h1', style({ opacity: 0 })),
  806. * query('.content', style({ opacity: 0 })),
  807. *
  808. * // animate the inner elements in, one by one
  809. * query('h1', animate(1000, style({ opacity: 1 }))),
  810. * query('.content', animate(1000, style({ opacity: 1 }))),
  811. * ])
  812. * ])
  813. * ]
  814. * })
  815. * class Cmp {
  816. * exp = '';
  817. *
  818. * goAnimate() {
  819. * this.exp = 'goAnimate';
  820. * }
  821. * }
  822. * ```
  823. *
  824. * @publicApi
  825. */
  826. function query(selector, animation, options = null) {
  827. return { type: 11 /* AnimationMetadataType.Query */, selector, animation, options };
  828. }
  829. /**
  830. * Use within an animation `query()` call to issue a timing gap after
  831. * each queried item is animated.
  832. *
  833. * @param timings A delay value.
  834. * @param animation One ore more animation steps.
  835. * @returns An object that encapsulates the stagger data.
  836. *
  837. * @usageNotes
  838. * In the following example, a container element wraps a list of items stamped out
  839. * by an `ngFor`. The container element contains an animation trigger that will later be set
  840. * to query for each of the inner items.
  841. *
  842. * Each time items are added, the opacity fade-in animation runs,
  843. * and each removed item is faded out.
  844. * When either of these animations occur, the stagger effect is
  845. * applied after each item's animation is started.
  846. *
  847. * ```html
  848. * <!-- list.component.html -->
  849. * <button (click)="toggle()">Show / Hide Items</button>
  850. * <hr />
  851. * <div [@listAnimation]="items.length">
  852. * <div *ngFor="let item of items">
  853. * {{ item }}
  854. * </div>
  855. * </div>
  856. * ```
  857. *
  858. * Here is the component code:
  859. *
  860. * ```typescript
  861. * import {trigger, transition, style, animate, query, stagger} from '@angular/animations';
  862. * @Component({
  863. * templateUrl: 'list.component.html',
  864. * animations: [
  865. * trigger('listAnimation', [
  866. * ...
  867. * ])
  868. * ]
  869. * })
  870. * class ListComponent {
  871. * items = [];
  872. *
  873. * showItems() {
  874. * this.items = [0,1,2,3,4];
  875. * }
  876. *
  877. * hideItems() {
  878. * this.items = [];
  879. * }
  880. *
  881. * toggle() {
  882. * this.items.length ? this.hideItems() : this.showItems();
  883. * }
  884. * }
  885. * ```
  886. *
  887. * Here is the animation trigger code:
  888. *
  889. * ```typescript
  890. * trigger('listAnimation', [
  891. * transition('* => *', [ // each time the binding value changes
  892. * query(':leave', [
  893. * stagger(100, [
  894. * animate('0.5s', style({ opacity: 0 }))
  895. * ])
  896. * ]),
  897. * query(':enter', [
  898. * style({ opacity: 0 }),
  899. * stagger(100, [
  900. * animate('0.5s', style({ opacity: 1 }))
  901. * ])
  902. * ])
  903. * ])
  904. * ])
  905. * ```
  906. *
  907. * @publicApi
  908. */
  909. function stagger(timings, animation) {
  910. return { type: 12 /* AnimationMetadataType.Stagger */, timings, animation };
  911. }
  912. function scheduleMicroTask(cb) {
  913. Promise.resolve().then(cb);
  914. }
  915. /**
  916. * An empty programmatic controller for reusable animations.
  917. * Used internally when animations are disabled, to avoid
  918. * checking for the null case when an animation player is expected.
  919. *
  920. * @see `animate()`
  921. * @see `AnimationPlayer`
  922. * @see `GroupPlayer`
  923. *
  924. * @publicApi
  925. */
  926. class NoopAnimationPlayer {
  927. constructor(duration = 0, delay = 0) {
  928. this._onDoneFns = [];
  929. this._onStartFns = [];
  930. this._onDestroyFns = [];
  931. this._originalOnDoneFns = [];
  932. this._originalOnStartFns = [];
  933. this._started = false;
  934. this._destroyed = false;
  935. this._finished = false;
  936. this._position = 0;
  937. this.parentPlayer = null;
  938. this.totalTime = duration + delay;
  939. }
  940. _onFinish() {
  941. if (!this._finished) {
  942. this._finished = true;
  943. this._onDoneFns.forEach(fn => fn());
  944. this._onDoneFns = [];
  945. }
  946. }
  947. onStart(fn) {
  948. this._originalOnStartFns.push(fn);
  949. this._onStartFns.push(fn);
  950. }
  951. onDone(fn) {
  952. this._originalOnDoneFns.push(fn);
  953. this._onDoneFns.push(fn);
  954. }
  955. onDestroy(fn) {
  956. this._onDestroyFns.push(fn);
  957. }
  958. hasStarted() {
  959. return this._started;
  960. }
  961. init() { }
  962. play() {
  963. if (!this.hasStarted()) {
  964. this._onStart();
  965. this.triggerMicrotask();
  966. }
  967. this._started = true;
  968. }
  969. /** @internal */
  970. triggerMicrotask() {
  971. scheduleMicroTask(() => this._onFinish());
  972. }
  973. _onStart() {
  974. this._onStartFns.forEach(fn => fn());
  975. this._onStartFns = [];
  976. }
  977. pause() { }
  978. restart() { }
  979. finish() {
  980. this._onFinish();
  981. }
  982. destroy() {
  983. if (!this._destroyed) {
  984. this._destroyed = true;
  985. if (!this.hasStarted()) {
  986. this._onStart();
  987. }
  988. this.finish();
  989. this._onDestroyFns.forEach(fn => fn());
  990. this._onDestroyFns = [];
  991. }
  992. }
  993. reset() {
  994. this._started = false;
  995. this._finished = false;
  996. this._onStartFns = this._originalOnStartFns;
  997. this._onDoneFns = this._originalOnDoneFns;
  998. }
  999. setPosition(position) {
  1000. this._position = this.totalTime ? position * this.totalTime : 1;
  1001. }
  1002. getPosition() {
  1003. return this.totalTime ? this._position / this.totalTime : 1;
  1004. }
  1005. /** @internal */
  1006. triggerCallback(phaseName) {
  1007. const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
  1008. methods.forEach(fn => fn());
  1009. methods.length = 0;
  1010. }
  1011. }
  1012. /**
  1013. * A programmatic controller for a group of reusable animations.
  1014. * Used internally to control animations.
  1015. *
  1016. * @see `AnimationPlayer`
  1017. * @see `{@link animations/group group()}`
  1018. *
  1019. */
  1020. class AnimationGroupPlayer {
  1021. constructor(_players) {
  1022. this._onDoneFns = [];
  1023. this._onStartFns = [];
  1024. this._finished = false;
  1025. this._started = false;
  1026. this._destroyed = false;
  1027. this._onDestroyFns = [];
  1028. this.parentPlayer = null;
  1029. this.totalTime = 0;
  1030. this.players = _players;
  1031. let doneCount = 0;
  1032. let destroyCount = 0;
  1033. let startCount = 0;
  1034. const total = this.players.length;
  1035. if (total == 0) {
  1036. scheduleMicroTask(() => this._onFinish());
  1037. }
  1038. else {
  1039. this.players.forEach(player => {
  1040. player.onDone(() => {
  1041. if (++doneCount == total) {
  1042. this._onFinish();
  1043. }
  1044. });
  1045. player.onDestroy(() => {
  1046. if (++destroyCount == total) {
  1047. this._onDestroy();
  1048. }
  1049. });
  1050. player.onStart(() => {
  1051. if (++startCount == total) {
  1052. this._onStart();
  1053. }
  1054. });
  1055. });
  1056. }
  1057. this.totalTime = this.players.reduce((time, player) => Math.max(time, player.totalTime), 0);
  1058. }
  1059. _onFinish() {
  1060. if (!this._finished) {
  1061. this._finished = true;
  1062. this._onDoneFns.forEach(fn => fn());
  1063. this._onDoneFns = [];
  1064. }
  1065. }
  1066. init() {
  1067. this.players.forEach(player => player.init());
  1068. }
  1069. onStart(fn) {
  1070. this._onStartFns.push(fn);
  1071. }
  1072. _onStart() {
  1073. if (!this.hasStarted()) {
  1074. this._started = true;
  1075. this._onStartFns.forEach(fn => fn());
  1076. this._onStartFns = [];
  1077. }
  1078. }
  1079. onDone(fn) {
  1080. this._onDoneFns.push(fn);
  1081. }
  1082. onDestroy(fn) {
  1083. this._onDestroyFns.push(fn);
  1084. }
  1085. hasStarted() {
  1086. return this._started;
  1087. }
  1088. play() {
  1089. if (!this.parentPlayer) {
  1090. this.init();
  1091. }
  1092. this._onStart();
  1093. this.players.forEach(player => player.play());
  1094. }
  1095. pause() {
  1096. this.players.forEach(player => player.pause());
  1097. }
  1098. restart() {
  1099. this.players.forEach(player => player.restart());
  1100. }
  1101. finish() {
  1102. this._onFinish();
  1103. this.players.forEach(player => player.finish());
  1104. }
  1105. destroy() {
  1106. this._onDestroy();
  1107. }
  1108. _onDestroy() {
  1109. if (!this._destroyed) {
  1110. this._destroyed = true;
  1111. this._onFinish();
  1112. this.players.forEach(player => player.destroy());
  1113. this._onDestroyFns.forEach(fn => fn());
  1114. this._onDestroyFns = [];
  1115. }
  1116. }
  1117. reset() {
  1118. this.players.forEach(player => player.reset());
  1119. this._destroyed = false;
  1120. this._finished = false;
  1121. this._started = false;
  1122. }
  1123. setPosition(p) {
  1124. const timeAtPosition = p * this.totalTime;
  1125. this.players.forEach(player => {
  1126. const position = player.totalTime ? Math.min(1, timeAtPosition / player.totalTime) : 1;
  1127. player.setPosition(position);
  1128. });
  1129. }
  1130. getPosition() {
  1131. const longestPlayer = this.players.reduce((longestSoFar, player) => {
  1132. const newPlayerIsLongest = longestSoFar === null || player.totalTime > longestSoFar.totalTime;
  1133. return newPlayerIsLongest ? player : longestSoFar;
  1134. }, null);
  1135. return longestPlayer != null ? longestPlayer.getPosition() : 0;
  1136. }
  1137. beforeDestroy() {
  1138. this.players.forEach(player => {
  1139. if (player.beforeDestroy) {
  1140. player.beforeDestroy();
  1141. }
  1142. });
  1143. }
  1144. /** @internal */
  1145. triggerCallback(phaseName) {
  1146. const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
  1147. methods.forEach(fn => fn());
  1148. methods.length = 0;
  1149. }
  1150. }
  1151. const ɵPRE_STYLE = '!';
  1152. /**
  1153. * @module
  1154. * @description
  1155. * Entry point for all animation APIs of the animation package.
  1156. */
  1157. /**
  1158. * @module
  1159. * @description
  1160. * Entry point for all public APIs of this package.
  1161. */
  1162. // This file is not used to build this module. It is only used during editing
  1163. /**
  1164. * Generated bundle index. Do not edit.
  1165. */
  1166. export { AUTO_STYLE, AnimationBuilder, AnimationFactory, NoopAnimationPlayer, animate, animateChild, animation, group, keyframes, query, sequence, stagger, state, style, transition, trigger, useAnimation, AnimationGroupPlayer as ɵAnimationGroupPlayer, ɵPRE_STYLE };
  1167. //# sourceMappingURL=animations.mjs.map