Angular 20.1 Simple Animate On Scroll POC Implementation

26.07.2025 - 09:38

Read on dev.to

Did you ever think about creating your own Animate on scroll - for short AOS - library in Angular?
I did a few times, so i gave it a try and made a simple AOS library which supports only one animation type but can be extended pretty easy.

First of all, what is AOS?
AOS - Animate on scroll is some kind of UI feature where divs, images, ... - you name it - will get visible if with a beautiful animation when entering the viewport and hide again with the same - or another - animation when leaving the view port.

What do we need to archive this wanted behavior?
We basically only need a scrolling container where the animated elements are within and a little bit of angular magic.

Let's start by installing the latest angular cli globally, create a project and add tailwind since we will use it for easier animating!

So in your Favorite terminal, execute the following commands:

This will create a project in your desired directory and install its dependencies.
After that we need to setup tailwind.
We can do this easily by executing
npm install tailwindcss @tailwindcss/postcss postcss --force

Adding a file called .postcssrc.json with the following content:

and adding @import "tailwindcss"; to our angular project styles.scss.
Let's also add some simple primary & secondary colors for our testing environment in styles.scss.

Your styles.scss with custom colors and darkmode support could look like this for example:

Perfect! Our base is setup completly fine.
Now we should create some basic buttons or something which we can later animate on scroll.
For that i made a simple button which gets repeated four times within our future scrolling container.
This looks like this in the code:

And like this in the browser. (Note that you can only see one item since each button is wrapped in a full screen height div and you would need to scroll to see the others.)

Now comes the fun part!

We need a few things to make this work:

  1. A Service which get's initialized when the app gets initalized so we can listen to scroll events on needed containers.
  2. A directive which marks needed containers so we know we need to listen for scroll events on this container.
  3. A directive which marks an element which should be animated on scroll with the needed meta, such as threshold, animation name, and so on.
  4. A environment provider which will initialize our service on startup and gives us the possibility to customize everything.

**Let's start with the Service.

What do we need here?**

The first thing We need is an array with HTMLElements for which we should listen to scroll events, and a function to push to this array and add listeners to those elements.
We will push this elements from directives including a onDestroyRef, so we can stop listening to its events when the component attachted to the directive we are calling the service from gets destroyed.

So let's do that.

Create a simple service by executing ng g s aos-service in your favorite terminal. ( Make sure to remove the {providedIn: 'root'} part since we will later register it as a library.

After adding a function to save elements, and listen to scroll events your service should look like this:

Perfect!
Since we got this, we can add our aosWatch directive to register scroll containers.

This is actually pretty easy. All we need here is a SSR check to prevent logic from running in SSR context if you are using SSR, the elementRef to the element we are appending it to and the AosService injected.

If you are done it should look like this:

If you now add the xsipAosWatch directive to the main div and scroll in the Browser, you should se many SCROLLING!! logs.

Perfect, we are halfway done!

Let's implement our aosElement directive
What do we need for that?
This is actually a pretty simple directive. It will set a attribute using setAttribute and some tailwind classes to smooth out animations.
You could for sure improve this with more input params, but for now we will only add one for the animation style which we will later bind to a tailwind class using a object.

Our aos directive which identifies elements which should be animated on scroll could look like this:

If we import this directive to our app-component and append it to the third element - in this case the div with the title Button 3 we will see in the browser that it got a few more classes and a new attribute now.
That's exactly what we wanted to archive!

Let's re-visit our aos-service and add a function to identify if elements are in view or hidden, as well as a custom naming to tailwind class mapping ( for example fadeIn will result in opacity-0 ) and a type for that to make our aos-directive input typesafe!

After doing all this changes our aos-service should be finished and look like this:

And our aos-directive like this:

We are done! Congratulations, you did your first AOS implementation.
For sure, this is a POC, but can be refactored into something really cool!

If you visit https://aos.kerschbaumer.dev/ and scroll through the page, you will see that button 3 fades in as you scroll it into view, and out as it leaves the view.

Also here is the github repo for the POC :
https://github.com/xsip/ng-20-aos

I hope you learned something.
Happy coding :)