Motion
페이지 레벨 모션 훅
stable페이지 전체 요소의 입장 애니메이션을 선언적으로 관리하는 훅
@hua-labs/motion-corev2.0.0
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
}지원 페이지 타입
| 타입 | 포함 요소 |
|---|---|
home | hero, title, description, cta, feature1, feature2, feature3 |
dashboard | header, sidebar, main, card1, card2, card3, chart |
product | hero, title, image, description, price, buyButton, features |
blog | header, 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() 함수가 추가된다.
차이점 비교
| 기능 | useSimplePageMotion | usePageMotions |
|---|---|---|
| 입장 애니메이션 | O | O |
| 호버 인터랙션 | X | O |
| 클릭 인터랙션 | X | O |
| 상태 관리자 | X | O (MotionStateManager) |
reset() | X | O |
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
useSimplePageMotion과useCustomPageMotion은 내부적으로 같은 구현(useSimplePageMotions)을 사용한다.- 요소에
data-motion-id속성이 없으면 Intersection Observer가 연결되지 않는다. usePageMotions는document에 이벤트 위임 방식으로 호버/클릭 리스너를 등록하므로 개별 요소마다 이벤트 핸들러를 붙일 필요가 없다.- 페이지 언마운트 시
MotionStateManager상태가 자동으로 초기화된다.