How to Create a Sleek Preloader Animation Using GSAP Timeline

How to Create a Sleek Preloader Animation Using GSAP Timeline

Have you ever come across a website with a fluidly animated preloader that drew you in and grabbed your interest from the first glance? It made you want to reload the page over and over again.

Last week, while browsing the internet, I came across Enyata's website, and after seeing the preloader, I was pretty impressed, so I thought, "Why not develop it out?" And that's exactly what I did.

In this article, I'll show you how to use the timeline feature of the Greensock Animation Platform (GSAP), and at the end, you'll be able to make this preloader.

eb0bf3400755c6f40dcbd3c950dc5c3e5efc9426.gif

Let's get started!

Prerequisites

This article assumes that you have:

  • Basic understanding of HTML and CSS
  • Basic understanding of Javascript
  • A code editor (VS Code recommended)
  • A web browser (Chrome or Firefox recommended)

What is GSAP?

The Greensock Animation Platform (GSAP) is arguably one of the best animation libraries for the web because it enables you to animate just about anything that can be accessed with JavaScript, including DOM Elements, SVGs, generic objects, canvases, and more.

GSAP is also a great choice because it is:

  • flexible

  • lightweight

  • fast, like really fast (estimated to be 20x faster than jQuery),

  • has a large and supportive community via the forums.

You can learn more about this library here.

Tweens and Timelines

In GSAP, a Tween is a Javascript object that allows you to define parameters that control how animation plays out. Tweens works in such a way that you provide the properties in the format:

gsap.method(element, var, duration)

A Timeline is a tool that allows you to chain together multiple animations (i.e Tweens, and other timelines by nesting ) which makes it easy to control the animations as a whole, and to precisely set their timing. A typical timeline is written like so:

let tl = gsap.timeline();

We would be looking into the most commonly used methods to create Tweens:

  • to()

  • from()

  • fromTo()

to()

This is the most common method in GSAP, as it allows you to define the destination values. Just as its name implies, it specifies where your animation is going to .

from()

The from() method acts like a backwards tween, where you set where the values should start from, and then GSAP animates to the element’s current values.

fromTo()

The fromTo() is really great because it allows us to define both the Start and End values for animations, just as shown in the demo below:

There are many other methods listed in the documentation, but we would be working with these three.

Now that we've learned the basics of Tweens and Timelines, let's build out the preloader!

Building out the preloader

Yay! The time we've all been waiting for is here. In this section, we will build a very simple landing page with HTML and CSS, build the preloader, and use the GSAP timeline to animate the elements.

This section has been broken into different steps to make it easier to understand.

Step 1: Install GSAP

First, to use GSAP in a project, we would have to install it. Luckily, there are different methods to do so.

Using the CDN

You can easily set up GSAP into your project by adding the following to your HTML file:

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js"></script>

Installing via Package managers

//Using npm
npm install gsap

//or with yarn
yarn add gsap

Now that it's installed, then import it into your project

import { gsap } from "gsap";

Step 2: Creating the landing page

We'll start by creating an HTML page with 2 divs — one, the preloader div, and the other will be the landing page.

Inside the preloader div, we have a div with a class prl-logo which is the logo on the preloader, and it contains an h1 which would be hidden until it is defined later in the animation sequence.

The SVG element is the menu button in the navigation bar.

<body>
    <!-- Intro -->
    <div class="preloader">
      <div class="prl-logo">
        <h1 class="hide"> cruise. &trade; </h1>
      </div>
      <div class="lightCyan-slider"></div>
      <div class="persianGreen-slider"></div>
      <div class="white-slider"></div>
    </div>

    <!--Hero-->
    <section>
      <nav>
        <a class="logo" href="index.html">Cruise.</a>
        <svg
          class="menu-btn"
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 24 24"
          width="24"
          height="24"
        >
          <path fill="none" d="M0 0h24v24H0z" />
          <path
            d="M3 4h18v2H3V4zm0 7h12v2H3v-2zm0 7h18v2H3v-2z"
            fill="rgba(255,255,255,1)"
          />
        </svg>
      </nav>
      <div class="hero-content">
        <h2>Lets go on an adventure.</h2>
        <p
          >Lorem ipsum dolor sit amet consectetur adipisicing elit. Dolorem
          culpa vero quae perferendis molestiae exercitationem nemo atque
          veritatis ratione rem dolore quibusdam quia, a totam quidem nostrum
          iusto! Reiciendis, rem.</p
        >
        <button>Explore</button>
      </div>
    </section>

    <script src="app.js"></script>
  </body>

Now, for the CSS, we have some basic styling, using flex and position to manipulate the layout and positioning of the elements.

You can also get the fonts I used from Google Fonts — Make sure to import them either in the head tag of your HTML file or in your CSS file.

For the preloader section and the sliders, we'll give them a position of fixed so that we can set the top and left properties for its positioning, and then the height and width of 100%, so it takes up 100% of the viewport.

To make the landing page responsive on mobile devices, we'll define some media queries too.

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: "Montserrat", sans-serif;
  min-height: 100vh;
  max-width: 100%;
  background: url(home1.jpg) no-repeat center center fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
  position: relative;
}

nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 10vh;
  padding: 1rem 5rem;
}

.logo {
  font-family: "Abril Fatface", cursive;
  text-decoration: underline;
  font-size: 1.3rem;
  color: #fff;
  font-weight: lighter;
}

.menu-btn {
  cursor: pointer;
}

.hero-content {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 60%;
  color: #fff;
  text-align: center;
  z-index: -1;
}
.hero-content h2 {
  font-size: 3rem;
  font-family: "Abril Fatface", cursive;
  font-weight: lighter;
}
.hero-content p {
  font-size: 0.9rem;
  font-family: "Montserrat", sans-serif;
  color: #f0f2f2;
  margin: 1.5rem 0rem;
  line-height: 24px;
}

button {
  border: none;
  outline: none;
  padding: 0.5rem 1.5rem;
  border-radius: 10px;
  color: #025959;
  cursor: pointer;
  margin-top: 1.5rem;
  font-size: 0.9rem;
}

/* Preloader  */
.preloader {
  background: white;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.prl-logo {
  font-family: "Abril Fatface", cursive;
  font-size: 1.3rem;
  z-index: 2;
}

/* Sliders  */
.lightCyan-slider,
.persianGreen-slider,
.white-slider {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transform: translateX(-100%);
}
.lightCyan-slider {
  background: #d5f2ef;
}

.persianGreen-slider {
  background: #03a6a6;
}

.white-slider {
  background: #fff;
}

.hide {
  opacity: 0;
  color: #03a6a6;
  font-weight: lighter;
}

/* Responsive media queries */
@media screen and (max-width: 768px) {
  .logo,
  .prl-logo {
    font-size: 1rem;
  }
  .hero-content h2 {
    font-size: 2rem;
  }
  .hero-content p {
    font-size: 0.8rem;
  }
}

@media screen and (max-width: 425px) {
  nav {
    padding: 1rem 3rem;
  }
}

The resulting layout 👇

screencapture-cruise-landing-netlify-app-2022-01-22-06_43_07.png

Great, we have our landing page set up, now let's dive into Javascript and build the animation timeline.

Step 3: Implementing GSAP timeline

We start by creating a timeline, which accepts the defaults property. This lets you set properties that will be inherited by all tweens in that timeline.

In this case, we're setting the ease animation to power1.out.

const tl = gsap.timeline({ defaults: { ease: "power1.out" } });

To define a tween:

  1. Define the target element

  2. Define the vars parameter

  3. Define the position parameter(Note: this is optional)

tl.to(".lightCyan-slider", {
  x: "-10%",
  duration: 1,
});

The code above first takes the element we want to animate( the target element), which in this case is the class lightCyan-slider.

Then, we add the vars parameter, which contains the properties/values you want the tween to have. In this case, the vars parameter contains the x key which is equivalent to a transform: translateX() in CSS.

To position the animations in the timeline, you'll need to pass the position parameter after the vars parameter. Here it is defined as "-=1", and it is super helpful because it tells the timeline exactly where to insert the animation.

In this case, the animation runs 1 second before the end of the previous animation.

tl.to(
  ".persianGreen-slider",
  {
    x: "-20%",
    duration: 1.5,
  },
  "-=1"
);

To learn more about the position parameter, check here.

Now, we can define the other tweens:

const tl = gsap.timeline({ defaults: { ease: "power1.out" } });

tl.to(".lightCyan-slider", {
  x: "-10%",
  duration: 1,
});

tl.to(
  ".persianGreen-slider",
  {
    x: "-20%",
    duration: 1.5,
  },
  "-=1"
);

tl.to(
  ".white-slider",
  {
    x: "-30%",
    duration: 1.5,
  },
  "-=1"
);

tl.to(".hide", {
  x: "0%",
  duration: 2,
  opacity: 1,
});

tl.to(".preloader", {
  x: "200%",
  duration: 3,
});

tl.fromTo(
  "nav",
  {
    opacity: 0,
  },
  {
    opacity: 1,
    duration: 1,
  },
  "-=2"
);

tl.fromTo(
  ".hero-content",
  {
    opacity: 0,
    y: -20,
  },
  {
    opacity: 1,
    duration: 1,
    y: 0,
  },
  "-=1.5"
);

Note : It is important that you write your tweens in the order that you want the timeline to run.

For example, in the code above, we go from:

.lightCyan-slider --> .persianGreen-slider --> .white-slider --> .hide --> .preloader --> nav -->.hero-content

Great!, we have successfully created a timeline using GSAP that chains all the animations for our landing page, see the result!

eb0bf3400755c6f40dcbd3c950dc5c3e5efc9426.gif

Check out the live demo and the code repository on Github.

Conclusion

Congrats!!! If you made it to the end, that means you have successfully implemented the GSAP timeline and built an awesome preloader. I hope you got a lot of value from this article.

I want you to know there are a lot of possibilities in using GSAP and is not limited to preloaders. Check out some of the best GSAP animation websites on awwwards and on Greensock Showcase.

Also, do well to like and follow for more content, and if you've got any questions or spotted any errors... please do well to leave some feedback as this is my first technical article :)

Resources and Further Reading