03Block Reveal

Block Reveal

GSAPDramaticPortfolio#next-transition-router

Wipe effect known from films and portfolios. A solid overlay moves across the screen, covering old content and revealing new. GSAP Timeline allows for precise sequencing.

Quick Start

  • 📦npm install next-transition-router gsap
  • 🔧Create overlay element + GSAP Timeline for sequenced animations
  • ⚡Use gsap.fromTo() for predictable initial states
  • ✅transformOrigin controls wipe direction

Installation

Terminal
1npm install next-transition-router gsap

Provider Setup

app/providers.tsx
1'use client'
2
3import { useRef } from 'react'
4import { TransitionRouter } from 'next-transition-router'
5import gsap from 'gsap'
6
7export default function GSAPProvider({
8 children,
9}: {
10 children: React.ReactNode
11}) {
12 const overlayRef = useRef<HTMLDivElement>(null)
13 const wrapperRef = useRef<HTMLDivElement>(null)
14
15 return (
16 <>
17 <TransitionRouter
18 auto
19 leave={(next) => {
20 const tl = gsap.timeline({ onComplete: next })
21 const content = wrapperRef.current?.querySelectorAll('h1, p, .btn, .demo-badge')
22
23 tl.to(content, {
24 y: -40,
25 opacity: 0,
26 stagger: 0.04,
27 duration: 0.35,
28 ease: 'power3.in',
29 })
30
31 tl.fromTo(
32 overlayRef.current,
33 { scaleY: 0, transformOrigin: 'bottom' },
34 { scaleY: 1, duration: 0.5, ease: 'power4.inOut' },
35 '-=0.1'
36 )
37 }}
38 enter={(next) => {
39 const tl = gsap.timeline({ onComplete: next })
40 const content = wrapperRef.current?.querySelectorAll('h1, p, .btn, .demo-badge')
41
42 gsap.set(content, { y: 50, opacity: 0 })
43
44 tl.fromTo(
45 overlayRef.current,
46 { scaleY: 1, transformOrigin: 'top' },
47 { scaleY: 0, duration: 0.5, ease: 'power4.inOut' }
48 )
49
50 tl.to(content, {
51 y: 0,
52 opacity: 1,
53 stagger: 0.06,
54 duration: 0.5,
55 ease: 'power3.out',
56 }, '-=0.2')
57 }}
58 >
59 <div ref={wrapperRef}>{children}</div>
60 </TransitionRouter>
61
62 <div
63 ref={overlayRef}
64 style={{
65 position: 'fixed',
66 inset: 0,
67 background: '#0a0a0a',
68 zIndex: 9999,
69 transform: 'scaleY(0)',
70 }}
71 />
72 </>
73 )
74}