요소 애니메이션
개별 DOM 요소에 애니메이션 적용하기
Transition 예제
다양한 transition 효과를 사용하는 방법입니다:
import { transition } from '@ssgoi/react';
import { fade, scale, blur, slide, fly, rotate, bounce } from '@ssgoi/react/transitions';
// Fade 트랜지션
<div ref={transition({
key: "fade-element",
...fade({ spring: { stiffness: 300, damping: 30 } })
})}>
Fade 효과
</div>
// Scale 트랜지션
<div ref={transition({
key: "scale-element",
...scale({ spring: { stiffness: 300, damping: 30 } })
})}>
Scale 효과
</div>
// Blur 트랜지션
<div ref={transition({
key: "blur-element",
...blur({ amount: 10, spring: { stiffness: 300, damping: 30 } })
})}>
Blur 효과
</div>
// Slide 트랜지션 (방향 지정)
<div ref={transition({
key: "slide-element",
...slide({ direction: 'left', spring: { stiffness: 300, damping: 30 } })
})}>
Slide 효과
</div>
// Fly 트랜지션 (커스텀 위치)
<div ref={transition({
key: "fly-element",
...fly({ x: 200, y: -50, spring: { stiffness: 300, damping: 30 } })
})}>
Fly 효과
</div>
// Rotate 트랜지션
<div ref={transition({
key: "rotate-element",
...rotate({ spring: { stiffness: 300, damping: 30 } })
})}>
Rotate 효과
</div>
// Bounce 트랜지션
<div ref={transition({
key: "bounce-element",
...bounce({ spring: { stiffness: 300, damping: 30 } })
})}>
Bounce 효과
</div>
기본 구조
TransitionConfig 인터페이스
interface TransitionConfig {
spring?: {
stiffness: number; // 스프링 강성 (기본: 300)
damping: number; // 감쇠 계수 (기본: 30)
};
tick?: (progress: number) => void; // in: 0→1, out: 1→0
prepare?: (element: HTMLElement) => void; // 애니메이션 시작 전 초기 설정
onStart?: () => void;
onEnd?: () => void;
}
트랜지션 정의
interface Transition {
in?: (element: HTMLElement) => TransitionConfig;
out?: (element: HTMLElement) => TransitionConfig;
}
동작 원리
- 마운트 시: 요소가 DOM에 추가될 때
in
함수 실행 - 언마운트 시: 요소가 제거되기 전
out
함수 실행 - 애니메이션: 스프링 물리 엔진이 progress 생성
- in: 0 → 1
- out: 1 → 0
- tick 콜백: 매 프레임마다 호출되어 스타일 업데이트
트랜지션 프리셋
import { fade, scale /** 등등 */ } from "@ssgoi/react/transitions";
프레임워크별 사용법
import { transition } from "@ssgoi/react";
<div
ref={transition({
key: "unique-key",
in: (element) => ({
tick: (progress) => {
element.style.opacity = progress;
element.style.transform = `translateY(${20 * (1 - progress)}px)`;
},
}),
out: (element) => ({
tick: (progress) => {
element.style.opacity = 1 - progress;
},
}),
})}
>
Content
</div>
Progress 동작 방식
key
key
는 페이지 내에서 고유해야 함 (DOM이 생성되거나 삭제될 때도 애니메이션 상태를 추적할 수 있도록)key
를 설정하지 않으면 기본적으로 호출 위치 기반의 자동 키가 생성됨
in 애니메이션
- progress: 0 → 1
- 요소가 나타날 때 실행
- 투명도 0에서 1로, 작은 크기에서 원래 크기로
out 애니메이션
- progress: 1 → 0
- 요소가 사라질 때 실행
- 투명도 1에서 0으로, 원래 크기에서 작은 크기로
// 예시: in과 out의 차이
{
in: (element) => ({
tick: (progress) => {
// progress: 0 → 1
element.style.opacity = progress; // 0 → 1
}
}),
out: (element) => ({
tick: (progress) => {
// progress: 1 → 0
element.style.opacity = progress; // 1 → 0
}
})
}
prepare 콜백
애니메이션이 시작되기 전에 DOM 요소를 준비하는 단계입니다:
{
in: {
prepare: (element) => {
// tick이 실행되기 전에 초기 상태 설정
element.style.willChange = 'opacity, transform';
},
tick: (progress) => ({
opacity: progress,
transform: `translateY(${20 * (1 - progress)}px)`
})
}
}