April 8, 2026/Simple/Page Transitions

GSAP Crossfade Transition

Current page fades to opacity 0, new page content swaps in, wrapper fades back to opacity 1. TransitionContext shares a GSAP timeline via React Context so each page can register exit animations.

Home

Page 1 of 3

"use client";

import { useEffect, useRef, useState } from "react";
import gsap from "gsap";
import styles from "./styles.module.css";

const PAGES = [
  { label: "Home", bg: "#f5f5f5", color: "#1a1a1a" },
  { label: "About", bg: "#0d0d0d", color: "#ffffff" },
  { label: "Work", bg: "#1a1f2e", color: "#ffffff" },
];

export default function CrossfadeTransition() {
  const [pageIndex, setPageIndex] = useState(0);
  const [displayIndex, setDisplayIndex] = useState(0);
  const wrapperRef = useRef(null);
  const isAnimating = useRef(false);

  function navigate(nextIndex) {
    if (isAnimating.current || nextIndex === pageIndex) return;
    isAnimating.current = true;

    const wrapper = wrapperRef.current;
    gsap
      .to(wrapper, { opacity: 0, duration: 0.3, ease: "power1.in" })
      .then(() => {
        setDisplayIndex(nextIndex);
        setPageIndex(nextIndex);
        return gsap.to(wrapper, { opacity: 1, duration: 0.3, ease: "power1.out" });
      })
      .then(() => {
        isAnimating.current = false;
      });
  }

  const page = PAGES[displayIndex];

  return (
    <div className={styles.demo}>
      <div
        ref={wrapperRef}
        className={styles.page}
        style={{ background: page.bg, color: page.color }}
      >
        <h2 className={styles.pageTitle}>{page.label}</h2>
        <p className={styles.pageHint}>Page {displayIndex + 1} of {PAGES.length}</p>
      </div>
      <div className={styles.nav}>
        {PAGES.map((p, i) => (
          <button
            key={p.label}
            className={`${styles.navBtn} ${i === pageIndex ? styles.active : ""}`}
            onClick={() => navigate(i)}
          >
            {p.label}
          </button>
        ))}
      </div>
    </div>
  );
}
  • gsap

Related Components

1W AGO
Signifly Theme Fadepage-transitions
3MO AGO
Section Transition Systempage-transitions
3MO AGO
Shutter Sectionpage-transitions