Creating Eye-Catching Shimmer Effects in Angular 16

Saunak Surani
Widle Studio LLP
Published in
7 min readJul 22, 2023
Shimmer Effects in Angular 16

In today’s web development, delivering engaging user experiences is crucial for keeping visitors on your site. One way to captivate users is by adding subtle and visually appealing animations, such as shimmer effects. Shimmer effects are widely used to simulate the appearance of loading or content placeholders before the actual data is displayed.

In this article, we will explore how to implement shimmer effects in Angular 16, a popular front-end framework. We’ll walk through the steps to create shimmering components that add an elegant touch to your user interface. So, let’s dive into the world of shimmer effects and make your Angular applications shine!

Table of Contents:

1. Understanding Shimmer Effects
2. Setting Up an Angular 16 Project
3. Creating a Shimmer Service
4. Implementing Shimmer Components
4.1. Shimmer Loader Component
4.2. Shimmer Card Component
5. Fine-Tuning Shimmer Effects
6. Bonus: Dynamic Shimmer Content
7. Conclusion

1. Understanding Shimmer Effects

Shimmer effects are animations that mimic a subtle, wave-like movement, creating the illusion of loading content. These effects are commonly used in places where data is asynchronously loaded, such as news feeds, image galleries, or product listings. Shimmer effects offer a more pleasant experience for users compared to static loading spinners.

The shimmer effect is typically achieved by animating a gradient pattern that moves across the component, giving the impression of shimmering light. As the actual content is fetched and rendered, the shimmer effect seamlessly transitions to reveal the loaded data.

2. Setting Up an Angular 16 Project

Before we start implementing shimmer effects, let’s set up an Angular 16 project.

Step 1: Install Angular CLI

npm install -g @angular/cli

Step 2: Create a new Angular project

ng new shimmer-effects-app
cd shimmer-effects-app

3. Creating a Shimmer Service

To encapsulate the logic for shimmer effects, we’ll create a Shimmer Service. This service will be responsible for generating unique shimmer animation IDs and managing their status.

Step 1: Generate the Shimmer Service

ng generate service shimmer

Step 2: Open the generated service file (shimmer.service.ts) and implement the service as follows:

// shimmer.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})

export class ShimmerService {
private shimmerAnimations: Set<string> = new Set();

constructor() {}

generateShimmerAnimationId(): string {
const animationId = `shimmer-${Math.random().toString(36).substr(2, 9)}`;
this.shimmerAnimations.add(animationId);
return animationId;
}

removeShimmerAnimation(animationId: string): void {
this.shimmerAnimations.delete(animationId);
}

isShimmerAnimationRunning(animationId: string): boolean {
return this.shimmerAnimations.has(animationId);
}
}

In this service, we generate unique shimmer animation IDs using the `generateShimmerAnimationId` method. The IDs will help us identify and control shimmer animations for individual components. We also provide methods to remove animations and check if a shimmer animation is currently running.

4. Implementing Shimmer Components

Now that we have the Shimmer Service ready, let’s proceed to implement the shimmer effect in two different components: a Shimmer Loader Component and a Shimmer Card Component.

4.1. Shimmer Loader Component

The Shimmer Loader Component will be used as a placeholder while content is loading or before it is rendered. It will display a shimmering effect until the actual data is ready to be displayed.

Step 1: Generate the Shimmer Loader Component

ng generate component shimmer-loader

Step 2: Open the generated component file (shimmer-loader.component.ts) and implement the component as follows:

// shimmer-loader.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ShimmerService } from '../shimmer.service';
@Component({
selector: 'app-shimmer-loader',
templateUrl: './shimmer-loader.component.html',
styleUrls: ['./shimmer-loader.component.css']
})

export class ShimmerLoaderComponent implements OnInit {
@Input() shimmerFor: string;

constructor(private shimmerService: ShimmerService) {}

ngOnInit(): void {
const animationId = this.shimmerService.generateShimmerAnimationId();
this.startShimmerAnimation(animationId);
}

ngOnDestroy(): void {
this.shimmerService.removeShimmerAnimation(this.shimmerFor);
}

startShimmerAnimation(animationId: string): void {
// Implement shimmer animation logic here
}
}

In this component, we utilize the Shimmer Service to generate and manage the shimmer animation ID. The `ngOnInit` lifecycle hook generates a unique animation ID for the component and starts the shimmer animation. We use the `ngOnDestroy` hook to remove the shimmer animation from the Shimmer Service when the component is destroyed.

4.2. Shimmer Card Component

The Shimmer Card Component will be used to represent data cards or items while the actual data is being loaded. It will display shimmering content to simulate a loading effect.

Step 1: Generate the Shimmer Card Component

ng generate component shimmer-card

Step 2: Open the generated component file (shimmer-card.component.ts) and implement the component as follows:

// shimmer-card.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ShimmerService } from '../shimmer.service';
@Component({
selector: 'app-shimmer-card',
templateUrl: './shimmer-card.component.html',
styleUrls: ['./shimmer-card.component.css']
})

export class ShimmerCardComponent implements OnInit {
@Input() shimmerFor: string;

constructor(private shimmerService: ShimmerService) {}

ngOnInit(): void {
const animationId = this.shimmerService.generateShimmerAnimationId();
this.startShimmerAnimation(animationId);
}

ngOnDestroy(): void {
this.shimmerService.removeShimmerAnimation(this.shimmerFor);
}

startShimmerAnimation(animationId: string): void {
// Implement shimmer animation logic here
}
}

Similar to the Shimmer Loader Component, the Shimmer Card Component also interacts with the Shimmer Service to generate and manage the animation ID. The shimmer animation starts when the component initializes and is removed from the Shimmer Service when the component is destroyed.

5. Fine-Tuning Shimmer Effects

At this point, we have created the skeleton of our shimmering components. However, we still need to implement the shimmer animation logic inside the `startShimmerAnimation` method for both components.

Shimmer effects can be achieved using

CSS animations or by leveraging Angular animations. Let’s explore both approaches and see how we can implement them to create shimmer effects in our components.

5.1. CSS Animation Approach

In this approach, we’ll utilize CSS animations to create shimmer effects. We’ll apply the animation to an overlay element that simulates the shimmering effect while the actual content is loading behind it.

Step 1: Add CSS styles for shimmer animation

/* shimmer-loader.component.css and shimmer-card.component.css */
.shimmer {
position: relative;
}
.shimmer::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image: linear-gradient(-45deg, #f0f0f0 25%, #e4e4e4 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmerAnimation 2s infinite;
}
@keyframes shimmerAnimation {
0% {
background-position: -100% 0;
}
100% {
background-position: 100% 0;
}
}

In the above CSS code, we define the `shimmer` class and apply the shimmer animation using the `::after` pseudo-element. The `shimmerAnimation` keyframes create the shimmering effect by animating the background position from left to right.

Step 2: Apply the shimmer effect to the components’ templates

<! - shimmer-loader.component.html →
<div class="shimmer" [ngStyle]="{ width: '200px', height: '24px' }"></div>
<! - shimmer-card.component.html →
<div class="shimmer" [ngStyle]="{ width: '100%', height: '200px' }"></div>

In the templates, we apply the `shimmer` class to the element we want to shimmer. In the example above, we create a simple rectangular div with a shimmer effect. You can customize the dimensions and styles to match your specific use case.

5.2. Angular Animation Approach

Alternatively, we can use Angular animations to achieve shimmer effects. This approach allows for more control and flexibility over the animation.

Step 1: Import the necessary Angular animations modules

// app.module.ts
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Step 2: Define the shimmer animation using Angular animations

// shimmer-loader.component.ts and shimmer-card.component.ts
import { animate, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'app-shimmer-loader',
templateUrl: './shimmer-loader.component.html',
styleUrls: ['./shimmer-loader.component.css'],
animations: [
trigger('shimmerAnimation', [
transition('void => *', [
style({ backgroundPosition: '-100% 0' }),
animate('2s', style({ backgroundPosition: '100% 0' }))
])
])
]
})
// shimmer-card.component.ts
import { animate, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'app-shimmer-card',
templateUrl: './shimmer-card.component.html',
styleUrls: ['./shimmer-card.component.css'],
animations: [
trigger('shimmerAnimation', [
transition('void => *', [
style({ backgroundPosition: '-100% 0' }),
animate('2s', style({ backgroundPosition: '100% 0' }))
])
])
]
})

In the above code, we define a trigger named `shimmerAnimation` with a transition from void (component initialization) to any state (*). The animation changes the background position from left to right over a 2-second duration.

Step 3: Apply the shimmer animation in the components’ templates

<! - shimmer-loader.component.html →
<div class="shimmer" [@shimmerAnimation]></div>
<! - shimmer-card.component.html →
<div class="shimmer" [@shimmerAnimation]></div>

In the templates, we use the Angular animation trigger (`[@shimmerAnimation]`) to apply the shimmer effect to the respective elements.

6. Bonus: Dynamic Shimmer Content

For an added touch, we can make our shimmer components more dynamic by adding varying content based on the use case.

Let’s say we want to display a shimmering list of items, such as a product catalog. We can create a Shimmer List Component that generates a dynamic number of shimmer cards based on the input.

Step 1: Generate the Shimmer List Component

ng generate component shimmer-list

Step 2: Open the generated component file (shimmer-list.component.ts) and implement the component as follows:

// shimmer-list.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { ShimmerService } from '../shimmer.service';
@Component({
selector: 'app-shimmer-list',
templateUrl: './shimmer-list.component.html',
styleUrls: ['./shimmer-list.component.css']
})

export class ShimmerListComponent implements OnInit {
@Input() itemCount: number = 3; // Default to 3 shimmer cards
shimmerItems: number[] = [];

constructor(private shimmerService: ShimmerService) {}

ngOnInit(): void {
for (let i = 0; i < this
.itemCount; i++) {
const animationId = this.shimmerService.generateShimmerAnimationId();
this.shimmerItems.push(animationId);
}
}

ngOnDestroy(): void {
this.shimmerItems.forEach((animationId) =>
this.shimmerService.removeShimmerAnimation(animationId)
);
}
}

Step 3: Update the Shimmer List Component template (shimmer-list.component.html)

<! - shimmer-list.component.html →
<div *ngFor="let item of shimmerItems" class="shimmer" [@shimmerAnimation]></div>

In the template, we use the `ngFor` directive to generate the desired number of shimmer cards based on the `itemCount` input. Each card has its own unique animation ID, allowing them to shimmer independently.

7. Conclusion

In this tutorial, we explored how to create eye-catching shimmer effects in Angular 16 applications. We learned two approaches to implementing shimmer animations: the CSS animation approach and the Angular animation approach. Both methods offer beautiful and seamless shimmer effects that can enhance the user experience during content loading.

By using the Shimmer Service, we efficiently managed the shimmer animations for individual components, making our implementation reusable and maintainable. Additionally, we went a step further and created a dynamic shimmer list component that generates shimmer cards based on the input, providing even more flexibility.

As you continue to develop your Angular applications, consider incorporating shimmer effects to engage users while data is being loaded. Experiment with different styles, durations, and triggers to find the perfect shimmer effect for your application.

Now that you have the tools and knowledge to create shimmer effects, go ahead and make your Angular applications shine with delightful shimmering animations!

--

--

Saunak Surani
Widle Studio LLP

Passionate about technology, design, startups, and personal development. Bringing ideas to life at https://widle.studio