Instructions

Code Documentation – GSAP + IntersectionObserver Highlight System

Code Documentation

This script highlights a category item (.project-category) based on which project card (.project-card-cms) is currently visible in the viewport. The highlight effect is done using GSAP animations for smooth color transitions.

1. GSAP Import

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>

Loads the GSAP animation library from CDN.

Required for animating the text color.

2. DOM Ready Event

document.addEventListener("DOMContentLoaded", () => {

Ensures the script runs only after the HTML content has fully loaded.

3. Collect All Category Elements

document.addEventListener("DOMContentLoaded", () => {
  • Selects all elements inside .project-category-list-item with class .project-category.
  • These are the category items that will be highlighted.

4. Default Highlight on Page Load

if (allItems.length > 0) {
  gsap.to(allItems, { color: "gray", duration: 0.3, ease: "power2.out" });
  gsap.to(allItems[0], { color: "black", duration: 0.5, ease: "power2.out" });
}
  • Sets all categories to gray.
  • Highlights the first category in black when the page loads.
  • Uses GSAP for a smooth transition.

5. Intersection Observer Options

const observerOptions = {
  root: null,       // Uses viewport as the container
  threshold: 0.5,   // Element must be 50% visible to trigger
};
  • Defines the conditions for when a project card is considered “visible.”

6. Function: Highlight Category

const highlightCategory = (projectName) => {
  gsap.to(allItems, { color: "gray", duration: 0.3, ease: "power2.out" });

  document.querySelectorAll(".project-category-list-item").forEach((item) => {
    if (item.getAttribute("data-project-title") === projectName) {
      const category = item.querySelector(".project-category");
      if (category) {
        gsap.to(category, {
          color: "black",
          duration: 0.5,
          ease: "power2.out",
        });
      }
    }
  });
};
  • Resets all categories to gray.
  • Finds the category whose data-project-title matches the currently visible project’s data-project-card.
  • Animates that category to black.

7. Intersection Observer Setup

const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      const projectName = entry.target.getAttribute("data-project-card");
      if (projectName) {
        highlightCategory(projectName);
      }
    }
  });
}, observerOptions);
  • Observes project cards entering the viewport.
  • When a card is at least 50% visible, its related category is highlighted.

8. Attach Observer to Each Project Card

document.querySelectorAll(".project-card-cms").forEach((card) => {  observer.observe(card);});
  • Applies the observer to all .project-card-cms elements.
  • Each card must have a data-project-card attribute that matches a data-project-title on a category item.