angular-cn/aio/dist/generated/docs/guide/transition-and-triggers.json

5 lines
42 KiB
JSON

{
"id": "guide/transition-and-triggers",
"title": "Animations transitions and triggers",
"contents": "\n\n\n<div class=\"github-links\">\n <a href=\"https://github.com/angular/angular/edit/master/aio/content/guide/transition-and-triggers.md?message=docs%3A%20describe%20your%20change...\" aria-label=\"Suggest Edits\" title=\"Suggest Edits\"><i class=\"material-icons\" aria-hidden=\"true\" role=\"img\">mode_edit</i></a>\n</div>\n\n\n<div class=\"content\">\n <h1 id=\"animations-transitions-and-triggers\">Animations transitions and triggers<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#animations-transitions-and-triggers\"><i class=\"material-icons\">link</i></a></h1>\n<p>You learned the basics of Angular animations in the <a href=\"guide/animations\">introduction</a> page.</p>\n<p>This guide goes into greater depth on special transition states such as <code>*</code> (wildcard) and <code>void</code>, and show how these special states are used for elements entering and leaving a view.\nThis chapter also explores multiple animation triggers, animation callbacks, and sequence-based animation using keyframes.</p>\n<h2 id=\"predefined-states-and-wildcard-matching\">Predefined states and wildcard matching<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#predefined-states-and-wildcard-matching\"><i class=\"material-icons\">link</i></a></h2>\n<p>In Angular, transition states can be defined explicitly through the <code><a href=\"api/animations/state\" class=\"code-anchor\">state</a>()</code> function, or using the predefined <code>*</code> (wildcard) and <code>void</code> states.</p>\n<h3 id=\"wildcard-state\">Wildcard state<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#wildcard-state\"><i class=\"material-icons\">link</i></a></h3>\n<p>An asterisk <code>*</code> or <em>wildcard</em> matches any animation state. This is useful for defining transitions that apply regardless of the HTML element's start or end state.</p>\n<p>For example, a transition of <code>open => *</code> applies when the element's state changes from open to anything else.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/animations/wildcard-state-500.png\" alt=\"wildcard state expressions\" width=\"500\" height=\"229\">\n</div>\n<p>The following is another code sample using the wildcard state together with the previous example using the <code>open</code> and <code>closed</code> states.\nInstead of defining each state-to-state transition pair, any transition to <code>closed</code> takes 1 second, and any transition to <code>open</code> takes 0.5 seconds.</p>\n<p>This allows us to add new states without having to include separate transitions for each one.</p>\n<code-example header=\"src/app/open-close.component.ts\" path=\"animations/src/app/open-close.component.ts\" region=\"trigger-wildcard1\" language=\"typescript\">\nanimations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('openClose', [\n // ...\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('open', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '200px',\n opacity: 1,\n backgroundColor: 'yellow'\n })),\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('closed', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '100px',\n opacity: 0.5,\n backgroundColor: 'green'\n })),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => closed', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('1s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => open', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('0.5s')\n ]),\n ]),\n],\n\n</code-example>\n<p>Use a double arrow syntax to specify state-to-state transitions in both directions.</p>\n<code-example header=\"src/app/open-close.component.ts\" path=\"animations/src/app/open-close.component.ts\" region=\"trigger-wildcard2\" language=\"typescript\">\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('open &#x3C;=> closed', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('0.5s')\n]),\n\n</code-example>\n<h3 id=\"using-wildcard-state-with-multiple-transition-states\">Using wildcard state with multiple transition states<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#using-wildcard-state-with-multiple-transition-states\"><i class=\"material-icons\">link</i></a></h3>\n<p>In the two-state button example, the wildcard isn't that useful because there are only two possible states, <code>open</code> and <code>closed</code>.\nWildcard states are better when an element in one particular state has multiple potential states that it can change to.\nIf the button can change from <code>open</code> to either <code>closed</code> or something like <code>inProgress</code>, using a wildcard state could reduce the amount of coding needed.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/animations/wildcard-3-states.png\" alt=\"wildcard state with 3 states\" width=\"600\" height=\"426\">\n</div>\n<code-example path=\"animations/src/app/open-close.component.ts\" header=\"src/app/open-close.component.ts\" region=\"trigger-transition\" language=\"typescript\">\nanimations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('openClose', [\n // ...\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('open', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '200px',\n opacity: 1,\n backgroundColor: 'yellow'\n })),\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('closed', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '100px',\n opacity: 0.5,\n backgroundColor: 'green'\n })),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('open => closed', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('1s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('closed => open', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('0.5s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => closed', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('1s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => open', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('0.5s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('open &#x3C;=> closed', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('0.5s')\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a> ('* => open', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a> ('1s',\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a> ({ opacity: '*' }),\n ),\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => *', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('1s')\n ]),\n\n</code-example>\n<p>The <code>* => *</code> transition applies when any change between two states takes place.</p>\n<p>Transitions are matched in the order in which they are defined. Thus, you can apply other transitions on top of the <code>* => *</code> (any-to-any) transition. For example, define style changes or animations that would apply just to <code>open => closed</code>, or just to <code>closed => open</code>, and then use <code>* => *</code> as a fallback for state pairings that aren't otherwise called out.</p>\n<p>To do this, list the more specific transitions <em>before</em> <code>* => *</code>.</p>\n<h3 id=\"using-wildcards-with-styles\">Using wildcards with styles<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#using-wildcards-with-styles\"><i class=\"material-icons\">link</i></a></h3>\n<p>Use the wildcard <code>*</code> with a style to tell the animation to use whatever the current style value is, and animate with that. Wildcard is a fallback value that's used if the state being animated isn't declared within the trigger.</p>\n<code-example path=\"animations/src/app/open-close.component.ts\" header=\"src/app/open-close.component.ts\" region=\"transition4\" language=\"typescript\">\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a> ('* => open', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a> ('1s',\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a> ({ opacity: '*' }),\n ),\n]),\n\n</code-example>\n<h3 id=\"void-state\">Void state<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#void-state\"><i class=\"material-icons\">link</i></a></h3>\n<p>You can use the <code>void</code> state to configure transitions for an element that is entering or leaving a page. See <a href=\"guide/transition-and-triggers#enter-leave-view\">Animating entering and leaving a view</a>.</p>\n<h3 id=\"combining-wildcard-and-void-states\">Combining wildcard and void states<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#combining-wildcard-and-void-states\"><i class=\"material-icons\">link</i></a></h3>\n<p>You can combine wildcard and void states in a transition to trigger animations that enter and leave the page:</p>\n<ul>\n<li>\n<p>A transition of <code>* => void</code> applies when the element leaves a view, regardless of what state it was in before it left.</p>\n</li>\n<li>\n<p>A transition of <code>void => *</code> applies when the element enters a view, regardless of what state it assumes when entering.</p>\n</li>\n<li>\n<p>The wildcard state <code>*</code> matches to <em>any</em> state, including <code>void</code>.</p>\n</li>\n</ul>\n<h2 id=\"animating-entering-and-leaving-a-view\">Animating entering and leaving a view<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#animating-entering-and-leaving-a-view\"><i class=\"material-icons\">link</i></a></h2>\n<p>This section shows how to animate elements entering or leaving a page.</p>\n<div class=\"alert is-helpful\">\n<p><strong>Note:</strong> For this example, an element entering or leaving a view is equivalent to being inserted or removed from the DOM.</p>\n</div>\n<p>Now add a new behavior:</p>\n<ul>\n<li>When you add a hero to the list of heroes, it appears to fly onto the page from the left.</li>\n<li>When you remove a hero from the list, it appears to fly out to the right.</li>\n</ul>\n<code-example path=\"animations/src/app/hero-list-enter-leave.component.ts\" header=\"src/app/hero-list-enter-leave.component.ts\" region=\"animationdef\" language=\"typescript\">\nanimations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('flyInOut', [\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('in', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ transform: 'translateX(0)' })),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('void => *', [\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ transform: 'translateX(-100%)' }),\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>(100)\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => void', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>(100, <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ transform: 'translateX(100%)' }))\n ])\n ])\n]\n\n</code-example>\n<p>In the above code, you applied the <code>void</code> state when the HTML element isn't attached to a view.</p>\n<a id=\"enter-leave-view\"></a>\n<h2 id=\"enter-and-leave-aliases\">:enter and :leave aliases<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#enter-and-leave-aliases\"><i class=\"material-icons\">link</i></a></h2>\n<p><code>:enter</code> and <code>:leave</code> are aliases for the <code>void => *</code> and <code>* => void</code> transitions. These aliases are used by several animation functions.</p>\n<code-example hidecopy=\"\" language=\"typescript\">\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a> ( ':enter', [ ... ] ); // alias for void => *\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a> ( ':leave', [ ... ] ); // alias for * => void\n</code-example>\n<p>It's harder to target an element that is entering a view because it isn't in the DOM yet.\nSo, use the aliases <code>:enter</code> and <code>:leave</code> to target HTML elements that are inserted or removed from a view.</p>\n<h3 id=\"use-of-ngif-and-ngfor-with-enter-and-leave\">Use of *ngIf and *ngFor with :enter and :leave<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#use-of-ngif-and-ngfor-with-enter-and-leave\"><i class=\"material-icons\">link</i></a></h3>\n<p>The <code>:enter</code> transition runs when any <code>*<a href=\"api/common/NgIf\" class=\"code-anchor\">ngIf</a></code> or <code>*<a href=\"api/common/NgForOf\" class=\"code-anchor\">ngFor</a></code> views are placed on the page, and <code>:leave</code> runs when those views are removed from the page.</p>\n<p>This example has a special trigger for the enter and leave animation called <code>myInsertRemoveTrigger</code>. The HTML template contains the following code.</p>\n<code-example path=\"animations/src/app/insert-remove.component.html\" header=\"src/app/insert-remove.component.html\" region=\"insert-remove\" language=\"typescript\">\n&#x3C;div @myInsertRemoveTrigger *<a href=\"api/common/NgIf\" class=\"code-anchor\">ngIf</a>=\"isShown\" class=\"insert-remove-container\">\n &#x3C;p>The box is inserted&#x3C;/p>\n&#x3C;/div>\n\n</code-example>\n<p>In the component file, the <code>:enter</code> transition sets an initial opacity of 0, and then animates it to change that opacity to 1 as the element is inserted into the view.</p>\n<code-example path=\"animations/src/app/insert-remove.component.ts\" header=\"src/app/insert-remove.component.ts\" region=\"enter-leave-trigger\" language=\"typescript\">\n<a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('myInsertRemoveTrigger', [\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>(':enter', [\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0 }),\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('100ms', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 1 })),\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>(':leave', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('100ms', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0 }))\n ])\n]),\n\n</code-example>\n<p>Note that this example doesn't need to use <code><a href=\"api/animations/state\" class=\"code-anchor\">state</a>()</code>.</p>\n<h2 id=\"increment-and-decrement-in-transitions\">:increment and :decrement in transitions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#increment-and-decrement-in-transitions\"><i class=\"material-icons\">link</i></a></h2>\n<p>The <code><a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>()</code> function takes additional selector values, <code>:increment</code> and <code>:decrement</code>. Use these to kick off a transition when a numeric value has increased or decreased in value.</p>\n<div class=\"alert is-helpful\">\n<p><strong>Note:</strong> The following example uses <code><a href=\"api/animations/query\" class=\"code-anchor\">query</a>()</code> and <code><a href=\"api/animations/stagger\" class=\"code-anchor\">stagger</a>()</code> methods, which is discussed in the <a href=\"guide/complex-animation-sequences#complex-sequence\">complex sequences</a> page.</p>\n</div>\n<code-example path=\"animations/src/app/hero-list-page.component.ts\" header=\"src/app/hero-list-page.component.ts\" region=\"increment\" language=\"typescript\">\n<a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('filterAnimation', [\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>(':enter, * => 0, * => -1', []),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>(':increment', [\n <a href=\"api/animations/query\" class=\"code-anchor\">query</a>(':enter', [\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0, width: '0px' }),\n <a href=\"api/animations/stagger\" class=\"code-anchor\">stagger</a>(50, [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('300ms ease-out', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 1, width: '*' })),\n ]),\n ], { optional: true })\n ]),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>(':decrement', [\n <a href=\"api/animations/query\" class=\"code-anchor\">query</a>(':leave', [\n <a href=\"api/animations/stagger\" class=\"code-anchor\">stagger</a>(50, [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('300ms ease-out', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0, width: '0px' })),\n ]),\n ])\n ]),\n]),\n\n</code-example>\n<h2 id=\"boolean-values-in-transitions\">Boolean values in transitions<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#boolean-values-in-transitions\"><i class=\"material-icons\">link</i></a></h2>\n<p>If a trigger contains a boolean value as a binding value, then this value can be matched using a <code><a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>()</code> expression that compares <code>true</code> and <code>false</code>, or <code>1</code> and <code>0</code>.</p>\n<code-example path=\"animations/src/app/open-close.component.2.html\" header=\"src/app/open-close.component.html\" region=\"trigger-boolean\">\n&#x3C;div [@openClose]=\"isOpen ? true : false\" class=\"open-close-container\">\n&#x3C;/div>\n\n</code-example>\n<p>In the code snippet above, the HTML template binds a <code>&#x3C;div></code> element to a trigger named <code>openClose</code> with a status expression of <code>isOpen</code>, and with possible values of <code>true</code> and <code>false</code>. This is an alternative to the practice of creating two named states of <code>open</code> and <code>close</code>.</p>\n<p>In the component code, in the <code>@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a></code> metadata under the <code>animations:</code> property, when the state evaluates to <code>true</code> (meaning \"open\" here), the associated HTML element's height is a wildcard style or default. In this case, use whatever height the element already had before the animation started. When the element is \"closed,\" the element animates to a height of 0, which makes it invisible.</p>\n<code-example path=\"animations/src/app/open-close.component.2.ts\" header=\"src/app/open-close.component.ts\" region=\"trigger-boolean\" language=\"typescript\">\nanimations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('openClose', [\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('true', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ height: '*' })),\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('false', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ height: '0px' })),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('false &#x3C;=> true', <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>(500))\n ])\n],\n\n</code-example>\n<h2 id=\"multiple-animation-triggers\">Multiple animation triggers<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#multiple-animation-triggers\"><i class=\"material-icons\">link</i></a></h2>\n<p>You can define more than one animation trigger for a component. You can attach animation triggers to different elements, and the parent-child relationships among the elements affect how and when the animations run.</p>\n<h3 id=\"parent-child-animations\">Parent-child animations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#parent-child-animations\"><i class=\"material-icons\">link</i></a></h3>\n<p>Each time an animation is triggered in Angular, the parent animation always get priority and child animations are blocked. In order for a child animation to run, the parent animation must query each of the elements containing child animations and then allow the animations to run using the <a href=\"api/animations/animateChild\"><code>animateChild()</code></a> function.</p>\n<h4 id=\"disabling-an-animation-on-an-html-element\">Disabling an animation on an HTML element<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#disabling-an-animation-on-an-html-element\"><i class=\"material-icons\">link</i></a></h4>\n<p>A special animation control binding called <code>@.disabled</code> can be placed on an HTML element to disable animations on that element, as well as any nested elements. When true, the <code>@.disabled</code> binding prevents all animations from rendering.</p>\n<p>The code sample below shows how to use this feature.</p>\n<code-tabs>\n\n<code-pane path=\"animations/src/app/open-close.component.4.html\" header=\"src/app/open-close.component.html\" region=\"toggle-animation\">\n&#x3C;div [@.disabled]=\"isDisabled\">\n &#x3C;div [@childAnimation]=\"isOpen ? 'open' : 'closed'\"\n class=\"open-close-container\">\n &#x3C;p>The box is now {{ isOpen ? 'Open' : 'Closed' }}!&#x3C;/p>\n &#x3C;/div>\n&#x3C;/div>\n\n</code-pane>\n\n<code-pane path=\"animations/src/app/open-close.component.4.ts\" header=\"src/app/open-close.component.ts\" region=\"toggle-animation\" language=\"typescript\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n animations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('childAnimation', [\n // ...\n ]),\n ],\n})\nexport class OpenCloseChildComponent {\n isDisabled = false;\n isOpen = false;\n}\n\n</code-pane>\n\n</code-tabs>\n<p>When the <code>@.disabled</code> binding is true, the <code>@childAnimation</code> trigger doesn't kick off.</p>\n<p>When an element within an HTML template has animations disabled using the <code>@.disabled</code> host binding, animations are disabled on all inner elements as well.\nYou can't selectively disable multiple animations on a single element.</p>\n<p>However, selective child animations can still be run on a disabled parent in one of the following ways:</p>\n<ul>\n<li>\n<p>A parent animation can use the <a href=\"api/animations/query\"><code>query()</code></a> function to collect inner elements located in disabled areas of the HTML template.\nThose elements can still animate.</p>\n</li>\n<li>\n<p>A subanimation can be queried by a parent and then later animated with the <code><a href=\"api/animations/animateChild\" class=\"code-anchor\">animateChild</a>()</code> function.</p>\n</li>\n</ul>\n<h4 id=\"disabling-all-animations\">Disabling all animations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#disabling-all-animations\"><i class=\"material-icons\">link</i></a></h4>\n<p>To disable all animations for an Angular app, place the <code>@.disabled</code> host binding on the topmost Angular component.</p>\n<code-example path=\"animations/src/app/app.component.ts\" header=\"src/app/app.component.ts\" region=\"toggle-app-animations\" language=\"typescript\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-root',\n templateUrl: 'app.component.html',\n styleUrls: ['app.component.css'],\n animations: [\n slideInAnimation\n // <a href=\"api/animations/animation\" class=\"code-anchor\">animation</a> triggers go here\n ]\n})\nexport class AppComponent {\n @<a href=\"api/core/HostBinding\" class=\"code-anchor\">HostBinding</a>('@.disabled')\n public animationsDisabled = false;\n}\n\n</code-example>\n<div class=\"alert is-helpful\">\n<p><strong>Note:</strong> Disabling animations application-wide is useful during end-to-end (E2E) testing.</p>\n</div>\n<h2 id=\"animation-callbacks\">Animation callbacks<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#animation-callbacks\"><i class=\"material-icons\">link</i></a></h2>\n<p>The animation <code><a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>()</code> function emits <em>callbacks</em> when it starts and when it finishes. The example below features a component that contains an <code>openClose</code> trigger.</p>\n<code-example path=\"animations/src/app/open-close.component.ts\" header=\"src/app/open-close.component.ts\" region=\"events1\" language=\"typescript\">\n@<a href=\"api/core/Component\" class=\"code-anchor\">Component</a>({\n selector: 'app-open-close',\n animations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('openClose', [\n // ...\n ]),\n ],\n templateUrl: 'open-close.component.html',\n styleUrls: ['open-close.component.css']\n})\nexport class OpenCloseComponent {\n onAnimationEvent( event: <a href=\"api/animations/AnimationEvent\" class=\"code-anchor\">AnimationEvent</a> ) {\n }\n}\n\n\n</code-example>\n<p>In the HTML template, the animation event is passed back via <code>$event</code>, as <code>@trigger.start</code> and <code>@trigger.done</code>, where <code><a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a></code> is the name of the trigger being used.\nIn this example, the trigger <code>openClose</code> appears as follows.</p>\n<code-example path=\"animations/src/app/open-close.component.3.html\" header=\"src/app/open-close.component.html\" region=\"callbacks\">\n &#x3C;div [@openClose]=\"isOpen ? 'open' : 'closed'\"\n (@openClose.start)=\"onAnimationEvent($event)\"\n (@openClose.done)=\"onAnimationEvent($event)\"\n class=\"open-close-container\">\n&#x3C;/div>\n\n</code-example>\n<p>A potential use for animation callbacks could be to cover for a slow API call, such as a database lookup.\nFor example, you could set up the <strong>InProgress</strong> button to have its own looping animation where it pulsates or does some other visual motion while the backend system operation finishes.</p>\n<p>Then, another animation can be called when the current animation finishes.\nFor example, the button goes from the <code>inProgress</code> state to the <code>closed</code> state when the API call is completed.</p>\n<p>An animation can influence an end user to <em>perceive</em> the operation as faster, even when it isn't.\nThus, a simple animation can be a cost-effective way to keep users happy, rather than seeking to improve the speed of a server call and having to compensate for circumstances beyond your control, such as an unreliable network connection.</p>\n<p>Callbacks can serve as a debugging tool, for example in conjunction with <code>console.warn()</code> to view the application's progress in a browser's Developer JavaScript Console.\nThe following code snippet creates console log output for the original example, a button with the two states of <code>open</code> and <code>closed</code>.</p>\n<code-example path=\"animations/src/app/open-close.component.ts\" header=\"src/app/open-close.component.ts\" region=\"events\" language=\"typescript\">\nexport class OpenCloseComponent {\n onAnimationEvent( event: <a href=\"api/animations/AnimationEvent\" class=\"code-anchor\">AnimationEvent</a> ) {\n // openClose is <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a> name in this example\n console.warn(`Animation Trigger: ${event.triggerName}`);\n\n // phaseName is start or done\n console.warn(`Phase: ${event.phaseName}`);\n\n // in our example, totalTime is 1000 or 1 second\n console.warn(`Total time: ${event.totalTime}`);\n\n // in our example, fromState is either open or closed\n console.warn(`From: ${event.fromState}`);\n\n // in our example, toState either open or closed\n console.warn(`To: ${event.toState}`);\n\n // the HTML element itself, the button in this case\n console.warn(`Element: ${event.element}`);\n }\n}\n\n\n</code-example>\n<a id=\"keyframes\"></a>\n<h2 id=\"keyframes\">Keyframes<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#keyframes\"><i class=\"material-icons\">link</i></a></h2>\n<p>The previous section features a simple two-state transition. Now create an animation with multiple steps run in sequence using <em>keyframes</em>.</p>\n<p>Angular's <code>keyframe()</code> function is similar to keyframes in CSS. Keyframes allow several style changes within a single timing segment.\nFor example, the button, instead of fading, could change color several times over a single 2-second timespan.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/animations/keyframes-500.png\" alt=\"keyframes\" width=\"500\" height=\"244\">\n</div>\n<p>The code for this color change might look like this.</p>\n<code-example path=\"animations/src/app/status-slider.component.ts\" header=\"src/app/status-slider.component.ts\" region=\"keyframes\" language=\"typescript\">\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => active', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('2s', <a href=\"api/animations/keyframes\" class=\"code-anchor\">keyframes</a>([\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'blue' }),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'red' }),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'orange' })\n ]))\n\n</code-example>\n<h3 id=\"offset\">Offset<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#offset\"><i class=\"material-icons\">link</i></a></h3>\n<p>Keyframes include an <em>offset</em> that defines the point in the animation where each style change occurs.\nOffsets are relative measures from zero to one, marking the beginning and end of the animation, respectively and should be applied to each of the keyframe's steps if used at least once.</p>\n<p>Defining offsets for keyframes is optional.\nIf you omit them, evenly spaced offsets are automatically assigned.\nFor example, three keyframes without predefined offsets receive offsets of 0, 0.5, and 1.\nSpecifying an offset of 0.8 for the middle transition in the above example might look like this.</p>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/animations/keyframes-offset-500.png\" alt=\"keyframes with offset\" width=\"500\" height=\"247\">\n</div>\n<p>The code with offsets specified would be as follows.</p>\n<code-example path=\"animations/src/app/status-slider.component.ts\" header=\"src/app/status-slider.component.ts\" region=\"keyframesWithOffsets\" language=\"typescript\">\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => active', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('2s', <a href=\"api/animations/keyframes\" class=\"code-anchor\">keyframes</a>([\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'blue', offset: 0}),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'red', offset: 0.8}),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'orange', offset: 1.0})\n ])),\n]),\n<a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => inactive', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('2s', <a href=\"api/animations/keyframes\" class=\"code-anchor\">keyframes</a>([\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'orange', offset: 0}),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'red', offset: 0.2}),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ backgroundColor: 'blue', offset: 1.0})\n ]))\n]),\n\n</code-example>\n<p>You can combine keyframes with <code>duration</code>, <code>delay</code>, and <code>easing</code> within a single animation.</p>\n<h3 id=\"keyframes-with-a-pulsation\">Keyframes with a pulsation<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#keyframes-with-a-pulsation\"><i class=\"material-icons\">link</i></a></h3>\n<p>Use keyframes to create a pulse effect in your animations by defining styles at specific offset throughout the animation.</p>\n<p>Here's an example of using keyframes to create a pulse effect:</p>\n<ul>\n<li>\n<p>The original <code>open</code> and <code>closed</code> states, with the original changes in height, color, and opacity, occurring over a timeframe of 1 second.</p>\n</li>\n<li>\n<p>A keyframes sequence inserted in the middle that causes the button to appear to pulsate irregularly over the course of that same 1-second timeframe.</p>\n</li>\n</ul>\n<div class=\"lightbox\">\n <img src=\"generated/images/guide/animations/keyframes-pulsation.png\" alt=\"keyframes with irregular pulsation\" width=\"600\" height=\"312\">\n</div>\n<p>The code snippet for this animation might look like this.</p>\n<code-example path=\"animations/src/app/open-close.component.1.ts\" header=\"src/app/open-close.component.ts\" region=\"trigger\" language=\"typescript\">\n<a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('openClose', [\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('open', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '200px',\n opacity: 1,\n backgroundColor: 'yellow'\n })),\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('close', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({\n height: '100px',\n opacity: 0.5,\n backgroundColor: 'green'\n })),\n // ...\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => *', [\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>('1s', <a href=\"api/animations/keyframes\" class=\"code-anchor\">keyframes</a> ( [\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0.1, offset: 0.1 }),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0.6, offset: 0.2 }),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 1, offset: 0.5 }),\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ opacity: 0.2, offset: 0.7 })\n ]))\n ])\n])\n\n</code-example>\n<h3 id=\"animatable-properties-and-units\">Animatable properties and units<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#animatable-properties-and-units\"><i class=\"material-icons\">link</i></a></h3>\n<p>Angular's animation support builds on top of web animations, so you can animate any property that the browser considers animatable.\nThis includes positions, sizes, transforms, colors, borders, and more. The W3C maintains a list of animatable properties on its <a href=\"https://www.w3.org/TR/css-transitions-1/\">CSS Transitions</a> page.</p>\n<p>For positional properties with a numeric value, define a unit by providing the value as a string, in quotes, with the appropriate suffix:</p>\n<ul>\n<li>50 pixels: <code>'50px'</code></li>\n<li>Relative font size: <code>'3em'</code></li>\n<li>Percentage: <code>'100%'</code></li>\n</ul>\n<p>If you don't provide a unit when specifying dimension, Angular assumes a default unit of pixels, or px.\nExpressing 50 pixels as <code>50</code> is the same as saying <code>'50px'</code>.</p>\n<h3 id=\"automatic-property-calculation-with-wildcards\">Automatic property calculation with wildcards<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#automatic-property-calculation-with-wildcards\"><i class=\"material-icons\">link</i></a></h3>\n<p>Sometimes you don't know the value of a dimensional style property until runtime.\nFor example, elements often have widths and heights that depend on their content and the screen size.\nThese properties are often challenging to animate using CSS.</p>\n<p>In these cases, you can use a special wildcard <code>*</code> property value under <code><a href=\"api/animations/style\" class=\"code-anchor\">style</a>()</code>, so that the value of that particular style property is computed at runtime and then plugged into the animation.</p>\n<p>The following example has a trigger called <code>shrinkOut</code>, used when an HTML element leaves the page.\nThe animation takes whatever height the element has before it leaves, and animates from that height to zero.</p>\n<code-example path=\"animations/src/app/hero-list-auto.component.ts\" header=\"src/app/hero-list-auto.component.ts\" region=\"auto-calc\" language=\"typescript\">\nanimations: [\n <a href=\"api/animations/trigger\" class=\"code-anchor\">trigger</a>('shrinkOut', [\n <a href=\"api/animations/state\" class=\"code-anchor\">state</a>('in', <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ height: '*' })),\n <a href=\"api/animations/transition\" class=\"code-anchor\">transition</a>('* => void', [\n <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ height: '*' }),\n <a href=\"api/animations/animate\" class=\"code-anchor\">animate</a>(250, <a href=\"api/animations/style\" class=\"code-anchor\">style</a>({ height: 0 }))\n ])\n ])\n]\n\n</code-example>\n<h3 id=\"keyframes-summary\">Keyframes summary<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#keyframes-summary\"><i class=\"material-icons\">link</i></a></h3>\n<p>The <code><a href=\"api/animations/keyframes\" class=\"code-anchor\">keyframes</a>()</code> function in Angular allows you to specify multiple interim styles within a single transition, with an optional offset to define the point in the animation where each style change occurs.</p>\n<h2 id=\"more-on-angular-animations\">More on Angular animations<a title=\"Link to this heading\" class=\"header-link\" aria-hidden=\"true\" href=\"guide/transition-and-triggers#more-on-angular-animations\"><i class=\"material-icons\">link</i></a></h2>\n<p>You may also be interested in the following:</p>\n<ul>\n<li><a href=\"guide/animations\">Introduction to Angular animations</a></li>\n<li><a href=\"guide/complex-animation-sequences\">Complex animation sequences</a></li>\n<li><a href=\"guide/reusable-animations\">Reusable animations</a></li>\n<li><a href=\"guide/route-animations\">Route transition animations</a></li>\n</ul>\n\n \n</div>\n\n<!-- links to this doc:\n - api/common/NgForOf\n - guide/animations\n - guide/complex-animation-sequences\n - guide/reusable-animations\n - guide/route-animations\n-->\n<!-- links from this doc:\n - api/animations/AnimationEvent\n - api/animations/animate\n - api/animations/animateChild\n - api/animations/animation\n - api/animations/keyframes\n - api/animations/query\n - api/animations/stagger\n - api/animations/state\n - api/animations/style\n - api/animations/transition\n - api/animations/trigger\n - api/common/NgForOf\n - api/common/NgIf\n - api/core/Component\n - api/core/HostBinding\n - guide/animations\n - guide/complex-animation-sequences\n - guide/complex-animation-sequences#complex-sequence\n - guide/reusable-animations\n - guide/route-animations\n - guide/transition-and-triggers#animatable-properties-and-units\n - guide/transition-and-triggers#animating-entering-and-leaving-a-view\n - guide/transition-and-triggers#animation-callbacks\n - guide/transition-and-triggers#animations-transitions-and-triggers\n - guide/transition-and-triggers#automatic-property-calculation-with-wildcards\n - guide/transition-and-triggers#boolean-values-in-transitions\n - guide/transition-and-triggers#combining-wildcard-and-void-states\n - guide/transition-and-triggers#disabling-all-animations\n - guide/transition-and-triggers#disabling-an-animation-on-an-html-element\n - guide/transition-and-triggers#enter-and-leave-aliases\n - guide/transition-and-triggers#enter-leave-view\n - guide/transition-and-triggers#increment-and-decrement-in-transitions\n - guide/transition-and-triggers#keyframes\n - guide/transition-and-triggers#keyframes-summary\n - guide/transition-and-triggers#keyframes-with-a-pulsation\n - guide/transition-and-triggers#more-on-angular-animations\n - guide/transition-and-triggers#multiple-animation-triggers\n - guide/transition-and-triggers#offset\n - guide/transition-and-triggers#parent-child-animations\n - guide/transition-and-triggers#predefined-states-and-wildcard-matching\n - guide/transition-and-triggers#use-of-ngif-and-ngfor-with-enter-and-leave\n - guide/transition-and-triggers#using-wildcard-state-with-multiple-transition-states\n - guide/transition-and-triggers#using-wildcards-with-styles\n - guide/transition-and-triggers#void-state\n - guide/transition-and-triggers#wildcard-state\n - https://github.com/angular/angular/edit/master/aio/content/guide/transition-and-triggers.md?message=docs%3A%20describe%20your%20change...\n - https://www.w3.org/TR/css-transitions-1/\n-->"
}