Angular: How to create animation using Angular Animations

Matsal Dev
6 min readApr 18, 2022

--

Animations are a great way to improve the user experience. We can do them both from the style sheet and with the Angular framework. In this article, I’ll show you how to do it using Angular.

Demo

Imagine we have an online store where we sell shoes. The user sees the list of shoes and after clicking on any of them, the information about adding them to the basket is displayed. This is a simplified example of a real store that I made for this article. Instead of different shoe model names, I’ve only limited myself to displaying the shoe brands that represent them. When finished, the app should behave like this:

The final result.

Prepare the code.

To get started as soon as possible, let’s put the following code in our app component.scss:

@import url('https://fonts.googleapis.com/css2?family=Epilogue:wght@400;500;600&family=Work+Sans:wght@500&display=swap');:host {
font-family: 'Epilogue', sans-serif;
}
.container {
display: flex;
}
h1 {
margin: 40px 40px 20px;
font-weight: 700 !important;
}
ul {
list-style-type: none;
}
.list-wrapper {
margin: 0 0 20px;

.list-item {
width: 380px;
height: 50px;
padding: 0 0 0 30px;
margin: 20px 0 0;
align-items: center;
display: flex;
border-radius: 15px;
background: #F4F4F4;
color: #9B9B9B;
font-size: 18px;
font-weight: 400;
cursor: pointer;
}
}
.tile {
width: 300px;
margin: 20px 0 0 100px;
height: 250px;
background: #FFE9E9;
border-radius: 15px;

.tile-header {
padding-left: 20px;
font-weight: 400;
font-size: 18px;
margin: 20px 0;
color: #FD8383;
}
.tile-body {
display: flex;
justify-content: center;
align-items: center;
height: 60%;
font-size: 64px;
color: #C63838;
}
}

App.component.html:

<h1>Shoes</h1>
<div class="container">
<div class="list-wrapper">
<ul>
<li *ngFor="let brand of shoes" (click)="selectedBrand = brand" class="list-item">{{brand}}</li>
</ul>
</div>
<div class="tile">
<h5 class="tile-header">Added to bag</h5>
<div class="tile-body">
<span class="tile-name">{{selectedBrand}}</span>
</div>
</div>
</div>

App.component.ts:

import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'animations';
selectedBrand: string = 'Nike';
shoes: string[] = [
'Adidas',
'Nike',
'Puma',
'Umbro'
]
}

After running the above code, the application should work as below:

Now that we have everything ready, it’s time to start creating the animation.

Create Animation

  1. Let’s start with importing the appropriate module that will allow us to use the animation. Let’s add “BrowserAnimationModule” to the module of our application:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

2. The next step is to import the animation functions that we are going to use. In our case, we will use the following:

import {trigger, state, style, animate, transition} from '@angular/animations';

Trigger — the function by which the animation knows when to start an action. As the first argument it takes the name of the animation that will be used to include elements in the HTML template. The second argument is an array of states and transitions.

State — the function that defines the states that an element can take. For example, if an element is expanded its state can be named “expanded”, and if it is collapsed, then it becomes “collapse”.

Style — this function describes the styles that will be included when the element is in a certain state, eg when it is in a “collapse” state its height will be 0, and when it is “expanded” state its height will be 100px. In this case, style will take an object with height that depends on the state.

Animate —the function that determines the duration of the animation, its delay and type.

Transition — the function that describes what is to happen when an element changes its state. There are different ways to change your condition.

3. Then, using the above knowledge, let’s make the following changes in the app.component.ts file:

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [
trigger('checkItem', [
state('check', style({
backgroundColor: '#FFE9E9',
color: '#FD8383',
fontWeight: '500'
})),
state('uncheck', style({
fontWeight: '400'
})),
transition('check => check, [
animate('.2s')
]),
]),
]
})

As you can see, we used the functions mentioned earlier here. Let’s also make changes to the app.component.html file:

<h1>Shoes</h1>
<div class="container">
<div class="list">
<ul>
<li
*ngFor="let brand of shoes"
(click)="selectedBrand = brand" class="list-item"
[@checkItem]="selectedBrand === brand ? 'check' : 'uncheck'">{{shoe}}
</li>
</ul>
</div>
<div class="tile">
<h5 class="tile-header">Added to bag</h5>
<div class="tile-body">
<span class="tile-name">{{selectedShoes}}</span>
</div>
</div>
</div>

When the user clicks on item, the ‘selectedShoe’ variable will be assigned the brand name they chose. When the name of the selected brand is the same as the name of the item, then the first condition will be met and the ‘checkItem’ function will be run. The state of the element will change to ‘check’ which will cause the style of the object with properties included in the function and will make the item change its appearance. It will go from the ‘hide’ state (this state was at the beginning, and it resulted from the fact that the name of the selected brand was different from the name of the item) to the ‘check’ state, and this transition will be described by the animate function. In our case, the transition from one state to the other will take .2 seconds. A similar situation will occur in the case of transition from the ‘uncheck’ state to the ‘check’ state.

After making the changes, the application works like this:

4. As you can see by introducing a few changes, we can easily highlight the item selected by the user. Let’s add an animation that will show an item has been added to the basket (it was clicked by the user). This type of animation appears when you click and lasts for a few seconds and then disappears.

Changes in app.component.html:

<h1>Shoes</h1>
<div class="container">
<div class="list">
<ul>
<li
*ngFor="let brand of shoes"
(click)="selectedBrand = brand" class="list-item"
[@checkItem]="selectedBrand === brand? 'check' : 'uncheck'">
{{shoe}}
</li>
</ul>
</div>
<div class="tile" [@show]="selectedBrand">
<h5 class="tile-header">Added to bag</h5>
<div class="tile-body">
<span class="tile-name">{{selectedBrand}}</span>
</div>
</div>
</div>

App.component.ts:

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
animations: [
trigger('checkItem', [
state('check', style({
backgroundColor: '#FFE9E9',
color: '#FD8383',
fontWeight: '500'
})),
state('uncheck', style({
fontWeight: '400'
})),
transition('check => uncheck', [
animate('.2s')
]),
]),
trigger(‘show’, [
transition('* => *', [ // each time the binding value changes
animate('.5s', style({ opacity: 1 })),
animate('.5s 1500ms', style({ opacity: 0 }))
])
])
]
})

We added the “show” animation to our animations. It is performed every time the value of the “selectedBrand” variable changes. However, we can be confused when we look at the first argument of the transition function. Earlier, we covered an example of transition from one state to another, and here we have a weird syntax. This syntax means “wild card”. It connects each state animation. In case there are several different animations, we can use this syntax to put it at the end to perform this transition when the state pairs are not invoked otherwise. After introducing further changes, we got the end result:

Summary

Undoubtedly, Angular’s strong feature that distinguishes it from the competition is the possibility of creating various types of animations. The animation presented above is quite simple, but it is not its full potential! Angular provides a lot of functions to create very complex applications. If you have any questions, please leave a comment. I will try to answer as soon as possible.

--

--

Matsal Dev

Frontend Developer - Angular and Typescript enthusiast.