logo

DowanKim

휘황찬란한 Pretext 데모, 직접 한번 구현해보자

2026년 4월 23일

일상

image.png

홈 화면 메인부분 부터 커리어 부분 까지, 마우스 인터랙션에 따라 글자들이 날라다니다가 마우스가 벗어나면 다시 돌아오는 효과를 적용하였습니다.

최근 아티클을 보며 pretext를 알게 되었고, 이를 적용한 pretext-playgrund 데모 사이트를 보며 그 이론과, 인터랙션 효과가 재밌어 보였습니다.


“흔들리는 텍스트”는 Pretext가 아니다

요즘 pretext-playground 같은 데모를 보면, 마우스에 반응해 글자가 살아 움직이는 효과가 정말 매력적입니다.

그런데 이걸 곧바로 “Pretext 구현”이라고 이해하면 방향이 살짝 틀어질 수 있습니다. 이번 글은 그 지점을 분리해서 정리한 글입니다.


1) 같은 “텍스트 UI”여도 목적이 다르다

Pretext(원래 문제의식)

Korean FE Article에서 짚듯이, Pretext의 핵심은

DOM 텍스트를 유지하면서도 텍스트 레이아웃/측정 비용을 줄이고, 접근성을 지키는 것에 가깝습니다.

즉 키워드는:

  • 성능(특히 텍스트가 많은 UI)
  • 예측 가능한 레이아웃
  • a11y 유지(실제 텍스트 노드)

Playground 스타일 데모

Pretext Playground에서 인상적인 부분은

시각 인터랙션(마우스 반발, 흔들림, 복귀 애니메이션) 입니다.

즉 :

  • 인터랙티브 모션
  • 실시간 프레임 루프
  • 물리 느낌(반발/감쇠/복귀)

둘 다 DOM 텍스트를 다룰 수는 있지만, 해결하려는 문제 자체가 다릅니다.


2) 어떻게 구현했나?

공개 데모 코드를 직접 해부하지 않더라도, 화면 결과만으로 구현 철학은 읽을 수 있습니다.

Playground 방식

  • requestAnimationFrame 기반의 프레임 루프
  • 포인터 좌표를 읽어 각 요소에 힘 계산
  • 요소 위치는 transform: translate3d(...) rotate(...)로 갱신
  • 감쇠/스프링 계수로 자연스러운 복귀 연출

핵심은 “텍스트를 성능 최적화 대상으로 본다”기보다 “텍스트를 움직이는 인터랙션 대상으로 본다”는 점입니다.


3) 내 구현

의도적으로 Playground 방식 을 택했습니다.

다만 구조는 실서비스 컴포넌트에 맞게 분리했습니다.

A. ScatterPhysicsZone

  • 포인터 상태(x, y, active)를 한 곳에서 관리
  • 구독 함수 집합(subsRef)을 매 프레임 호출
  • 루프는 requestAnimationFrame 자기 재귀로 지속
  • 정지 조건은 effect cleanup에서 cancelAnimationFrame

즉, 프레임 루프를 중앙집중형으로 1개만 운영합니다.

B. ScatterLetterText (글자)

  • 텍스트를 그래페음 단위로 분할(Intl.Segmenter)
  • 글자별 span에 대해 home(원위치), offset, velocity 관리
  • 매 프레임 스프링 복귀 + 포인터 반발 힘 계산
  • 결과를 각 span transform으로 반영

즉, 글자 하나하나가 독립된 작은 물체처럼 움직입니다.

C. ScatterBlock (이미지)

  • 글자 단위가 아닌 블록 단위(이미지/아이콘 묶음)로 동일 물리 적용
  • 중심점 기준으로 한 덩어리만 이동/회전

텍스트는 미세하게, 큰 오브젝트는 거칠게 연출합니다.

D. 적용 범위 제어

  • Zone 안(Home/About/Career)에만 효과 가능
  • 링크/버튼처럼 UX 우선인 요소에는 효과 미적용
  • 텍스트 강조 영역에만 ScatterLetterText를 선택적으로 배치

즉, “멋”보다 사용성 우선으로 범위를 잘라 썼습니다.


4) Pretext 의도와 다른점?

1) 목표가 “레이아웃 최적화”가 아니라 “브랜딩 인터랙션”이었기 때문

이번 구현의 목표는 최적화가 아닙니다.

마우스에 밀리고 다시 복귀하는 감성적인 타이포 모션.

그래서 Pretext의 본래 문제(텍스트 측정 최적화)보다

Playground가 보여준 감각을 제품에 맞춰 재해석하엿습니다. 다만 추후 최적화를 목표로 구현을 진행해보고자 합니다.

2) DOM 접근성과 실서비스 구조를 유지하고 싶었기 때문

  • 실제 텍스트를 DOM으로 유지
  • sr-only + aria-hidden 조합으로 읽기 경험 보완
  • prefers-reduced-motion 대응으로 모션 민감 사용자 배려

즉, 화려한 모션을 넣으면서도 웹 기본기(a11y + 사용자 설정 존중)를 놓치지 않았습니다.


5) 마지막으로…

  • Korean FE Article가 말하는 포인트는 타당합니다: Pretext의 본질은 화려한 흔들림 데모 그 자체가 아니다.
  • 그렇지만 Pretext Playground는 훌륭한 인터랙션 레퍼런스입니다.
  • 저는 Playground를 레퍼런스로 의도적으로 인터랙션에 집중했고, DOM/a11y/reduced-motion을 지키는 방향으로 실서비스형 구조로 구현했습니다.

“Pretext의 철학”과 “Playground의 연출”은 구분해서 보고, 이번엔 연출 목적에 맞게 구현했습니다