랜딩 인트로에서 흔히 보는 "여러 화면을 스크롤로 넘기는" 경험을, 페이지를 진짜로 갈아끼우지 않고 한 sticky 위에서 안무로만 처리하고 싶었습니다. 섹션을 늘릴수록 DOM이 깊어지는 대신, 단일 progress 위에서 phase 윈도우만 추가하면 시퀀스가 자라는 구조를 노렸습니다.
구현 포인트
- 외부에 600vh 컨테이너 + 내부 sticky h-screen으로 "한 화면이 멈춰서 안무하는" 무대를 만든다.
- 모든 안무는 useScrollProgress({ mode: "sticky" })가 주는 단일 progress 0~1 위에서 파생. phase별로 [from,to] 윈도우만 갖고 mapRange(progress, from, to, 0, 1)로 로컬값을 계산.
- 카운팅은 cubic ease-out으로 progress 숫자 변환. 스크롤 위치가 곧 카운트값이라 빨리 스크롤하면 빨리, 천천히 스크롤하면 천천히 차오른다.
알아둘 점 (gotcha)
- 내부 sticky는 부모가 overflow-hidden이면 sticky가 깨진다 외부 컨테이너에는 overflow를 걸지 않았다.
- iframe 임베드 시 sticky가 사용자 viewport가 아니라 iframe viewport 기준으로 동작 data-demo-embed-fixed 고정 높이로 전환해 iframe 내부 스크롤로 안무가 정상 재생되도록 함.
- phase 윈도우가 겹치면 두 phase가 동시에 보이며 cross-fade가 된다. 의도해서 0.30~0.32 같은 짧은 겹침을 둠.
실무 활용 예시
- 제품 소개 랜딩의 "왜 / 무엇을 / 어떻게" 인트로 시퀀스
- 캠페인 페이지의 풀스크린 스토리텔링 인트로