Skip to content
Docs
Motion

페이지 레벨 모션 훅

stable

페이지 전체 요소의 입장 애니메이션을 선언적으로 관리하는 훅

Import

import {
  useSimplePageMotion,
  useCustomPageMotion,
  usePageMotions,
} from '@hua-labs/motion-core'

useSimplePageMotion

페이지 타입 프리셋(home, dashboard, product, blog)을 기반으로 페이지 내 여러 요소의 입장 애니메이션을 한 번에 설정한다. 3단계 추상화 중 1단계에 해당한다.

Signature

function useSimplePageMotion(
  pageType: PageType
): Record<string, PageMotionRef>

type PageType = 'home' | 'dashboard' | 'product' | 'blog'

interface PageMotionRef {
  ref: { current: HTMLElement | null }
  style: CSSProperties
  isVisible: boolean
  isHovered: boolean
  isClicked: boolean
}

지원 페이지 타입

타입포함 요소
homehero, title, description, cta, feature1, feature2, feature3
dashboardheader, sidebar, main, card1, card2, card3, chart
producthero, title, image, description, price, buyButton, features
blogheader, title, content, sidebar, related1, related2, related3

Usage

요소에 data-motion-id 속성을 추가하면 Intersection Observer가 자동으로 연결된다.

import { useSimplePageMotion } from '@hua-labs/motion-core'

function HomePage() {
  const motions = useSimplePageMotion('home')

  return (
    <div>
      <div
        data-motion-id="hero"
        style={motions.hero?.style}
      >
        히어로 영역
      </div>

      <h1
        data-motion-id="title"
        style={motions.title?.style}
      >
        페이지 제목
      </h1>

      <div
        data-motion-id="cta"
        style={motions.cta?.style}
      >
        <button>시작하기</button>
      </div>
    </div>
  )
}

useCustomPageMotion

직접 구성한 PageMotionsConfig를 사용하여 1단계 방식의 페이지 모션을 적용한다. useSimplePageMotion의 커스텀 버전이다.

Signature

function useCustomPageMotion(
  config: PageMotionsConfig
): Record<string, PageMotionRef>

type PageMotionsConfig = Record<string, PageMotionElement>

interface PageMotionElement {
  type: string         // MOTION_PRESETS 키: 'hero' | 'title' | 'button' | 'card' | 'text' | 'image'
  entrance?: MotionType
  hover?: boolean
  click?: boolean
  delay?: number
  duration?: number
  threshold?: number
}

Usage

import { useCustomPageMotion } from '@hua-labs/motion-core'

function CustomPage() {
  const motions = useCustomPageMotion({
    banner: { type: 'hero', delay: 0 },
    heading: { type: 'title', delay: 200 },
    body: { type: 'text', delay: 400 },
    action: { type: 'button', hover: true, click: true }
  })

  return (
    <div>
      <div data-motion-id="banner" style={motions.banner?.style}>배너</div>
      <h1 data-motion-id="heading" style={motions.heading?.style}>제목</h1>
      <p data-motion-id="body" style={motions.body?.style}>본문</p>
      <button data-motion-id="action" style={motions.action?.style}>실행</button>
    </div>
  )
}

usePageMotions

상태 관리자(MotionStateManager)를 활용하여 호버/클릭 인터랙션까지 포함한 완전한 페이지 모션을 관리한다. 3단계 추상화 중 2단계에 해당하며 useSimplePageMotion보다 더 많은 기능을 제공한다.

Signature

function usePageMotions(config: PageMotionsConfig): Record<string, PageMotionRef> & {
  reset: () => void
}

useSimplePageMotion과 동일한 PageMotionsConfig 타입을 받지만, 반환값에 reset() 함수가 추가된다.

차이점 비교

기능useSimplePageMotionusePageMotions
입장 애니메이션OO
호버 인터랙션XO
클릭 인터랙션XO
상태 관리자XO (MotionStateManager)
reset()XO

Usage

import { usePageMotions } from '@hua-labs/motion-core'

function InteractiveDashboard() {
  const { card1, card2, header, reset } = usePageMotions({
    header: { type: 'hero' },
    card1: { type: 'card', hover: true, click: false },
    card2: { type: 'card', hover: true, click: true }
  })

  return (
    <div>
      <header data-motion-id="header" style={header?.style}>
        대시보드
      </header>
      <div data-motion-id="card1" style={card1?.style}>카드 1</div>
      <div data-motion-id="card2" style={card2?.style}>카드 2</div>
      <button onClick={reset}>모션 리셋</button>
    </div>
  )
}

Notes

  • useSimplePageMotionuseCustomPageMotion은 내부적으로 같은 구현(useSimplePageMotions)을 사용한다.
  • 요소에 data-motion-id 속성이 없으면 Intersection Observer가 연결되지 않는다.
  • usePageMotionsdocument에 이벤트 위임 방식으로 호버/클릭 리스너를 등록하므로 개별 요소마다 이벤트 핸들러를 붙일 필요가 없다.
  • 페이지 언마운트 시 MotionStateManager 상태가 자동으로 초기화된다.