React Animation - GSAP

Code SubtleCode Subtle
7 min read

GSAP in React

Using GSAP (GreenSock Animation Platform) in React

GSAP (GreenSock Animation Platform) is a powerful animation library for JavaScript that works well with React. It allows you to create high-performance animations with ease.

Here's a step-by-step guide to using GSAP in React, along with some examples:

Step-by-Step Guide

1. Install GSAP

You can install GSAP in your React project using npm or yarn.

npm install gsap
# or
yarn add gsap

2. Import GSAP in Your Component

After installing GSAP, you can import the necessary modules in your React components.

import { gsap } from 'gsap';

3. Create References for Elements to Animate

In React, GSAP animations are typically applied to DOM elements. You can use the useRef hook to create a reference to the DOM element you want to animate.

import React, { useRef, useEffect } from 'react';
import { gsap } from 'gsap';

const MyComponent = () => {
  const boxRef = useRef(null);

  useEffect(() => {
    gsap.to(boxRef.current, { rotation: 360, duration: 2 });
  }, []);

  return (
    <div>
      <div ref={boxRef} style={styles.box}></div>
    </div>
  );
};

const styles = {
  box: {
    width: '100px',
    height: '100px',
    backgroundColor: 'red',
  },
};

export default MyComponent;

In this example:

  • boxRef is used to reference the div element.

  • GSAP rotates the element 360 degrees over 2 seconds.

GSAP Animation Example : GSAP Example 1

4. Controlling Animations with State

You can also trigger animations based on component state. For example, animating an element when a button is clicked.

import React, { useRef, useState } from 'react';
import { gsap } from 'gsap';

const MyComponent = () => {
  const boxRef = useRef(null);
  const [isAnimating, setAnimating] = useState(false);

  const animateBox = () => {
    gsap.to(boxRef.current, { x: isAnimating ? 0 : 200, duration: 1 });
    setAnimating(!isAnimating);
  };

  return (
    <div>
      <div ref={boxRef} style={styles.box}></div>
      <button onClick={animateBox}>Animate</button>
    </div>
  );
};

const styles = {
  box: {
    width: '100px',
    height: '100px',
    backgroundColor: 'red',
  },
};

export default MyComponent;

5. Using Timelines in GSAP

GSAP provides a Timeline feature to sequence animations. This allows multiple animations to run in succession.

import React, { useRef, useEffect } from 'react';
import { gsap, TimelineLite } from 'gsap';

const MyComponent = () => {
  const box1Ref = useRef(null);
  const box2Ref = useRef(null);
  const box3Ref = useRef(null);

  useEffect(() => {
    const tl = gsap.timeline();
    tl.to(box1Ref.current, { x: 100, duration: 1 })
      .to(box2Ref.current, { x: 100, duration: 1 })
      .to(box3Ref.current, { x: 100, duration: 1 });
  }, []);

  return (
    <div>
      <div ref={box1Ref} style={styles.box}></div>
      <div ref={box2Ref} style={styles.box}></div>
      <div ref={box3Ref} style={styles.box}></div>
    </div>
  );
};

const styles = {
  box: {
    width: '100px',
    height: '100px',
    backgroundColor: 'blue',
    marginBottom: '10px',
  },
};

export default MyComponent;

In this example:

  • The three boxes will move to the right sequentially, one after the other.

GSAP X TimeLine : Timeline GSAP code

6. Reversing Animations

You can reverse GSAP animations easily by calling .reverse() on the timeline or animation.

import React, { useRef, useEffect, useState } from 'react';
import { gsap } from 'gsap';

const MyComponent = () => {
  const boxRef = useRef(null);
  const [isReversed, setIsReversed] = useState(false);

  useEffect(() => {
    gsap.to(boxRef.current, { rotation: 360, duration: 2 });
  }, []);

  const toggleReverse = () => {
    const animation = gsap.to(boxRef.current, { rotation: 360, duration: 2 });
    if (isReversed) {
      animation.reverse();
    }
    setIsReversed(!isReversed);
  };

  return (
    <div>
      <div ref={boxRef} style={styles.box}></div>
      <button onClick={toggleReverse}>
        {isReversed ? 'Play' : 'Reverse'}
      </button>
    </div>
  );
};

const styles = {
  box: {
    width: '100px',
    height: '100px',
    backgroundColor: 'green',
  },
};

export default MyComponent;

Example Scenarios

Example 1: Fading in Elements

useEffect(() => {
  gsap.fromTo(boxRef.current, { opacity: 0 }, { opacity: 1, duration: 2 });
}, []);

This will animate the opacity of the boxRef element from 0 (invisible) to 1 (fully visible) over 2 seconds.

Example 2: Animating Multiple Elements

useEffect(() => {
  gsap.to(".box", { x: 100, stagger: 0.2, duration: 1 });
}, []);

Using the stagger property, GSAP will animate elements with the class box one after another with a 0.2-second delay between each.

Example 3: Using ScrollTrigger (GSAP Plugin)

npm install gsap@npm:@gsap/shockingly
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";

gsap.registerPlugin(ScrollTrigger);

useEffect(() => {
  gsap.to(boxRef.current, {
    x: 500,
    scrollTrigger: {
      trigger: boxRef.current,
      start: "top center",
      end: "bottom top",
      scrub: true,
    },
  });
}, []);

In this example, the ScrollTrigger plugin animates an element based on scroll position.

Key Concepts to Remember:

  1. References: Use useRef to reference DOM elements.

  2. useEffect: Use GSAP animations within the useEffect hook to ensure the DOM elements have been rendered.

  3. Timelines: Use gsap.timeline() to sequence multiple animations.

  4. Reversing: Use .reverse() to reverse animations easily.

Key GSAP Parameters and their Usage

  1. target (Required)

    • The element(s) to animate. In React, this is usually referenced using useRef.

    • Can be a single element, an array of elements, or a string selector (e.g., ".my-class").

    • Example:

        gsap.to(boxRef.current, { duration: 1, x: 100 });
      
  2. duration

    • Specifies how long the animation should take (in seconds).

    • Default: 0.5 seconds.

    • Example:

        gsap.to(boxRef.current, { duration: 2, x: 200 });
      
  3. x, y, z

    • Moves the element along the respective axis (in pixels).

    • Example:

        gsap.to(boxRef.current, { duration: 1, x: 300, y: 200 });
      
  4. opacity

    • Fades the element in or out by adjusting the opacity (between 0 and 1).

    • Example:

        gsap.to(boxRef.current, { duration: 1, opacity: 0.5 });
      
  5. scale, scaleX, scaleY

    • Scales the element (1 is default size).

    • Example:

        gsap.to(boxRef.current, { duration: 1, scale: 1.5 });
      
  6. rotation

    • Rotates the element in degrees (clockwise is positive, counter-clockwise is negative).

    • Example:

        gsap.to(boxRef.current, { duration: 1, rotation: 360 });
      
  7. ease

    • Controls the easing function, defining how the animation accelerates or decelerates.

    • Common values: "power1.in", "power2.out", "elastic", "bounce", "linear".

    • Example:

        gsap.to(boxRef.current, { duration: 1, x: 100, ease: "power3.out" });
      
  8. delay

    • Adds a delay (in seconds) before starting the animation.

    • Example:

        gsap.to(boxRef.current, { duration: 1, x: 200, delay: 0.5 });
      
  9. repeat

    • Defines how many times the animation should repeat.

    • Set -1 for infinite repetition.

    • Example:

        gsap.to(boxRef.current, { duration: 1, x: 100, repeat: 3 });
      
  10. yoyo

    • When set to true, the animation will reverse after reaching the end (useful with repeat).

    • Example:

        gsap.to(boxRef.current, 
        { duration: 1, x: 100, repeat: 2, yoyo: true });
      
  11. stagger

    • Animates multiple elements with a staggered delay.

    • Example:

        gsap.to(".box", { duration: 1, x: 100, stagger: 0.2 });
      
  12. onComplete, onStart, onUpdate

    • These are callbacks that fire at specific points in the animation lifecycle.

    • onComplete: Fires when the animation finishes.

    • onStart: Fires when the animation starts.

    • onUpdate: Fires every time the values are updated.

    • Example:

        gsap.to(boxRef.current, { 
          duration: 1, 
          x: 100, 
          onComplete: () => console.log("Animation Complete!") 
        });
      
  13. from vs to

    • GSAP has both gsap.from() and gsap.to() methods.

    • gsap.from() starts the animation from a set of initial values, animating to the element's current state.

    • gsap.to() animates from the current state to the provided values.

    • Example (from):

        gsap.from(boxRef.current, { duration: 1, opacity: 0 });
      
  14. paused

    • If set to true, the animation will start in a paused state and can be triggered later.

    • Example:

        const animation = gsap.to(boxRef.current, 
        { duration: 1, x: 100, paused: true });
        animation.play(); // Trigger it later
      

Example Usage in React

import React, { useRef, useEffect } from 'react';
import { gsap } from 'gsap';

const GsapComponent = () => {
  const boxRef = useRef(null);

  useEffect(() => {
    gsap.to(boxRef.current, {
      duration: 1,     // 1 second animation duration
      x: 100,          // Move 100px along the x-axis
      rotation: 360,   // Rotate 360 degrees
      scale: 1.5,      // Scale the element by 1.5 times
      ease: "power2.out",  // Smooth easing
      delay: 0.5,      // Delay of 0.5 seconds before starting
      repeat: 2,       // Repeat the animation 2 times
      yoyo: true,      // Reverse after each repeat
      onComplete: () => console.log("Animation Completed!"), 
      // Fires on completion
    });
  }, []);

  return <div ref={boxRef} 
    style={{ width: 100, height: 100, backgroundColor: 'blue' }}>
    Animate Me</div>;
};

export default GsapComponent;

Example: GSAP Random Animation in React

import React, { useEffect, useRef } from "react";
import { gsap } from "gsap";

const RandomBoxes = () => {
  const boxesRef = useRef([]);

  useEffect(() => {
    boxesRef.current.forEach((box) => {
      gsap.to(box, {
        x: gsap.utils.random(0, 500),  // Random position between 0 and 500px for x
        y: gsap.utils.random(0, 300),  // Random position between 0 and 300px for y
        backgroundColor: gsap.utils.random(["#ff0000", "#00ff00", "#0000ff"]), // Random color
        duration: 2,
        repeat: -1,
        yoyo: true
      });
    });
  }, []);

  return (
    <div style={containerStyle}>
      <div
        className="box"
        ref={(el) => (boxesRef.current[0] = el)}
        style={boxStyle}
      ></div>
      <div
        className="box"
        ref={(el) => (boxesRef.current[1] = el)}
        style={boxStyle}
      ></div>
      <div
        className="box"
        ref={(el) => (boxesRef.current[2] = el)}
        style={boxStyle}
      ></div>
    </div>
  );
};

const containerStyle = {
  display: "flex",
  justifyContent: "space-around",
  alignItems: "center",
  height: "100vh",
};

const boxStyle = {
  width: "100px",
  height: "100px",
  backgroundColor: "red",
};

export default RandomBoxes;
1
Subscribe to my newsletter

Read articles from Code Subtle directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Code Subtle
Code Subtle

At Code Subtle, we empower aspiring web developers through personalized mentorship and engaging learning resources. Our community bridges the gap between theory and practice, guiding students from basics to advanced concepts. We offer expert mentorship and write interactive, user-friendly articles on all aspects of web development. Join us to learn, grow, and build your future in tech!