Animations using React Hooks and GreenSock
Tags: react, javascript, webdev
Published: 2019-10-03 14:21:18

---
title: Animations using React Hooks and GreenSock
published: true
tags: react, javascript, webdev 
canonical_url: https://blog.logrocket.com/animations-react-hooks-greensock/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/pjogxdl4oxkwade70if9.jpeg
---
**Written by [Paul Ryan](https://blog.logrocket.com/author/paulryan/)**✏️

Delving into the world of animations on the web can either be a great journey or a tiresome one. My goal is to make it a great journey, while also using the power of React Hooks to further entice your learning experience.

## What do I need to know?

This article should not be treated as a primer on JavaScript or React. I will explain each of the concepts we use, but you should have at least a little knowledge of both. You can check out the [React docs here](https://reactjs.org/docs/getting-started.html).

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## What will we be creating?

I like to teach by example. Just throwing lots of concepts and text at you isn’t going to do any good for your learning, and to be honest, it would be very boring for the both of us. We are going to create two separate animations, each with an increasing level of difficulty.

Our first animation will be a simple loader, similar to Google’s:

![Finished Animated Loader](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/finished-animated-loader.gif?resize=520%2C134&ssl=1)

Our second will be animating the LogRocket logo to make it even better!

![LogRocket Logo](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/logrocket-logo.png?resize=294%2C76&ssl=1)

## Getting set up

Setting up is quick and easy: I have [created a CodeSandbox here](https://codesandbox.io/s/greensock-set-up-6pn1m) that has the GreenSock npm module and also has React, so you can just fork it and follow along.

## Google-style loader

Now we can start creating our `Loader` component. It would be great if you could follow along, but I will have a link to the complete CodeSandbox at the end.

The first thing we need for our loader is our graphic, which I have created. The SVG is a basic one with a little markup.

```jsx
<svg viewBox="0 0 150 33.2" width="180" height="150">
  <circle ref={circle} cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
  <circle ref={circle} cx="55.2" cy="16.6" r="16.1" fill="#de4431" />
  <circle ref={circle} cx="94.3" cy="16.6" r="16.1" fill="#f4b61a" />
  <circle ref={circle} cx="133.4" cy="16.6" r="16.1" fill="#009e52" />
</svg>
```

Then, in our source code, we can create a `Loader` component, which is where the magic will happen.

Inside the `Loader` component, we want to render our graphic.

```jsx
// src/loader.jsx
import React from "react";
const Loader = () => {
  return (
    <svg viewBox="0 0 150 33.2" width="180" height="150">
      <circle cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
      <circle cx="55.2" cy="16.6" r="16.1" fill="#de4431" />
      <circle cx="94.3" cy="16.6" r="16.1" fill="#f4b61a" />
      <circle cx="133.4" cy="16.6" r="16.1" fill="#009e52" />
    </svg>
  );
};
export default Loader;
```

You should now be seeing:

![Static Loader SVG](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/static-loader.png?resize=498%2C169&ssl=1)

Fantastic! We now have our graphic in place, so let’s go animate it.

When animating, the first thing you need is a reference to the elements you plan on animating. To get a reference to our elements, we can use the `useRef` Hook. `useRef` returns a ref object that has a `current` property, which is what we target with our animations.

Creating a `useRef` is straightforward:

```jsx
const myElement = useRef(null) 
```

So, for our case, we have four elements that we need to target. We will create four refs like so:

```jsx
const blue = useRef(null);
const red = useRef(null);
const yellow = useRef(null);
const green = useRef(null);
```

We then can add these refs to our SVG:

```jsx
<svg viewBox="0 0 150 33.2" width="180" height="150">
  <circle ref={blue} cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
  <circle ref={red} cx="55.2" cy="16.6" r="16.1" fill="#de4431" />
  <circle ref={yellow} cx="94.3" cy="16.6" r="16.1" fill="#f4b61a" />
  <circle ref={green} cx="133.4" cy="16.6" r="16.1" fill="#009e52" />
</svg>
```

Our component now looks like this:

```jsx
// src/loader.jsx
import React, { useRef } from "react";

const Loader = () => {
  const blue = useRef(null);
  const red = useRef(null);
  const yellow = useRef(null);
  const green = useRef(null);

  return (
    <svg viewBox="0 0 150 33.2" width="180" height="150">
      <circle ref={blue} cx="16.1" cy="16.6" r="16.1" fill="#527abd" />
      <circle ref={red} cx="55.2" cy="16.6" r="16.1" fill="#de4431" />
      <circle ref={yellow} cx="94.3" cy="16.6" r="16.1" fill="#f4b61a" />
      <circle ref={green} cx="133.4" cy="16.6" r="16.1" fill="#009e52" />
    </svg>
  );
};

export default Loader;
```

With everything in place, we can start using GreenSock.

First we import `TweenMax`.

```jsx
import { TweenMax } from "gsap";
```

TweenMax is a fully featured module we use from GreenSock that will aid us in creating our animations. It has many methods, and we will make use of a couple!

> GreenSock also offers us TweenLite, which is a less featured module but is more lightweight.

For our animation, we want it to take place when our component mounts. In the traditional class-based component, we would use `componentDidMount`, but for Hooks we will use `useEffect`, which behaves the same with some small differences. To get a true deep dive into Hooks, you should check out this [great article](https://overreacted.io/a-complete-guide-to-useeffect/) by Dan Abramov.

So when our component mounts, we will use TweenMax’s `fromTo` method to animate our circles. The `fromTo` method is passed four arguments:

```jsx
fromTo(element(s), duration, start, end)
```

Let’s focus on getting the `blue` circle to move up and down. To do this we will target the `y` property of our animation.

So our code is as follows:

```jsx
TweenMax.fromTo(blue.current, 5, { y: 18 }, { y: -18 });
```

We first target our element, then we set a duration of `5s`. We start from `y` position `18` and finish on `-18`. This looks like the following:

![Blue Circle Animation](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/blue-circle-animation.gif?resize=336%2C140&ssl=1)

OK, so we have made a little progress, but it still has some issues — it is far too slow, and we also need the animation to be infinite. Let’s address these problems. To do so, all we need to do is add the `yoyo` and `repeat` properties to our `to` object.

```jsx
TweenMax.fromTo(blue.current, 0.5, { y: 18 }, { y: -18, yoyo: true, repeat: -1 });
```

`yoyo` means our animation will `yoyo` between the start and finish positions. Setting `repeat` to `-1` will make our animation infinite. We also set our duration to half a second so it will be much faster.

Now, with our new properties in place, we have:

![Blue Circle Animation](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/blue-circle-bouncing.gif?resize=336%2C140&ssl=1)

As you can see from the completed animation above, our yellow circle behaves the same as our blue circle. With this in mind, we can pass an array of elements (our `blue` and `yellow` ref) to our `fromTo` method.

```jsx
TweenMax.fromTo(
  [blue.current, yellow.current],
  0.5,
  { y: 18 },
  { y: -18, yoyo: true, repeat: -1 }
);
```

So now we have:

![Blue And Yellow Circles Bouncing](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/blue-yellow-circles-bouncing.gif?resize=336%2C140&ssl=1)

Success! I think you can now start seeing how powerful GreenSock is. To complete our animation, we just need to animate the red and green balls in the opposite way, like so:

```jsx
TweenMax.fromTo(
  [red.current, green.current],
  0.5,
  { y: -18 },
  { y: 18, repeat: -1, yoyo: true }
);
```

This code is almost the exact same as our code above except this time, we start on `y:-18` and finish on `y:18`.

Our final animation is now complete, and here’s how it should look:

![Finished Animated Loader](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/finished-animated-loader.gif?resize=520%2C134&ssl=1)

The complete code is below.

{% codesandbox gx7fi %}

## LogRocket logo animation

One animation down, one to go!

I have created an `SVG` for the LogRocket icon, and it is a big one, so I have included it in the starter CodeSandbox, which you can [check out here.](https://codesandbox.io/s/starter-logrocket-animation-8z29j)

The final animation will look like this:

![LogRocket Logo Animation Complete](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/logrocket-animation-complete.gif?resize=504%2C144&ssl=1)

As you can see from above, there is more to this than our first animation, so let’s get cracking!

The first part we are going to focus on is the rocket, which animates from the bottom. We have a `g` element with the `id` of `rocket`. This is the element we are going to target with GreenSock. Previously, we would have used `TweenMax` to do this, but now we will use `TimelineMax` since we want each of our elements to animate sequentially and not all at once.

We import `TimelineMax` like so:

```jsx
import { TimelineMax } from "gsap";
```

We first need to create a `Timeline`, and we do this by creating an instance of the `TimelineMax` class:

```jsx
const tl = new TimelineMax();
```

Similarly to `TweenMax`, our instance (`tl`) also has a `fromTo` method that we will use:

```jsx
tl.fromTo("#rocket", 2, { y: 50 }, { y: 0 });
```

This is very similar to our first animation except here, instead of using a `ref`, we are just passing the id — either way is fine.

Now our rocket should be coming up from the bottom like so:

![Rocket Animation](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/rocket-animation.gif?resize=88%2C130&ssl=1)

The next part is to `draw` our letters. All of our letter `path`s are wrapped in a `g` tag with the `id` `letters`, so they are easy for us to target. To get the drawing effect, we need to use a couple of `attributes`, which are `stroke-dasharray` and `stroke-dashoffset`. These are quite complicated, and to read in more detail, I recommend [heading here](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset).

For our case, we use these properties to break our paths into little pieces so we can animate them back together, which is what gives us our drawing effect. My rule of thumb here is setting the value of the two attributes to be the same, and once our text disappears, we are good to go. `100` is the value we will go with.

So in our `styles.css` file, we will set these two properties on our paths like so:

```jsx
svg #letters path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
```

As a side note, a `stroke` must be present on the `path` for this to work (this includes a `path` inheriting a `stroke` from a parent).

So now you are seeing the following:

![LogRocket Wordmark With Stroke Removed](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/logrocket-wordmark-stroke-removed.png?resize=714%2C190&ssl=1)

This is the same as what we had, but the letters are not as thick — that is because we have removed the `stroke`, but it still has a `fill`. The next step is setting the `fill-opacity` to `0`.

```jsx
svg #letters path {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  fill-opacity: 0;
}
```

With this in place, our letters have disappeared, so now we focus on getting them back.

All we need to do is animate our `strokeDashoffset` back to `0`. We will use our `tl` instance and the `to` method.

```jsx
tl.to("#letters path", 3, {
  strokeDashoffset: 0
});
```

As you can see, we use our `letters` selector and then target each `path` within that group. With that in place, our letters should now start drawing:

![Animated LogRocket Logo With Letter Paths Drawn](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/logrocket-logo-path-draw.gif?resize=456%2C162&ssl=1)

The final piece of the puzzle is to animate our `fill-opacity` to `1`. Once more, we use our `tl` instance and the `to` method.

```jsx
tl.to("#letters path", 3, { "fill-opacity": 1 });
```

And that’s that! Our LogRocket animation is now complete — not too bad, eh?

![LogRocket Logo Animation Complete](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2019/10/logrocket-animation-complete.gif?resize=504%2C144&ssl=1)

You can see the power of `TimelineMax` here. Normally, to run animations sequentially, you would have to use delays, but `TimelineMax` takes care of this for us.

The complete CodeSandbox can be found below.

{% codesandbox i9hjg %}

## Conclusion

So that’s all, folks. This was definitely more of an introduction to GreenSock than it was to React Hooks, but I hope you learned something about both. The guys at GreenSock have put in a massive amount of work for their library, so be sure to go even further with it to create great animations.
* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/animations-react-hooks-greensock/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *

The post [Animations using React Hooks and GreenSock](https://blog.logrocket.com/animations-react-hooks-greensock/) appeared first on [LogRocket Blog](https://blog.logrocket.com).