DEV Community

Cover image for GSAP Animations in Angular - Animation Directives
Nicola
Nicola

Posted on

2 1

GSAP Animations in Angular - Animation Directives

Create a directive for animation

As the second part of this tutorial we will create an attribute-directive, which will define a specific animation and its attributes.

We will start with a simple FadeIn animation.

But before starting with the real directive, we are going to create a generic class which will be extended by arbitrary directives, called CoreAnimationDirective.

The goal of this directive is to define the standard methods and attributes for our future animation directives, to prevent a lot of repeats and hard-to-mantain directives.

The CoreAnimationDirective class

Let's create! Before doing anything, let's create a specific folder for gsap directive.

From 'src/app' run in terminal mkdir directives\gsap.

Note: use \ or / directory separator according to your system.

Your project should look like this:

Project structure

Let's create the class, move to the gsap directory cd directives\gsap & echo > core-animation.directive.ts.

Open the file and write the following:

import {ElementRef, EventEmitter, Input, Output} from '@angular/core';
import {TimelineMax} from 'gsap';

export class CoreAnimationDirective {
  @Input() duration = 1;
  @Input() delay = 0;

  @Output() complete: EventEmitter<null> = new EventEmitter();
  @Output() reverseComplete: EventEmitter<null> = new EventEmitter();
  protected timeline: TimelineMax;

  constructor(protected element: ElementRef) {}
}
Enter fullscreen mode Exit fullscreen mode

A little bit of explanation:

  • @Input() duration - the duration of the animation
  • @Input() delay - the delay of the animation
  • @Output() complete - event emitter for the animation complete callback
  • @Output() reverseComplete - event emitter for the animation reverseComplete callback
  • protected timeline: TimelineMax - the timeline for animation

Check the docs about TimelineMax and eventCallbacks here.

The constructor have only 1 param, the element (ElementRef), it's the ref to the native element which uses the directive.

We need to instantiate our timeline before animating it inside the constructor:

constructor(protected element: ElementRef) {
  this.timeline = new TimelineMax({
    onComplete: _ => this.complete.emit(),
    onReverseComplete: _ => this.reverseComplete.emit(),
    paused:true,
    reversed:true
  });
}
Enter fullscreen mode Exit fullscreen mode

This piece of code will create a new timeline, paused and not reversed, with a onComplete and onReverseComplete callback.

Let's create the animateIn method:

protected animateIn() {
  if(this.timeline.isActive()) {
    this.timeline.kill();
  }
  this.timeline.play();
}
Enter fullscreen mode Exit fullscreen mode

This method will kill the animation if in progress (you can return if is active so it will not stop), and play the current animation.

The FadeInDirective class

Let's proceed with the next class, this class will perform the real animation.

It will extend the CoreAnimationClass, as we don't need to repeat some portions of code.

Inside the gsap folder we've created previously, run echo > fade-in-animation.directive.ts and write the following code inside:

import { Directive, OnInit, OnDestroy, ViewContainerRef, ElementRef, Input, EventEmitter } from '@angular/core';
import { TimelineMax } from 'gsap';
import { CoreAnimationDirective } from './core-animation.directive';

@Directive({
  selector: '[fadeInAnimation]'
})
export class FadeInAnimationDirective extends CoreAnimationDirective implements OnInit {
  constructor(protected element: ElementRef) {
    super(element);
  }

  ngOnInit() {
    // perform animation
    this.animateIn();
  }

  protected animateIn() {
    this.timeline.from(this.element.nativeElement, this.duration, {opacity:'0', ease:"Expo.easeInOut"}, this.delay);
    super.animateIn();
  }
}
Enter fullscreen mode Exit fullscreen mode

This component extends the CoreAnimationDirective, so we don't need to define the @Input, @Output and other properties twice.

We need to create the opacity animation using this.timeline.from as follow:

this.timeline.from(this.element.nativeElement, this.duration, {opacity:'0', ease:"Expo.easeInOut"}, this.delay);

This will perform an animation on element opacity, from 0 to 1 (or to element opacity current value).

Image of Datadog

The Future of AI, LLMs, and Observability on Google Cloud

Datadog sat down with Google’s Director of AI to discuss the current and future states of AI, ML, and LLMs on Google Cloud. Discover 7 key insights for technical leaders, covering everything from upskilling teams to observability best practices

Learn More

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more