img(src="/resources/images/devguide/animations/ng_animate_transitions_inactive_active.png" alt="In Angular animations we defines states and transitions between states" width="400")
:marked
If we have the same timing configuration for several transitions, we can combine
The `*` ("wildcard") state matches *any* animation state. This is useful for defining styles and
transitions that should apply regardless of which state the animation is in. For example:
* The `active => *` transition applies when the element's state changes from `active` to anything else.
* The `* => *` transition applies when *any* change between two states takes place.
figure.image-display
img(src="/resources/images/devguide/animations/ng_animate_transitions_inactive_active_wildcards.png" alt="The wildcard state can be used to match many different transitions at once" width="400")
:marked
### The `void` state
There's one special state called `void` that may apply to any animation. It applies
when the element is *not* attached to a view. This may be because it has not yet been
added or because it has been removed. The `void` state is useful for defining "enter" and
"leave" animations.
For example the `* => void` transition applies when the element leaves the view,
regardless of what state it was in before it left.
figure.image-display
img(src="/resources/images/devguide/animations/ng_animate_transitions_void_in.png" alt="The void state can be used for enter and leave transitions" width="400")
:marked
The wildcard state `*` also matches `void`.
## Example: Entering and Leaving
figure
img(src="/resources/images/devguide/animations/animation_enter_leave.gif" alt="Enter and leave animations" align="right" style="width:250px;" )
:marked
Using the `void` and `*` states we can define transitions that animate the
Note that in this case we have the styles applied to the void state directly in the
transition definitions, and not in a separate `state(void)` definition. We do this because
we want the transforms to be different on enter and leave: The element enters from the left
and leaves to the right.
## Example: Entering and Leaving from Different States
figure
img(src="/resources/images/devguide/animations/animation_enter_leave_states.gif" alt="Enter and leave animations combined with state animations" align="right" style="width:200px" )
:marked
We can also combine this animation with the earlier state transition animation by
using the hero state as the animation state. What this will let us do is configure
different transitions for entering and leaving based on what the state of the hero
is:
* Inactive hero enter: `void => inactive`
* Active hero enter: `void => active`
* Inactive hero leave: `active => void`
* Active hero leave: `inactive => void`
We now have fine-grained control over each transition:
figure.image-display
img(src="/resources/images/devguide/animations/ng_animate_transitions_inactive_active_void.png" alt="This example transitions between active, inactive, and void states" width="400")
There are three timing properties we can tune for every animated transition:
The duration, the delay, and the easing function. They are all combined into
a single transition *timing string*.
### Duration
The duration controls how long the animation takes to run from start to finish.
We can define a duration in three ways:
* As a plain number, in milliseconds: `100`
* In a string, as milliseconds: `'100ms'`
* In a string, as seconds: `'0.1s'`
### Delay
The delay controls how long to wait after an animation triggers before the
transition actually begins. We can define one by adding it in the same string
following the duration. It also has the same format options as the duration:
* Wait for 100ms and then run for 200ms: `'0.2s 100ms'`
### Easing
The [easing function](http://easings.net/) controls how the animation accelerates
and decelerates during its runtime. For example, using an `ease-in` function means
the animation begins relatively slowly but then picks up speed as it progresses. We
can control the easing by adding it as a *third* value in the string after the duration
and the delay (or as the *second* value when there is no delay):
* Wait for 100ms and then run for 200ms, with easing: `'0.2s 100ms ease-out'`
* Run for 200ms, with easing: `'0.2s ease-in-out'`
figure
img(src="/resources/images/devguide/animations/animation_timings.gif" alt="Animations with specific timings" align="right" style="width:220px;margin-left:20px" )
:marked
### Example
Here are a couple of custom timings in action. Both "enter" and "leave" last for
200 milliseconds but they have different easings. The leave begins after a
img(src="/resources/images/devguide/animations/animation_multistep.gif" alt="Animations with some bounce implemented with keyframes" align="right" style="width:220px;margin-left:20px" )
:marked
With animation *keyframes* we can go beyond a simple transition between two
sets of styles to a more intricate animation that goes through one or more
intermediate styles in between.
For each keyframe, we can specify an *offset* that defines at which point
in the animation that keyframe applies. The offset is a number between zero,
which marks the beginning of the animation, and one, which marks the end.
In this example we add some "bounce" to our enter and leave animations with
Note that the offsets are *not* defined in terms of absolute time. They are relative
measures from 0 to 1. The final timeline of the animation will based on the combination
of keyframe offsets, duration, delay, and easing.
Defining offsets for keyframes is optional. If we omit them, offsets with even
spacing are automatically assigned. For example, three keyframes without predefined
offsets will receive offsets `0`, `0.5`, and `1`.
:marked
## Parallel Animation Groups
figure
img(src="/resources/images/devguide/animations/animation_groups.gif" alt="Parallel animations with different timings, implemented with groups" align="right" style="width:220px;margin-left:20px" )
:marked
We've already seen how we can animate multiple style properties at the same time:
Just put all of them into the same `style()` definition!
But we may also want to configure different *timings* for animations that happen
in parallel. For example, we may want to animate two CSS properties but use a
different easing function for each one.
For this we can use animation *groups*. In this example we use groups both on
enter and leave so that we can use two different timing configurations. Both
are applied to the same element in parallel, but run independent of each other: