Next.js · GSAP · SplitText · Glassmorphism

글래스모피즘 스크롤 쇼케이스


Overview

300vh 높이의 섹션에서 스크롤 진행률에 따라 단어별 순차 등장(word reveal)과 글래스모피즘 구체가 슬라이드인하는 인터랙션을 구현한 프로젝트입니다.

GSAP SplitText로 heading을 단어 단위로 분할하고, rangeProgress 유틸 함수로 각 애니메이션의 시작~종료 구간을 독립적으로 제어합니다. CSS 키프레임 애니메이션과 GSAP 스크롤 연동을 조합하여 정적인 요소 없이 모든 영역이 살아 움직이는 섹션을 설계했습니다.

Anatomy

UI 해부도

300vh 섹션은 텍스트 영역과 글래스모피즘 구체로 좌우 분할됩니다. SplitText가 heading을 단어 단위로 분할하고, 스크롤 진행률에 따라 순차적으로 reveal됩니다.

Scroll Motion
5 Sections
GSAP
Label
대문자 추적 섹션 라벨
Heading
SplitText words · 순차 reveal
Body Text
설명 + 소형 텍스트 페이드인
Gradient Orb
글래스모피즘 구체 · 슬라이드인
Float Orbs
3개 장식 구체 · CSS 부유
FloatingShapes
16개 도형 · 대각선 이동

Structure

프로젝트 아키텍처

SectionShowcase는 텍스트 분할 · 스크롤 연동 · 장식 효과를 각각 독립된 모듈로 분리합니다. 글로벌 CSS 클래스와 GSAP 플러그인이 핵심 인터랙션을 담당합니다.

components/SCROLL
section/1
SectionShowcase.tsx
300vh 섹션 · word reveal · orb 슬라이드
text/1
SplitText (GSAP)
heading → words 분할 · 순차 reveal
effects/2
FloatingShapes.tsx
16개 도형 · 대각선 이동 + 스크롤 연동
BgOrbs.jsx
showcase 프리셋 배경
styles/1
globals.css
scatter-section · scatter-sticky · gradient-text 클래스

Data Flow

컴포넌트 데이터 플로우

데이터는 Setup → Scroll → Render 단방향으로 흐릅니다. ScrollTrigger가 스크롤 progress를 전달하면 각 업데이트 함수가 독립적으로 요소를 제어합니다.

SETUP
SplitText wordsset opacity: 0orb: hidden
SCROLL
ScrollTrigger scrub:1updateWordReveal()updateTextFade()updateOrbSlideIn()
RENDER
word opacity 순차body y+fadeorb scale+x

ANIMATION OUTPUT

Heading
단어 reveal
per-word opacity 0→1 순차
Body
텍스트 페이드
y: 30→0 + opacity
Orb
슬라이드인
x: 120→0 + scale 0.85→1
FloatingShapes
대각선 이동
diagonal 600px + scrub

Timeline

애니메이션 타임라인

스크롤 0%~100% 구간에서 5개의 애니메이션 레이어가 병렬로 동작합니다. rangeProgress 유틸로 각 레이어의 활성 구간을 독립적으로 제어합니다.

0%20%40%60%80%100%
Word Reveal
Text FadeIn
Orb SlideIn
FloatingShapes
CSS Float
heading 단어별 순차 페이드인 (각 단어 10% 범위)
body 텍스트 y:30→0 + opacity 0→1
orb x:120→0 + scale 0.85→1 + opacity 0→1
16개 도형 대각선 600px 이동
3개 장식 orb floatUp 무한 애니메이션

Interaction

인터랙션 플로우

스크롤 이벤트가 발생하면 SplitText 초기화 → Word Reveal과 Orb Animation 두 갈래로 분기됩니다. 리사이즈 시에는 SplitText를 안전하게 재초기화하여 레이아웃 깨짐을 방지합니다.

SCROLL EVENT
Setup PhaseINIT
  1. 1

    SplitText.create → words 배열 생성

    type: "words"
  2. 2

    모든 word 요소 opacity: 0으로 초기화

  3. 3

    orb 요소 hidden 상태 (x: 120, scale: 0.85)

Word RevealPER-WORD
  1. 1

    단어별 threshold 계산

    idx / totalWords
  2. 2

    fadeRange 0.1 구간 설정

    rangeProgress(p, threshold, +0.1)
  3. 3

    순차적으로 opacity 0→1 적용

Orb AnimationSLIDE-IN
  1. 1

    rangeProgress(0.15, 0.4) 계산

    progress → 0~1
  2. 2

    scale + x + opacity 보간

  3. 3

    x: 120→0, scale: 0.85→1

    opacity: 0→1
resize event detected?
SplitText 재초기화revert → 200ms debounce → re-setup
스크롤 업데이트 계속현재 progress 기반 애니메이션 유지

Patterns

핵심 기술 패턴

단순히 모션이 예쁜 것이 아니라, 스크롤 기반 인터랙션의 핵심 패턴을 체계적으로 설계했습니다. 범위 매핑 유틸 · 리사이즈 안전 처리 · CSS+GSAP 혼합까지 — 실무에서 바로 적용할 수 있는 패턴입니다.

Word Reveal
단어별 순차 등장
SplitText words에 인덱스 기반 임계값을 설정하여 스크롤에 따라 한 단어씩 순차적으로 opacity가 올라가는 타이핑 효과
wordThreshold = idx / totalWords fadeRange = 0.1
Range Progress
범위 매핑 유틸
스크롤 progress를 start~end 범위 안에서 0~1로 정규화하는 유틸 함수 — 복수 애니메이션의 타이밍 분리에 활용
rangeProgress(progress, start, end) if (p < start) return 0
Glassmorphism Orb
글래스모피즘 구체
200% backgroundSize 그라디언트 + radial-gradient 오버레이 + backdrop-blur 20px로 고급 유리 질감 구현
background-size: 200% 200% animation: gradientShift 6s infinite
Resize Safety
리사이즈 안전 처리
SplitText는 DOM을 변형하므로 리사이즈 시 revert() → 200ms debounce → 재생성으로 레이아웃 깨짐 방지
outroHeaderSplit.revert() mainST.kill() setupAnimation()
CSS Animations
CSS 무한 애니메이션
장식 orb에 CSS floatUp 키프레임으로 무한 부유 — GSAP과 별도로 동작하여 스크롤과 독립적인 생동감 부여
animation: floatUp 4s ease-in-out infinite
Diagonal Shapes
대각선 도형 이동
FloatingShapes를 스크롤 scrub에 연동하여 대각선 600px 이동 — 배경에 역동적인 깊이감 추가
diagonal={600} scrubStart='top bottom'

Responsive

반응형 전략

데스크탑 퍼스트로 설계하고 max-xl · max-md 2단계 브레이크포인트만 사용합니다. 모바일에서는 orb 영역을 숨기고 텍스트 중심의 세로 레이아웃으로 전환합니다.

Desktop1280px+
  • 좌우 flex 레이아웃
  • heading word reveal
  • 글래스모피즘 orb 표시
  • FloatingShapes 16개
  • 장식 orb 3개 부유
Tabletmax-xl~1280px
  • 좌우 레이아웃 유지
  • 패딩 축소 (px-20)
  • 텍스트 크기 조정
  • orb 크기 축소 (80×80)
  • 간격 축소 (gap-12)
Mobilemax-md~768px
  • 세로 스택 레이아웃
  • orb 영역 숨김 (hidden)
  • 텍스트 중앙 정렬
  • 폰트 사이즈 축소
  • 좌우 패딩 축소 (px-6)