Introduction to Angular Animations
Explore the fundamentals of Angular animations by understanding how to use the @angular/animations package. Learn to create animation triggers, states, styles, transitions, and control timing for smooth visual effects within Angular components.
Angular animations are based on CSS web transition functionality, which means that anything that can be styled or transformed through CSS can be animated the same way using Angular animations, with the added advantage of giving the developer more control in orchestrating it. This provides us with animations that have CSS-like performance along with the flexibility of JavaScript out of the box without additional dependencies.
How to use
To use @angular/animations in our application, we’ll have to do the following:
- Verify that the
@angular/animationspackage is installed and listed as a dependency in ourpackage.json. If not, add it by runningnpm install --save @angular/animations - Import
BrowserAnimationsModuleand add it to the module’s imports array (line 7):
Angular also comes with
NoopAnimationsModule, which we can use to disable all animations globally. It’s more commonly used for testing to mock the real animation when the animations are either too slow or don’t play any role in what’s being tested.
Animation APIs
Angular’s animation module provides functional APIs to create and control our animations. Angular animations consist of five main functions:
-
trigger: This is a container for all other animation function calls. It tells Angular which set of styles/animation to apply to the element. -
state: This is a named set of CSS styles applied on successful transition to a given state. -
style:This is a set of CSS styles applied to the element at a given state. -
animate: This specifies the timing information for a transition. -
transition: This defines the animation sequence between two states.
Note: You can find a complete list of the available functions in Angular’s official docs.
Style’s JavaScript/CSS convention
The style function, an integral part of Angular animations, is used to specify which styles to apply to the target element at a certain state. An interesting thing about this function is that it accepts two types of conventions—camel case and dashed case—which explains the varying syntax in animation codes we can find on the internet.
Camel case
The JavaScript naming convention uses camel case keys. Angular animations accepts this as is, letting us pass in regular key-value pairs like this:
Dashed case
The CSS property naming convention (dashed case), however, has to be enclosed in quotes to stop JavaScript from trying to interpret the hyphens as arithmetic operators. So, the same code above using the dashed case would look something like this:
Animation process
Animations using Angular’s BrowserAnimationModule go through four steps:
- Evaluate data binding expression: This tells Angular which animation state the host element is assigned to.
- Data binding target: This tells Angular which animation target defines CSS styles for the elements state.
- State: This tells Angular which CSS styles should be applied to the element.
- Transition: This tells Angular how it should apply the specified CSS styles when there’s a state change.
Order of execution
Angular animations happen after their trigger. For instance, the :enter state change will get called after ngOnInit and the first change detection cycle, whereas :leave happens right after the element ngOnDestroy is called.
Angular animations’ order of execution
In addition, each time an animation is triggered, the parent animation will have priority over the children, blocking all child animations from executing unless explicitly stated to execute both. To run both animations, the parent animation must query each element containing the child animations and run it using the animateChild method, which is covered in more detail in the Target Children Elements lesson.
Example
Angular animations’ definitions are added as part of the Component decorator’s animation property. The animation property accepts an array of trigger functions containing the trigger name and information about the animation.
A horizontal sliding animation, for example, will be structured in the following way:
The code snippet above contains the trigger with the name “horizontalSlide” (line 8). This trigger name will be used in the template to indicate which set of states and transitions the element has access to.
The trigger function contains an array of state and transition functions. The state function contains the name of the state: “left” and “right,” along with their respective styles (lines 18 and 19). Lastly, the transition function (line 20) contains the animate function, which tells Angular how to animate the element as it changes states.
To use this in our template, attach the animation trigger to the target element and bind it to a variable that contains the state names (“left” and “right”).
After adding the currentPosition variable to the component file and a button to toggle between the two states, we’ll end up with the following output.
Run the code below and click on the button to see the box moving from left to right and vice versa.
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', () => {
page.navigateTo();
expect(page.getTitleText()).toEqual('Welcome to angular!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});