Terminal
1npm install next-transition-router gsap
3D rotation effect around the Y-axis using CSS perspective. Page 'rotates' like a card, revealing new content. Ideal for flashcards, quizzes, and before/after comparisons.
npm install next-transition-router gsapperspective: 1500pxrotateY for horizontal card fliptransformStyle: 'preserve-3d' for child depth1npm install next-transition-router gsap
1'use client'23import { useRef } from 'react'4import { TransitionRouter } from 'next-transition-router'5import gsap from 'gsap'67export default function FlipProvider({ children }: { children: React.ReactNode }) {8 const wrapperRef = useRef<HTMLDivElement>(null)910 return (11 <div style={{ perspective: '1500px', perspectiveOrigin: 'center center' }}>12 <TransitionRouter13 auto14 leave={(next) => {15 const tl = gsap.timeline({ onComplete: next })16 const wrapper = wrapperRef.current17 const content = wrapper?.querySelectorAll('h1, p, .btn, .demo-badge')1819 tl.to(content, {20 opacity: 0,21 rotateY: -10,22 z: -50,23 stagger: 0.03,24 duration: 0.3,25 ease: 'power2.in',26 })2728 tl.to(wrapper, {29 rotateY: -95,30 scale: 0.95,31 opacity: 0,32 duration: 0.5,33 ease: 'power4.in',34 transformOrigin: 'center center',35 }, '-=0.15')36 }}37 enter={(next) => {38 const tl = gsap.timeline({ onComplete: next })39 const wrapper = wrapperRef.current40 const content = wrapper?.querySelectorAll('h1, p, .btn, .demo-badge')4142 gsap.set(wrapper, { rotateY: 95, scale: 0.95, opacity: 0 })43 gsap.set(content, { opacity: 0, rotateY: 15, z: -30 })4445 tl.to(wrapper, {46 rotateY: 0,47 scale: 1,48 opacity: 1,49 duration: 0.55,50 ease: 'power4.out',51 transformOrigin: 'center center',52 })5354 tl.to(content, {55 opacity: 1,56 rotateY: 0,57 z: 0,58 stagger: 0.05,59 duration: 0.4,60 ease: 'power3.out',61 }, '-=0.3')62 }}63 >64 <div ref={wrapperRef} style={{ transformStyle: 'preserve-3d' }}>65 {children}66 </div>67 </TransitionRouter>68 </div>69 )70}