Animation Finds for React
Tags: javascript, react, gsap, beginners
Published: 2022-06-02 17:28:29

I've been working on a recipe saver app in React and using it to learn how to implement different animations with GSAP. These are the animations I've learned so far and how to do them. Some also include the tutorials I've found for them.

- Horizontally moving title into place

- Fading page in

- Loading screen

- Horizontally scroll through images

- Using ScrollTrigger to move images from left and right

## Using GSAP in React 

1: Install GSAP into React.
`npm i gsap`

2: Import GSAP at the top of the page.
`import { gsap } from "gsap";`

3: In Index.js, I removed the lines with strict mode in order for the animations to work.

```
  <React.StrictMode>
  </React.StrictMode>
```

4: Add the hooks you are using
`import { useEffect, useState } from "react";`

## Horizontal Movement
This will make the title move into place from the right whenever the page is started. This will be done in Home.js.

1: In the return section, create an h1 tag with the page title and an id. That id is what I used for the tween.

```
return (
   <h1 id="homeTitle">Home</h1>
```

2: Before the return, create a useEffect() hook

```
useEffect(() =>
  {
  }, [])
```

3: In useEffect(), create a tween with the "homeTitle" id. This will make the title move into place from 50 pixels to the right.

`gsap.from("#homeTitle", {x: 50, duration: 1})`


## Page Fade In
This will fade in the page when the app is started. This will all be done in App.js.

1: In the return section, I put a div with a class. That class is what I used for the tween. The contents of the entire page will go into this div.

```
return (
   <div className="homePage">
   </div>
```

2: Before the return, create a useEffect() hook

```
 useEffect(() =>
  {
  }, [])
```

3: In useEffect(), create a tween with the "homePage" class. If you would like the fade to be longer, change the duration to a higher number. This tween is starting _from_ the opacity of 0 so it will fade in from blank.

`gsap.from(".homePage", {duration: 1, opacity: 0});`

## Loading
To find out one way to make a loading screen, I followed this easy to follow [tutorial](https://www.youtube.com/watch?v=SR8755C0bME) on YouTube by Tony Heimark. He used the package, [react-spinners](https://www.npmjs.com/package/react-spinners).

You can make this loading screen as long as it takes to load your data. My data is 5 very simple recipes so I put it in a setTimeout hook to see it more as Heimark shows. This will all be done in App.js.

**Using react-spinners**
1: Install the package.
`npm install --save react-spinners`

2: Find which loader you like on the [demo page](https://www.davidhu.io/react-spinners/). I chose SyncLoader.

3: At the top of App.js import your loader.
`import SyncLoader from "react-spinners/SyncLoader";`

**Before the return**
1: Create a state that shows whether "loading" is true or false.
`const [loading, setLoading] = useState(false);`

2: Create a useEffect() hook underneath the loading state.
```
 useEffect(() =>
  {
  }, [])
```

3: In useEffect(), set loading to be true. 
`setLoading(true)`

4: In the useEffect() after setting loading to true, add a setTimeout() hook. This is set to timeout after 5 seconds.

```
setTimeout(() =>
{
}, 5000)
```

5: In setTimeout() set loading to be false. After 5 seconds, loading will be set back to false.
`setLoading(false)`

**In the return**
1: Make a div that includes everything.

```
return (
   <div className="App">
```

2: In the "App" div, create a ternary expression with the loading state. 
`loading ? true : false`

3: Add the loader for when loading is true, and the page contents for when loading is false.
```
{loading 
   ? 
   <div id="loader">
      <SyncLoader color={"#FFB5D4"} loading={loading} size={30} />
   </div> 
   :
   <div className="homePage">
```

## ScrollTrigger: Horizontal scrolling
I watched this [video](https://www.youtube.com/watch?v=X7IBa7vZjmo) made by GSAP that explains the different parts of ScrollTrigger and what you can do. You can find a lot of different [examples](https://greensock.com/st-demos/) on their website. For horizontal scrolling, I followed this [example](https://codepen.io/GreenSock/pen/YzygYvM). Instead of sections, I used images.

**Home.js**
1: In return, add 3 images with the same class name. I won't include the image sources here to not take up too much space. Instead of images, you can use colored sections to see the movement also.
```
<img className="panel" src="" />
<img className="panel" src="" />
<img className="panel" src="" />
```

2: Before the return, create a useEffect() hook
```
 useEffect(() =>
  {
  }, [])
```

3: Add animation defaults to the top of the useEffect()
`gsap.defaults({ease: "none", duration: 2});`

4: Create an array with the panels
`let sections = gsap.utils.toArray(".panel");`

5: Create a tween that scrolls through the array horizontally

```
gsap.to(sections, {
   xPercent: -100 * (sections.length - 1),
   ease: "none",
   scrollTrigger: {
      trigger: ".cont",
      pin: true,
      scrub: 1,
      snap: 1 / (sections.length - 1),
      end: "+=3500",
   }
});
```

**App.css**
1: I made the image the size of the screen

```
.panel {
  height: 100vh;
  width: 100%;
}
```

## ScrollTrigger: Images from left and right
This will move an image from the left and another image from the right as you scroll. The other images will sit in place while the animated images move over them. This will be done in Home.js. 

**Home.js**
1: In return, add 6 images. I included a class for each image. I also made a box class that makes the dimensions.
```
<img className="imageA box" src="" />
<img className="imageB box" src="" />
<img className="imageC box" src="" />
<img className="imageD box" src="" />
<img className="imageE box" src="" />
<img className="imageF box" src="" />
```

2: Before the return, create a useEffect() hook
```
 useEffect(() =>
  {
  }, [])
```

3: Add animation defaults to the beginning of the useEffect()
`gsap.defaults({ease: "none", duration: 2});`

4: Create a tween with the horizontal movement. This will move the image into full view from the left.
`gsap.from(".imageA", {x: -1700})`

5: Inside the tween, create a scrollTrigger object. The _trigger_ point for when the image will start moving is when the top of the screen touches the top of the image. The image will be _pinned_ into place once the movement is done. The _scrub_ being true means the scroll will control where the image is at depending on how far you are scrolled. If the scrub was false, the image would animate and move on its own once it is triggered.
The entire tween will look like this:

```
gsap.from(".imageA", {
   scrollTrigger:
   {
      trigger: ".imageA",
      start: "top top",
      pin: true,
      scrub: true,
   }, x: -1700
})
```

6: I added another tween for moving another image. This will move an image from the right.

```
gsap.from(".imageD", {
   scrollTrigger:
   {
      trigger: ".imageD",
      start: "top top",
      pin: true,
      scrub: true,
   }, x: 1700
})
```

**App.css**
1. I made the image the size of the screen.

```
.box {
   height: 100vh;
   width: 100%;
}

```

2: For the animated images, I made the animated images have a position of absolute in order to move over the other images set in place.

```
.imageA {
  position: absolute;
}

.imageD {
  position: absolute;
}
```