Motion
입장 애니메이션 훅
stable요소가 뷰포트에 들어올 때 실행되는 입장 애니메이션 훅 모음
@hua-labs/motion-corev2.0.0
Import
import {
useFadeIn,
useSlideUp,
useSlideDown,
useSlideLeft,
useSlideRight,
useScaleIn,
useBounceIn,
useSpringMotion,
} from '@hua-labs/motion-core'공통 패턴
모든 입장 애니메이션 훅은 EntranceMotionReturn 타입을 반환한다.
interface EntranceMotionReturn<T extends MotionElement = HTMLDivElement>
extends BaseMotionReturn<T> {
pause: () => void
resume: () => void
}
interface BaseMotionReturn<T> {
ref: RefObject<T | null>
isVisible: boolean
isAnimating: boolean
style: MotionStyle
progress: number // 0 ~ 1
start: () => void
stop: () => void
reset: () => void
}기본 동작: autoStart: true 일 때 요소가 뷰포트에 들어오면 Intersection Observer가 자동으로 애니메이션을 시작한다.
useFadeIn
요소를 투명도 0에서 1로 페이드인한다.
Signature
function useFadeIn<T extends MotionElement = HTMLDivElement>(
options?: FadeInOptions
): EntranceMotionReturn<T>Parameters
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
delay | number | 0 | 시작 지연 시간 (ms) |
duration | number | 프로필 기본값 | 애니메이션 지속 시간 (ms) |
easing | string | 프로필 기본값 | CSS 이징 |
threshold | number | 프로필 기본값 | Intersection Observer 임계값 (0-1) |
triggerOnce | boolean | 프로필 기본값 | 한 번만 트리거할지 여부 |
autoStart | boolean | true | 자동 시작 여부 |
initialOpacity | number | 프로필 기본값 | 초기 투명도 |
targetOpacity | number | 1 | 목표 투명도 |
onStart | () => void | — | 시작 콜백 |
onComplete | () => void | — | 완료 콜백 |
onStop | () => void | — | 중단 콜백 |
onReset | () => void | — | 리셋 콜백 |
Usage
import { useFadeIn } from '@hua-labs/motion-core'
function Card() {
const { ref, style } = useFadeIn({ delay: 200, duration: 600 })
return (
<div ref={ref} style={style}>
카드 내용
</div>
)
}수동 제어:
const { ref, style, start, reset } = useFadeIn({ autoStart: false })
return (
<div>
<div ref={ref} style={style}>콘텐츠</div>
<button onClick={start}>시작</button>
<button onClick={reset}>초기화</button>
</div>
)useSlideUp / useSlideDown / useSlideLeft / useSlideRight
요소를 지정한 방향에서 슬라이드인한다. 네 훅은 모두 동일한 SlideOptions를 사용하며 direction 기본값만 다르다.
Signature
function useSlideUp<T extends MotionElement = HTMLDivElement>(
options?: SlideOptions
): EntranceMotionReturn<T>
function useSlideDown<T extends MotionElement = HTMLDivElement>(
options?: SlideOptions
): EntranceMotionReturn<T>
function useSlideLeft<T extends MotionElement = HTMLDivElement>(
options?: SlideOptions
): EntranceMotionReturn<T>
function useSlideRight<T extends MotionElement = HTMLDivElement>(
options?: SlideOptions
): EntranceMotionReturn<T>Parameters
| 파라미터 | 타입 | 기본값 | 설명 | |||
|---|---|---|---|---|---|---|
direction | `'up' \ | 'down' \ | 'left' \ | 'right'` | 훅별 방향 | 슬라이드 방향 |
distance | number | 프로필 기본값 | 슬라이드 거리 (px) | |||
duration | number | 프로필 기본값 | 지속 시간 (ms) | |||
delay | number | 0 | 지연 시간 (ms) | |||
easing | string | 프로필 기본값 | CSS 이징 | |||
autoStart | boolean | true | 자동 시작 | |||
triggerOnce | boolean | 프로필 기본값 | 한 번만 트리거 |
Usage
import { useSlideUp } from '@hua-labs/motion-core'
function Section() {
const { ref, style } = useSlideUp({ delay: 100, distance: 40 })
return <section ref={ref} style={style}>섹션 내용</section>
}useScaleIn
요소를 지정한 스케일에서 1로 확대하며 등장시킨다.
Signature
function useScaleIn<T extends MotionElement = HTMLDivElement>(
options?: ScaleOptions
): EntranceMotionReturn<T>Parameters
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
initialScale | number | 0 | 초기 스케일 |
targetScale | number | 1 | 목표 스케일 |
duration | number | 프로필 기본값 | 지속 시간 (ms) |
delay | number | 0 | 지연 시간 (ms) |
easing | string | 프로필 기본값 | CSS 이징 |
autoStart | boolean | true | 자동 시작 |
Usage
import { useScaleIn } from '@hua-labs/motion-core'
function Modal() {
const { ref, style } = useScaleIn({ initialScale: 0.8, duration: 300 })
return <div ref={ref} style={style}>모달 내용</div>
}useBounceIn
바운스 효과와 함께 요소를 등장시킨다.
Signature
function useBounceIn<T extends MotionElement = HTMLDivElement>(
options?: BounceOptions
): EntranceMotionReturn<T>Parameters
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
intensity | number | 프로필 기본값 | 바운스 강도 (오버슈트 비율) |
duration | number | 600 | 지속 시간 (ms) |
delay | number | 0 | 지연 시간 (ms) |
easing | string | 프로필 기본값 | CSS 이징 |
autoStart | boolean | true | 자동 시작 |
Usage
import { useBounceIn } from '@hua-labs/motion-core'
function Badge() {
const { ref, style } = useBounceIn({ intensity: 0.3 })
return <span ref={ref} style={style}>NEW</span>
}useSpringMotion
스프링 물리 시뮬레이션으로 값을 애니메이션한다. CSS transition 대신 requestAnimationFrame 루프로 동작한다.
Signature
function useSpringMotion<T extends MotionElement = HTMLDivElement>(
options: SpringMotionOptions
): BaseMotionReturn<T> & { value: number; velocity: number }
interface SpringMotionOptions extends SpringOptions {
from: number // 시작 값
to: number // 목표 값
enabled?: boolean // 활성화 여부
mass?: number // 질량 (프로필 기본값)
stiffness?: number // 강성 (프로필 기본값)
damping?: number // 감쇠 (프로필 기본값)
restDelta?: number // 정지 임계값
restSpeed?: number // 정지 속도
autoStart?: boolean // 자동 시작 (기본값: true)
}Returns
| 이름 | 타입 | 설명 |
|---|---|---|
ref | RefObject<T> | DOM 요소 참조 |
value | number | 현재 스프링 값 |
velocity | number | 현재 속도 |
isAnimating | boolean | 애니메이션 진행 여부 |
progress | number | 진행률 (0~1) |
start | () => void | 시작 |
stop | () => void | 중지 |
reset | () => void | 리셋 |
Usage
import { useSpringMotion } from '@hua-labs/motion-core'
function AnimatedCounter() {
const { value } = useSpringMotion({
from: 0,
to: 100,
stiffness: 100,
damping: 20,
mass: 1
})
return <div>{Math.round(value)}</div>
}Notes
- 모든 입장 훅은
MotionProfileProvider가 없을 때neutral프로필 기본값을 사용한다. autoStart: false로 설정하면start()함수를 직접 호출해야 한다.triggerOnce: true(기본값)이면 한 번 트리거된 후 Intersection Observer가 해제된다.useSpringMotion은 CSS transition이 아닌 JS 루프 기반이라pause/resume을 지원하지 않는다.