Day 5: Beginning My Animation Journey with GSAP

Saksham basnetSaksham basnet
4 min read

Today marks my fifth day of learning GSAP, and I decided to revise and combine all the concepts I've learned so far into a small project. This project includes text animations, custom cursors, SVG path animations, timeline controls, and scroll-triggered animations.

The Project Overview

The project features:

  • A heading with text animation that splits and animates from the middle.

  • A custom cursor that changes when hovering over an image.

  • An SVG path animation that responds to mouse movements.

  • A navigation menu that animates on click.

  • A scrolling text animation that changes direction and rotates based on scroll input.

The Code

Here's the complete code for the project:

//HTML and CSS
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>GSAP Project</title>
  <style>
    body {
      font-family: Arial, sans-serif;
    }
    h1 {
      text-align: center;
      margin-top: 50px;
    }
    .cursor {
      width: 20px;
      height: 20px;
      background-color: #000;
      border-radius: 50%;
      position: absolute;
      pointer-events: none;
      transition: transform 0.3s ease;
    }
    #image {
      width: 100px;
      height: 100px;
      background-color: red;
      margin: 50px auto;
    }
    #string {
      width: 100%;
      height: 200px;
      background-color: #f0f0f0;
    }
    #nav {
      position: fixed;
      top: 20px;
      right: 20px;
    }
    #full {
      position: fixed;
      top: 0;
      right: -100%;
      width: 100%;
      height: 100%;
      background-color: #333;
      color: #fff;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      transition: right 0.8s ease;
    }
    .marque {
      white-space: nowrap;
      overflow: hidden;
    }
    .marque img {
      display: inline-block;
      margin: 0 20px;
    }
  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
</head>
<body>

<h1>Hello, GSAP!</h1>
<div class="cursor"></div>
<div id="image"></div>
<div id="string"><svg width="1000" height="200"><path d="M 10 100 Q 500 100 990 100" stroke="black" stroke-width="2" fill="none" /></svg></div>
<div id="nav"><i>Menu</i></div>
<div id="full">
  <i>Close</i>
  <h3>Item 1</h3>
  <h3>Item 2</h3>
  <h3>Item 3</h3>
</div>
<div class="marque">
  <img src="https://via.placeholder.com/100" alt="Image 1">
  <img src="https://via.placeholder.com/100" alt="Image 2">
  <img src="https://via.placeholder.com/100" alt="Image 3">
</div>
//Javascript 

function breakText() {
    let h1 = document.querySelector("h1");
    let h1text = h1.textContent;
    let splited = h1text.split("");
    let halfValue = Math.floor(splited.length / 2);
    let clutter = "";
    splited.forEach(function (elem, idx) {
      if (idx < halfValue) {
        clutter += `<span class="a">${elem}</span>`;
      } else {
        clutter += `<span class="b">${elem}</span>`;
      }
    });
    h1.innerHTML = clutter;
  }
  breakText();
  gsap.from("h1 .a", {
    y: 50,
    duration: 0.6,
    delay: 0.5,
    stagger: 0.15,
    opacity: 0,
  });
  gsap.from("h1 .b", {
    y: 50,
    duration: 0.6,
    delay: 0.5,
    stagger: -0.15,
    opacity: 0,
  });

  // Day 2: Custom Cursor
  let crs = document.querySelector(".cursor");
  let main = document.querySelector("#main");
  let imgDiv = document.querySelector("#image");
  document.addEventListener("mousemove", function (e) {
    gsap.to(crs, {
      x: e.clientX,
      y: e.clientY,
      duration: 0.6,
    });
  });
  imgDiv.addEventListener("mouseenter", function () {
    crs.innerHTML = "View more";
    gsap.to(crs, {
      scale: 4,
      backgroundColor: "#ffffff74",
    });
  });
  imgDiv.addEventListener("mouseleave", function () {
    crs.innerHTML = "";
    gsap.to(crs, {
      scale: 1,
      backgroundColor: "#000",
    });
  });

  // Day 3: SVG Path Animation
  let initialValue = "M 10 100 Q 500 100 990 100";
  let finalValue = "M 10 100 Q 500 100 990 100";
  let string = document.querySelector("#string");
  string.addEventListener("mousemove", function (dets) {
    initialValue = `M 10 100 Q ${dets.clientX} ${dets.clientY} 990 100`;
    gsap.to("svg path", {
      attr: { d: initialValue },
      duration: 0.2,
      ease: "power3.out",
    });
  });
  string.addEventListener("mouseleave", function () {
    gsap.to("svg path", {
      attr: { d: finalValue },
      duration: 1,
      ease: "elastic.out(1, 0.2)",
    });
  });

  // Day 4: Navigation Menu Animation
  let navbar = document.querySelector("#nav i");
  let icon = document.querySelector("#full i");
  let tl = gsap.timeline();
  tl.to("#full", { right: 0, duration: 0.8 });
  tl.from("#full h3", {
    x: 150,
    duration: 0.5,
    stagger: 0.1,
    opacity: 0,
  });
  tl.from("#full i", { opacity: 0, x: 150 });
  tl.pause();
  navbar.addEventListener("click", function () {
    tl.play();
  });
  icon.addEventListener("click", function () {
    tl.reverse();
  });

  // Day 4: Scroll-Triggered Animation
  window.addEventListener("wheel", function (dets) {
    if (dets.deltaY > 0) {
      gsap.to(".marque", {
        transform: "translateX(-200%)",
        duration: 6,
        repeat: -1,
        ease: "none",
      });
      gsap.to(".marque img", { rotate: 180 });
    } else {
      gsap.to(".marque", {
        transform: "translateX(0%)",
        duration: 6,
        repeat: -1,
        ease: "none",
      });
      gsap.to(".marque img", { rotate: 0 });
    }
  });

Explanation

  1. Text Animation (Day 1):

    • The breakText function splits the text of the <h1> element into individual characters and wraps them in <span> elements with classes "a" and "b".

    • GSAP animates the characters from the bottom with a staggered effect, creating a dynamic text animation.

  2. Custom Cursor (Day 2):

    • The cursor follows the mouse movement using GSAP.

    • When hovering over the image, the cursor scales up and changes color, displaying "View more".

  3. SVG Path Animation (Day 3):

    • The SVG path animates based on the mouse position, creating a wavy line effect.

    • When the mouse leaves the SVG area, the path smoothly returns to its original shape.

  4. Navigation Menu Animation (Day 4):

    • A GSAP timeline animates the navigation menu when clicking the "Menu" icon.

    • The menu slides in, and its items fade and slide into view.

    • Clicking the "Close" icon reverses the animation, hiding the menu.

  5. Scroll-Triggered Animation (Day 4):

    • The text and images in the marquee element scroll horizontally based on the user's scroll direction.

    • The images rotate 180 degrees when scrolling down and revert to their original position when scrolling up.

Conclusion

Combining all the concepts from the first four days, I created a small project that showcases the versatility and power of GSAP. This project includes text animations, custom cursors, SVG path animations, timeline controls, and scroll-triggered animations, providing a rich interactive experience. I'm excited to continue exploring GSAP and creating more complex animations in the future!

0
Subscribe to my newsletter

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

Written by

Saksham basnet
Saksham basnet

I am a Frontend Developer From Nepal ꔪ