Recreating the StateOfJS Survey Animation Part 2
Tags: javascript, gsap, react
Published: 2018-12-06 17:50:37

---
title: Recreating the StateOfJS Survey Animation Part 2
published: true
description: Part 2 of my series recreating the 2018 State of JS animation   
tags: javascript, gsap, react
---

This is part 2 of my attempt to recreate the [2018 State of JS Animation](https://2018.stateofjs.com/). Part 1 can be found [here](https://dev.to/ryan_dunton/recreating-the-stateofjs-survey-animation-5ca9)

[A look at my finished attempt](https://state-of-js-animation-rgd.herokuapp.com/).

When we left off I had a page that looked like this:

![components](https://thepracticaldev.s3.amazonaws.com/i/vdya8h0m828ym53ufca9.png)

And each `Letter` component has the following state which runs on mount

```javascript
this.setState({
      minTop: -offsetTop - margin,
      maxTop: windowHeight - elementHeight + margin - offsetTop,
      maxRight: windowWidth - elementX - (elementWidth - margin),
      minLeft: -offsetLeft - margin,
      animationType,
      currentLeftOrRight,
      currentTopOrBottom
    });
```

Now that each component knows its minTop, maxTop, maxRight, minLeft and the animationType we can make the animation function.

Since we are using GreenSock's TweenLite we can move to a new x,y coordinate, we just have to get the coordinates. We can get the coordinates with a simple switch statement and give it random opposite coordinates within the max/min range.

```javascript
const getNewCoordinates = (minTop, maxTop, minLeft, maxRight, currentSide) => {
  let xDirection, yDirection, x, y;
  // alternate sides
  switch (currentSide) {
    case "left":
      xDirection = "right";
      x = maxRight;
      y = Math.random() * maxTop + minTop;
      break;
    case "right":
      xDirection = "left";
      x = minLeft;
      y = Math.random() * maxTop + minTop;
      break;
    case "top":
      yDirection = "bottom";
      x = Math.random() * minLeft + maxRight;
      y = minTop;
      break;
    case "bottom":
      yDirection = "top";
      x = Math.random() * minLeft + maxRight;
      y = maxTop;
      break;
    default:
      break;
  }
  return { x, y, xDirection, yDirection };
};
```

So now we pass that information to a tween animation that updates state but and viola! We have letters moving around the screen and call a `flipAnimation` function that just changes the `animationType` from "x" to "y" and refires the animation at the end of each animation.

```javascript
moveAnimation = () => {
    this.animation = TweenLite.to(
      this.letterElement,
      this.state.animationTime,
      {
        x: this.state.x,
        y: this.state.y,
        ease: Linear.easeNone,
        onComplete: this.flipAnimation
      }
    );
  };
``` 

So now we have letters moving around the screen, all we need to do is get them to "go home" on hover.

![go home](https://thepracticaldev.s3.amazonaws.com/i/6945xvhebanmi6j50dve.jpg)

We know from Greensock that the 'home' location is `x:0,y:0`. So we call a function when the `App` home state is set to true that moves all the `Letters` to 0,0 and give it a faster `animationTime` for a cool little effect.

```javascript
returnToHome = () => {
    if (this.state.x !== 0) {
      this.setState({
        x: 0,
        y: 0,
        animationTime: 0.5,
        endAnimation: true
      });
    }
  };
```

The only tricky part left is "restarting" the animations on end of hover. We can check if our `this.props.isHome` equals false and the `this.state.endAnimation` equals true. Which means the user is no longer hovering but the component is not animating yet, so we call the animation.

```javascript
if (!this.props.isHome && this.state.endAnimation) {
      this.setState({
        endAnimation: false
      });
      this.flipAnimation();
    }
```

Boom! Now we have a passable prototype. I still need to add resize functions and some mobile compatibility but other than that it is ready for the world.

Obviously I blew through some steps but the full code can be found on [Github](https://github.com/dunton/state-of-js-animation-recreate).

Integrating React and Greensock was suprisingly easy and I hope to do it again!