Terminal
1npm install next-transition-router gsap
Organic flowing transition using SVG displacement filters. Content melts and reforms creating a surreal, dream-like effect. Perfect for artistic experiences.
npm install next-transition-router gsapfeTurbulence + feDisplacementMapscale attribute: 0 → 50 → 01npm 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 LiquidProvider({ children }: { children: React.ReactNode }) {8 const wrapperRef = useRef<HTMLDivElement>(null)9 const overlayRef = useRef<HTMLDivElement>(null)1011 return (12 <>13 {/* SVG Filter for liquid effect */}14 <svg style={{ position: 'absolute', width: 0, height: 0 }}>15 <defs>16 <filter id="liquid-filter">17 <feTurbulence18 type="fractalNoise"19 baseFrequency="0.01"20 numOctaves="1"21 result="noise"22 />23 <feDisplacementMap24 in="SourceGraphic"25 in2="noise"26 scale="0"27 xChannelSelector="R"28 yChannelSelector="G"29 />30 </filter>31 </defs>32 </svg>3334 <TransitionRouter35 auto36 leave={(next) => {37 const tl = gsap.timeline({ onComplete: next })38 const displacementMap = document.querySelector('#liquid-filter feDisplacementMap')3940 // Animate displacement for liquid distortion41 tl.to(displacementMap, {42 attr: { scale: 50 },43 duration: 0.4,44 ease: 'power2.in',45 })4647 tl.to(overlayRef.current, {48 opacity: 1,49 duration: 0.3,50 }, '-=0.2')51 }}52 enter={(next) => {53 const tl = gsap.timeline({ onComplete: next })54 const displacementMap = document.querySelector('#liquid-filter feDisplacementMap')5556 gsap.set(displacementMap, { attr: { scale: 50 } })5758 tl.to(overlayRef.current, {59 opacity: 0,60 duration: 0.3,61 })6263 tl.to(displacementMap, {64 attr: { scale: 0 },65 duration: 0.4,66 ease: 'power2.out',67 }, '-=0.2')68 }}69 >70 <div ref={wrapperRef} style={{ filter: 'url(#liquid-filter)' }}>71 {children}72 </div>73 </TransitionRouter>7475 <div ref={overlayRef} style={{76 position: 'fixed',77 inset: 0,78 background: '#0a0a0a',79 zIndex: 9999,80 opacity: 0,81 pointerEvents: 'none',82 }} />83 </>84 )85}