Animated Page Transitions
Smooth page transition effects using GSAP. Includes wipe, fade, slide, and dynamic curtain effects that trigger on route changes, alongside elegant loading states.
Create smooth, immersive page transition effects (app routing simulation) using GSAP. This snippet demonstrates four premium transition styles: wipe reveal, smooth fade, slide up, and dynamic curtain, seamlessly integrating loading states to handle layout rendering or network delays.
HTML Structure
Here is a simplified structure simulating a Single Page Application (SPA). The main content areas (.page) sit within a container, controlled by navigation links. We also prepare the overlay elements and a loading spinner.
<div class="app-container">
<nav class="nav-links">
<button class="nav-link active" data-target="home">Home</button>
<button class="nav-link" data-target="about">About</button>
</nav>
<!-- Overlays for Transitions -->
<div class="transition-overlay overlay-wipe" id="overlay-wipe"></div>
<div class="transition-overlay overlay-curtain" id="overlay-curtain">
<div class="curtain-panel"></div>
<div class="curtain-panel"></div>
<div class="curtain-panel"></div>
<div class="curtain-panel"></div>
</div>
<div class="loading-indicator" id="loading-indicator">
<div class="spinner"></div>
<span>Loading</span>
</div>
<div class="page-container">
<div class="page active" id="page-home">
<h1>Home Page</h1>
</div>
<div class="page" id="page-about">
<h1>About Us</h1>
</div>
</div>
</div>
CSS: Styling the Overlays & Loader
Ensure that .page-container and individual .page elements are positioned correctly (absolute overlapping). The overylays cover the entire screen during transitions.
.page-container {
position: relative;
overflow: hidden;
}
.page {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
visibility: hidden;
opacity: 0;
}
.page.active {
visibility: visible;
opacity: 1;
}
.transition-overlay {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 50;
visibility: hidden;
}
.overlay-wipe {
background-color: #1a1a24;
transform: translateY(100%);
}
.overlay-curtain {
display: flex;
}
.curtain-panel {
flex: 1;
background-color: #1a1a24;
transform: scaleY(0);
transform-origin: top;
}
.loading-indicator {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
z-index: 60;
opacity: 0;
visibility: hidden;
}
GSAP Animation Logic
Use the GSAP timeline API (gsap.timeline) to chain the transition steps. The process typically goes:
- Show overlay blocking the screen.
- Show loading spinner briefly.
- Switch underlying
.pagevisibility. - Hide overlay and loader, then reveal the incoming page contents.
const tl = gsap.timeline();
// Example: Wipe Transition
function wipeTransition(fromPage, toPage) {
gsap.set('#overlay-wipe', { visibility: 'visible', y: '100%'} );
tl.to('#overlay-wipe', { y: '0%', duration: 0.6, ease: 'power4.inOut' })
.to('#loading-indicator', { autoAlpha: 1, duration: 0.2 }, "-=0.2") // Show Loader
.call(() => {
fromPage.classList.remove('active');
toPage.classList.add('active');
gsap.set(toPage, { autoAlpha: 1 });
})
.to('#loading-indicator', { autoAlpha: 0, duration: 0.2 }, "+=0.3") // Hide Loader
.to('#overlay-wipe', { y: '-100%', duration: 0.6, ease: 'power4.inOut' })
.set('#overlay-wipe', { visibility: 'hidden' });
}
// Example: Curtain Transition
function curtainTransition(fromPage, toPage) {
gsap.set('#overlay-curtain', { visibility: 'visible' });
tl.to('.curtain-panel', { scaleY: 1, transformOrigin: 'top', stagger: 0.1, duration: 0.5, ease: 'power3.inOut' })
.to('#loading-indicator', { autoAlpha: 1, duration: 0.2 })
.call(() => switchPages(fromPage, toPage))
.to('#loading-indicator', { autoAlpha: 0, duration: 0.2 }, "+=0.3")
.to('.curtain-panel', { scaleY: 0, transformOrigin: 'bottom', stagger: 0.1, duration: 0.5, ease: 'power3.inOut' })
.set('#overlay-curtain', { visibility: 'hidden' });
}
Each transition guarantees smooth visual continuity and gives developers complete control over pre-fetching data routing logic underneath the animations.