@hua-labs/motion-core 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +245 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/hooks/useBounceIn.d.ts +3 -0
- package/dist/hooks/useBounceIn.d.ts.map +1 -0
- package/dist/hooks/useBounceIn.js +141 -0
- package/dist/hooks/useBounceIn.js.map +1 -0
- package/dist/hooks/useButtonEffect.d.ts +48 -0
- package/dist/hooks/useButtonEffect.d.ts.map +1 -0
- package/dist/hooks/useButtonEffect.js +311 -0
- package/dist/hooks/useButtonEffect.js.map +1 -0
- package/dist/hooks/useCardList.d.ts +23 -0
- package/dist/hooks/useCardList.d.ts.map +1 -0
- package/dist/hooks/useCardList.js +119 -0
- package/dist/hooks/useCardList.js.map +1 -0
- package/dist/hooks/useClickToggle.d.ts +15 -0
- package/dist/hooks/useClickToggle.d.ts.map +1 -0
- package/dist/hooks/useClickToggle.js +102 -0
- package/dist/hooks/useClickToggle.js.map +1 -0
- package/dist/hooks/useFadeIn.d.ts +17 -0
- package/dist/hooks/useFadeIn.d.ts.map +1 -0
- package/dist/hooks/useFadeIn.js +133 -0
- package/dist/hooks/useFadeIn.js.map +1 -0
- package/dist/hooks/useFocusToggle.d.ts +15 -0
- package/dist/hooks/useFocusToggle.d.ts.map +1 -0
- package/dist/hooks/useFocusToggle.js +99 -0
- package/dist/hooks/useFocusToggle.js.map +1 -0
- package/dist/hooks/useGradient.d.ts +25 -0
- package/dist/hooks/useGradient.d.ts.map +1 -0
- package/dist/hooks/useGradient.js +144 -0
- package/dist/hooks/useGradient.js.map +1 -0
- package/dist/hooks/useHoverMotion.d.ts +15 -0
- package/dist/hooks/useHoverMotion.d.ts.map +1 -0
- package/dist/hooks/useHoverMotion.js +99 -0
- package/dist/hooks/useHoverMotion.js.map +1 -0
- package/dist/hooks/useLoadingSpinner.d.ts +30 -0
- package/dist/hooks/useLoadingSpinner.d.ts.map +1 -0
- package/dist/hooks/useLoadingSpinner.js +283 -0
- package/dist/hooks/useLoadingSpinner.js.map +1 -0
- package/dist/hooks/useMotion.d.ts +103 -0
- package/dist/hooks/useMotion.d.ts.map +1 -0
- package/dist/hooks/useMotion.js +266 -0
- package/dist/hooks/useMotion.js.map +1 -0
- package/dist/hooks/useMotionState.d.ts +26 -0
- package/dist/hooks/useMotionState.d.ts.map +1 -0
- package/dist/hooks/useMotionState.js +119 -0
- package/dist/hooks/useMotionState.js.map +1 -0
- package/dist/hooks/useNavigation.d.ts +40 -0
- package/dist/hooks/useNavigation.d.ts.map +1 -0
- package/dist/hooks/useNavigation.js +212 -0
- package/dist/hooks/useNavigation.js.map +1 -0
- package/dist/hooks/usePulse.d.ts +3 -0
- package/dist/hooks/usePulse.d.ts.map +1 -0
- package/dist/hooks/usePulse.js +134 -0
- package/dist/hooks/usePulse.js.map +1 -0
- package/dist/hooks/useRepeat.d.ts +26 -0
- package/dist/hooks/useRepeat.d.ts.map +1 -0
- package/dist/hooks/useRepeat.js +179 -0
- package/dist/hooks/useRepeat.js.map +1 -0
- package/dist/hooks/useScaleIn.d.ts +3 -0
- package/dist/hooks/useScaleIn.d.ts.map +1 -0
- package/dist/hooks/useScaleIn.js +111 -0
- package/dist/hooks/useScaleIn.js.map +1 -0
- package/dist/hooks/useScrollProgress.d.ts +21 -0
- package/dist/hooks/useScrollProgress.d.ts.map +1 -0
- package/dist/hooks/useScrollProgress.js +139 -0
- package/dist/hooks/useScrollProgress.js.map +1 -0
- package/dist/hooks/useScrollReveal.d.ts +17 -0
- package/dist/hooks/useScrollReveal.d.ts.map +1 -0
- package/dist/hooks/useScrollReveal.js +95 -0
- package/dist/hooks/useScrollReveal.js.map +1 -0
- package/dist/hooks/useScrollToggle.d.ts +17 -0
- package/dist/hooks/useScrollToggle.d.ts.map +1 -0
- package/dist/hooks/useScrollToggle.js +119 -0
- package/dist/hooks/useScrollToggle.js.map +1 -0
- package/dist/hooks/useSkeleton.d.ts +21 -0
- package/dist/hooks/useSkeleton.d.ts.map +1 -0
- package/dist/hooks/useSkeleton.js +139 -0
- package/dist/hooks/useSkeleton.js.map +1 -0
- package/dist/hooks/useSlideDown.d.ts +25 -0
- package/dist/hooks/useSlideDown.d.ts.map +1 -0
- package/dist/hooks/useSlideDown.js +263 -0
- package/dist/hooks/useSlideDown.js.map +1 -0
- package/dist/hooks/useSlideLeft.d.ts +3 -0
- package/dist/hooks/useSlideLeft.d.ts.map +1 -0
- package/dist/hooks/useSlideLeft.js +111 -0
- package/dist/hooks/useSlideLeft.js.map +1 -0
- package/dist/hooks/useSlideRight.d.ts +3 -0
- package/dist/hooks/useSlideRight.d.ts.map +1 -0
- package/dist/hooks/useSlideRight.js +111 -0
- package/dist/hooks/useSlideRight.js.map +1 -0
- package/dist/hooks/useSlideUp.d.ts +3 -0
- package/dist/hooks/useSlideUp.d.ts.map +1 -0
- package/dist/hooks/useSlideUp.js +111 -0
- package/dist/hooks/useSlideUp.js.map +1 -0
- package/dist/hooks/useSpringMotion.d.ts +32 -0
- package/dist/hooks/useSpringMotion.d.ts.map +1 -0
- package/dist/hooks/useSpringMotion.js +185 -0
- package/dist/hooks/useSpringMotion.js.map +1 -0
- package/dist/hooks/useVisibilityToggle.d.ts +15 -0
- package/dist/hooks/useVisibilityToggle.d.ts.map +1 -0
- package/dist/hooks/useVisibilityToggle.js +106 -0
- package/dist/hooks/useVisibilityToggle.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +109 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/easing.d.ts +44 -0
- package/dist/utils/easing.d.ts.map +1 -0
- package/dist/utils/easing.js +98 -0
- package/dist/utils/easing.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { useRef, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
export function useLoadingSpinner(options = {}) {
|
|
3
|
+
const { duration = 1000, easing = 'linear', type = 'rotate', rotationSpeed = 1, pulseSpeed = 1, bounceHeight = 20, waveCount = 3, dotCount = 3, barCount = 4, color = '#3b82f6', backgroundColor = 'transparent', size = 40, thickness = 4, autoStart = true, infinite = true, onComplete, onStart, onStop, onReset } = options;
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
6
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
7
|
+
const [progress, setProgress] = useState(0);
|
|
8
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
9
|
+
const [rotationAngle, setRotationAngle] = useState(0);
|
|
10
|
+
const [pulseScale, setPulseScale] = useState(1);
|
|
11
|
+
const [bounceOffset, setBounceOffset] = useState(0);
|
|
12
|
+
const [waveProgress, setWaveProgress] = useState(0);
|
|
13
|
+
const [dotProgress, setDotProgress] = useState(0);
|
|
14
|
+
const [barProgress, setBarProgress] = useState(0);
|
|
15
|
+
const animationRef = useRef(null);
|
|
16
|
+
const startTimeRef = useRef(0);
|
|
17
|
+
// 애니메이션 루프 함수
|
|
18
|
+
const runAnimation = useCallback(() => {
|
|
19
|
+
if (!isAnimating)
|
|
20
|
+
return;
|
|
21
|
+
const animate = (currentTime) => {
|
|
22
|
+
if (!isAnimating)
|
|
23
|
+
return;
|
|
24
|
+
if (!startTimeRef.current) {
|
|
25
|
+
startTimeRef.current = currentTime;
|
|
26
|
+
}
|
|
27
|
+
const elapsed = currentTime - startTimeRef.current;
|
|
28
|
+
const currentProgress = (elapsed / duration) % 1;
|
|
29
|
+
setProgress(currentProgress);
|
|
30
|
+
// 타입별 애니메이션 업데이트
|
|
31
|
+
switch (type) {
|
|
32
|
+
case 'rotate':
|
|
33
|
+
setRotationAngle(currentProgress * 360 * rotationSpeed);
|
|
34
|
+
break;
|
|
35
|
+
case 'pulse':
|
|
36
|
+
setPulseScale(0.8 + 0.4 * Math.sin(currentProgress * Math.PI * 2 * pulseSpeed));
|
|
37
|
+
break;
|
|
38
|
+
case 'bounce':
|
|
39
|
+
setBounceOffset(bounceHeight * Math.sin(currentProgress * Math.PI * 2));
|
|
40
|
+
break;
|
|
41
|
+
case 'wave':
|
|
42
|
+
setWaveProgress(currentProgress);
|
|
43
|
+
break;
|
|
44
|
+
case 'dots':
|
|
45
|
+
setDotProgress(currentProgress);
|
|
46
|
+
break;
|
|
47
|
+
case 'bars':
|
|
48
|
+
setBarProgress(currentProgress);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
if (infinite || currentProgress < 1) {
|
|
52
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
setIsAnimating(false);
|
|
56
|
+
onComplete?.();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
60
|
+
}, [isAnimating, duration, type, rotationSpeed, pulseSpeed, bounceHeight, infinite, onComplete]);
|
|
61
|
+
// 로딩 시작 함수
|
|
62
|
+
const startLoading = useCallback(() => {
|
|
63
|
+
if (isLoading)
|
|
64
|
+
return;
|
|
65
|
+
setIsLoading(true);
|
|
66
|
+
setIsAnimating(true);
|
|
67
|
+
setProgress(0);
|
|
68
|
+
startTimeRef.current = 0;
|
|
69
|
+
onStart?.();
|
|
70
|
+
runAnimation();
|
|
71
|
+
}, [isLoading, onStart, runAnimation]);
|
|
72
|
+
// 로딩 중단 함수
|
|
73
|
+
const stopLoading = useCallback(() => {
|
|
74
|
+
setIsLoading(false);
|
|
75
|
+
setIsAnimating(false);
|
|
76
|
+
if (animationRef.current) {
|
|
77
|
+
cancelAnimationFrame(animationRef.current);
|
|
78
|
+
animationRef.current = null;
|
|
79
|
+
}
|
|
80
|
+
onStop?.();
|
|
81
|
+
}, [onStop]);
|
|
82
|
+
// 로딩 상태 설정 함수
|
|
83
|
+
const setLoadingState = useCallback((loading) => {
|
|
84
|
+
if (loading) {
|
|
85
|
+
startLoading();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
stopLoading();
|
|
89
|
+
}
|
|
90
|
+
}, [startLoading, stopLoading]);
|
|
91
|
+
// 모션 시작 함수
|
|
92
|
+
const start = useCallback(() => {
|
|
93
|
+
if (!isVisible) {
|
|
94
|
+
setIsVisible(true);
|
|
95
|
+
startLoading();
|
|
96
|
+
}
|
|
97
|
+
}, [isVisible, startLoading]);
|
|
98
|
+
// 모션 중단 함수
|
|
99
|
+
const stop = useCallback(() => {
|
|
100
|
+
stopLoading();
|
|
101
|
+
}, [stopLoading]);
|
|
102
|
+
// 모션 리셋 함수
|
|
103
|
+
const reset = useCallback(() => {
|
|
104
|
+
setIsVisible(false);
|
|
105
|
+
setIsAnimating(false);
|
|
106
|
+
setProgress(0);
|
|
107
|
+
setIsLoading(false);
|
|
108
|
+
setRotationAngle(0);
|
|
109
|
+
setPulseScale(1);
|
|
110
|
+
setBounceOffset(0);
|
|
111
|
+
setWaveProgress(0);
|
|
112
|
+
setDotProgress(0);
|
|
113
|
+
setBarProgress(0);
|
|
114
|
+
startTimeRef.current = 0;
|
|
115
|
+
if (animationRef.current) {
|
|
116
|
+
cancelAnimationFrame(animationRef.current);
|
|
117
|
+
animationRef.current = null;
|
|
118
|
+
}
|
|
119
|
+
onReset?.();
|
|
120
|
+
}, [onReset]);
|
|
121
|
+
// 모션 일시정지 함수
|
|
122
|
+
const pause = useCallback(() => {
|
|
123
|
+
setIsAnimating(false);
|
|
124
|
+
if (animationRef.current) {
|
|
125
|
+
cancelAnimationFrame(animationRef.current);
|
|
126
|
+
animationRef.current = null;
|
|
127
|
+
}
|
|
128
|
+
}, []);
|
|
129
|
+
// 모션 재개 함수
|
|
130
|
+
const resume = useCallback(() => {
|
|
131
|
+
if (isVisible && !isAnimating) {
|
|
132
|
+
setIsAnimating(true);
|
|
133
|
+
runAnimation();
|
|
134
|
+
}
|
|
135
|
+
}, [isVisible, isAnimating, runAnimation]);
|
|
136
|
+
// 자동 시작
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (autoStart) {
|
|
139
|
+
startLoading();
|
|
140
|
+
}
|
|
141
|
+
}, [autoStart, startLoading]);
|
|
142
|
+
// 컴포넌트 언마운트 시 정리
|
|
143
|
+
useEffect(() => {
|
|
144
|
+
return () => {
|
|
145
|
+
if (animationRef.current) {
|
|
146
|
+
cancelAnimationFrame(animationRef.current);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
// 스피너 스타일 계산
|
|
151
|
+
const getSpinnerStyle = () => {
|
|
152
|
+
const baseStyle = {
|
|
153
|
+
width: size,
|
|
154
|
+
height: size,
|
|
155
|
+
backgroundColor: 'transparent',
|
|
156
|
+
position: 'relative',
|
|
157
|
+
display: 'inline-block'
|
|
158
|
+
};
|
|
159
|
+
switch (type) {
|
|
160
|
+
case 'rotate':
|
|
161
|
+
return {
|
|
162
|
+
...baseStyle,
|
|
163
|
+
border: `${thickness}px solid ${backgroundColor}`,
|
|
164
|
+
borderTop: `${thickness}px solid ${color}`,
|
|
165
|
+
borderRadius: '50%',
|
|
166
|
+
transform: `rotate(${rotationAngle}deg)`,
|
|
167
|
+
transition: `transform ${duration}ms ${easing}`
|
|
168
|
+
};
|
|
169
|
+
case 'pulse':
|
|
170
|
+
return {
|
|
171
|
+
...baseStyle,
|
|
172
|
+
backgroundColor: color,
|
|
173
|
+
borderRadius: '50%',
|
|
174
|
+
transform: `scale(${pulseScale})`,
|
|
175
|
+
transition: `transform ${duration}ms ${easing}`
|
|
176
|
+
};
|
|
177
|
+
case 'bounce':
|
|
178
|
+
return {
|
|
179
|
+
...baseStyle,
|
|
180
|
+
backgroundColor: color,
|
|
181
|
+
borderRadius: '50%',
|
|
182
|
+
transform: `translateY(${bounceOffset}px)`,
|
|
183
|
+
transition: `transform ${duration}ms ${easing}`
|
|
184
|
+
};
|
|
185
|
+
case 'wave':
|
|
186
|
+
return {
|
|
187
|
+
...baseStyle,
|
|
188
|
+
display: 'flex',
|
|
189
|
+
alignItems: 'center',
|
|
190
|
+
justifyContent: 'space-between'
|
|
191
|
+
};
|
|
192
|
+
case 'dots':
|
|
193
|
+
return {
|
|
194
|
+
...baseStyle,
|
|
195
|
+
display: 'flex',
|
|
196
|
+
alignItems: 'center',
|
|
197
|
+
justifyContent: 'space-between'
|
|
198
|
+
};
|
|
199
|
+
case 'bars':
|
|
200
|
+
return {
|
|
201
|
+
...baseStyle,
|
|
202
|
+
display: 'flex',
|
|
203
|
+
alignItems: 'center',
|
|
204
|
+
justifyContent: 'space-between'
|
|
205
|
+
};
|
|
206
|
+
default:
|
|
207
|
+
return baseStyle;
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
// 웨이브 바 스타일 생성
|
|
211
|
+
const getWaveBars = () => {
|
|
212
|
+
return Array.from({ length: waveCount }, (_, index) => {
|
|
213
|
+
const delay = index * (duration / waveCount);
|
|
214
|
+
const height = size * (0.3 + 0.7 * Math.sin((waveProgress + index / waveCount) * Math.PI * 2));
|
|
215
|
+
return {
|
|
216
|
+
width: thickness,
|
|
217
|
+
height: `${height}px`,
|
|
218
|
+
backgroundColor: color,
|
|
219
|
+
borderRadius: thickness / 2,
|
|
220
|
+
animationDelay: `${delay}ms`,
|
|
221
|
+
transition: `height ${duration}ms ${easing}`
|
|
222
|
+
};
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
// 점 스타일 생성
|
|
226
|
+
const getDots = () => {
|
|
227
|
+
return Array.from({ length: dotCount }, (_, index) => {
|
|
228
|
+
const delay = index * (duration / dotCount);
|
|
229
|
+
const opacity = 0.3 + 0.7 * Math.sin((dotProgress + index / dotCount) * Math.PI * 2);
|
|
230
|
+
const scale = 0.8 + 0.4 * Math.sin((dotProgress + index / dotCount) * Math.PI * 2);
|
|
231
|
+
return {
|
|
232
|
+
width: thickness * 2,
|
|
233
|
+
height: thickness * 2,
|
|
234
|
+
backgroundColor: color,
|
|
235
|
+
borderRadius: '50%',
|
|
236
|
+
opacity,
|
|
237
|
+
transform: `scale(${scale})`,
|
|
238
|
+
animationDelay: `${delay}ms`,
|
|
239
|
+
transition: `all ${duration}ms ${easing}`
|
|
240
|
+
};
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
// 바 스타일 생성
|
|
244
|
+
const getBars = () => {
|
|
245
|
+
return Array.from({ length: barCount }, (_, index) => {
|
|
246
|
+
const delay = index * (duration / barCount);
|
|
247
|
+
const height = size * (0.2 + 0.8 * Math.sin((barProgress + index / barCount) * Math.PI * 2));
|
|
248
|
+
return {
|
|
249
|
+
width: thickness,
|
|
250
|
+
height: `${height}px`,
|
|
251
|
+
backgroundColor: color,
|
|
252
|
+
borderRadius: thickness / 2,
|
|
253
|
+
animationDelay: `${delay}ms`,
|
|
254
|
+
transition: `height ${duration}ms ${easing}`
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
const style = getSpinnerStyle();
|
|
259
|
+
return {
|
|
260
|
+
ref,
|
|
261
|
+
isVisible,
|
|
262
|
+
isAnimating,
|
|
263
|
+
style,
|
|
264
|
+
progress,
|
|
265
|
+
start,
|
|
266
|
+
stop,
|
|
267
|
+
reset,
|
|
268
|
+
pause,
|
|
269
|
+
resume,
|
|
270
|
+
isLoading,
|
|
271
|
+
spinnerType: type,
|
|
272
|
+
rotationAngle,
|
|
273
|
+
pulseScale,
|
|
274
|
+
bounceOffset,
|
|
275
|
+
waveProgress,
|
|
276
|
+
dotProgress,
|
|
277
|
+
barProgress,
|
|
278
|
+
startLoading,
|
|
279
|
+
stopLoading,
|
|
280
|
+
setLoadingState
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=useLoadingSpinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLoadingSpinner.js","sourceRoot":"","sources":["../../src/hooks/useLoadingSpinner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { BaseMotionOptions, BaseMotionReturn, MotionElement } from '../types';
|
|
2
|
+
export interface MotionOptions extends BaseMotionOptions {
|
|
3
|
+
scale?: number | {
|
|
4
|
+
from: number;
|
|
5
|
+
to: number;
|
|
6
|
+
};
|
|
7
|
+
opacity?: number | {
|
|
8
|
+
from: number;
|
|
9
|
+
to: number;
|
|
10
|
+
};
|
|
11
|
+
rotate?: number | {
|
|
12
|
+
from: number;
|
|
13
|
+
to: number;
|
|
14
|
+
};
|
|
15
|
+
translateX?: number | {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
};
|
|
19
|
+
translateY?: number | {
|
|
20
|
+
from: number;
|
|
21
|
+
to: number;
|
|
22
|
+
};
|
|
23
|
+
skewX?: number | {
|
|
24
|
+
from: number;
|
|
25
|
+
to: number;
|
|
26
|
+
};
|
|
27
|
+
skewY?: number | {
|
|
28
|
+
from: number;
|
|
29
|
+
to: number;
|
|
30
|
+
};
|
|
31
|
+
backgroundColor?: string | {
|
|
32
|
+
from: string;
|
|
33
|
+
to: string;
|
|
34
|
+
};
|
|
35
|
+
color?: string | {
|
|
36
|
+
from: string;
|
|
37
|
+
to: string;
|
|
38
|
+
};
|
|
39
|
+
borderColor?: string | {
|
|
40
|
+
from: string;
|
|
41
|
+
to: string;
|
|
42
|
+
};
|
|
43
|
+
width?: number | string | {
|
|
44
|
+
from: number | string;
|
|
45
|
+
to: number | string;
|
|
46
|
+
};
|
|
47
|
+
height?: number | string | {
|
|
48
|
+
from: number | string;
|
|
49
|
+
to: number | string;
|
|
50
|
+
};
|
|
51
|
+
borderRadius?: number | string | {
|
|
52
|
+
from: number | string;
|
|
53
|
+
to: number | string;
|
|
54
|
+
};
|
|
55
|
+
borderWidth?: number | {
|
|
56
|
+
from: number;
|
|
57
|
+
to: number;
|
|
58
|
+
};
|
|
59
|
+
boxShadow?: string | {
|
|
60
|
+
from: string;
|
|
61
|
+
to: string;
|
|
62
|
+
};
|
|
63
|
+
blur?: number | {
|
|
64
|
+
from: number;
|
|
65
|
+
to: number;
|
|
66
|
+
};
|
|
67
|
+
brightness?: number | {
|
|
68
|
+
from: number;
|
|
69
|
+
to: number;
|
|
70
|
+
};
|
|
71
|
+
contrast?: number | {
|
|
72
|
+
from: number;
|
|
73
|
+
to: number;
|
|
74
|
+
};
|
|
75
|
+
grayscale?: number | {
|
|
76
|
+
from: number;
|
|
77
|
+
to: number;
|
|
78
|
+
};
|
|
79
|
+
hueRotate?: number | {
|
|
80
|
+
from: number;
|
|
81
|
+
to: number;
|
|
82
|
+
};
|
|
83
|
+
saturate?: number | {
|
|
84
|
+
from: number;
|
|
85
|
+
to: number;
|
|
86
|
+
};
|
|
87
|
+
sepia?: number | {
|
|
88
|
+
from: number;
|
|
89
|
+
to: number;
|
|
90
|
+
};
|
|
91
|
+
playOnMount?: boolean;
|
|
92
|
+
loop?: boolean;
|
|
93
|
+
yoyo?: boolean;
|
|
94
|
+
stagger?: number;
|
|
95
|
+
onUpdate?: (progress: number) => void;
|
|
96
|
+
}
|
|
97
|
+
export declare function useMotion<T extends MotionElement = HTMLDivElement>(options?: MotionOptions): BaseMotionReturn<T> & {
|
|
98
|
+
play: () => void;
|
|
99
|
+
reverse: () => void;
|
|
100
|
+
seek: (progress: number) => void;
|
|
101
|
+
getValue: (property: string) => any;
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=useMotion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMotion.d.ts","sourceRoot":"","sources":["../../src/hooks/useMotion.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { useRef, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
export function useMotion(options = {}) {
|
|
3
|
+
const { duration = 1000, easing = 'ease-out', delay = 0, threshold = 0.1, triggerOnce = true, autoStart = false, playOnMount = false, loop = false, yoyo = false, stagger = 0, scale = { from: 1, to: 1 }, opacity = { from: 1, to: 1 }, rotate = { from: 0, to: 0 }, translateX = { from: 0, to: 0 }, translateY = { from: 0, to: 0 }, skewX = { from: 0, to: 0 }, skewY = { from: 0, to: 0 }, backgroundColor, color, borderColor, width, height, borderRadius, borderWidth, boxShadow, blur = { from: 0, to: 0 }, brightness = { from: 100, to: 100 }, contrast = { from: 100, to: 100 }, grayscale = { from: 0, to: 0 }, hueRotate = { from: 0, to: 0 }, saturate = { from: 100, to: 100 }, sepia = { from: 0, to: 0 }, onComplete, onStart, onStop, onReset, onUpdate } = options;
|
|
4
|
+
const ref = useRef(null);
|
|
5
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
6
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
7
|
+
const [progress, setProgress] = useState(0);
|
|
8
|
+
const [isReversed, setIsReversed] = useState(false);
|
|
9
|
+
const observerRef = useRef(null);
|
|
10
|
+
const animationRef = useRef(null);
|
|
11
|
+
// 값 정규화 함수
|
|
12
|
+
const normalizeValue = (value) => {
|
|
13
|
+
if (typeof value === 'object' && 'from' in value && 'to' in value) {
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
return { from: value, to: value };
|
|
17
|
+
};
|
|
18
|
+
// 정규화된 값들
|
|
19
|
+
const normalizedScale = normalizeValue(scale);
|
|
20
|
+
const normalizedOpacity = normalizeValue(opacity);
|
|
21
|
+
const normalizedRotate = normalizeValue(rotate);
|
|
22
|
+
const normalizedTranslateX = normalizeValue(translateX);
|
|
23
|
+
const normalizedTranslateY = normalizeValue(translateY);
|
|
24
|
+
const normalizedSkewX = normalizeValue(skewX);
|
|
25
|
+
const normalizedSkewY = normalizeValue(skewY);
|
|
26
|
+
const normalizedBlur = normalizeValue(blur);
|
|
27
|
+
const normalizedBrightness = normalizeValue(brightness);
|
|
28
|
+
const normalizedContrast = normalizeValue(contrast);
|
|
29
|
+
const normalizedGrayscale = normalizeValue(grayscale);
|
|
30
|
+
const normalizedHueRotate = normalizeValue(hueRotate);
|
|
31
|
+
const normalizedSaturate = normalizeValue(saturate);
|
|
32
|
+
const normalizedSepia = normalizeValue(sepia);
|
|
33
|
+
// 보간 함수
|
|
34
|
+
const interpolate = (from, to, progress) => {
|
|
35
|
+
return from + (to - from) * progress;
|
|
36
|
+
};
|
|
37
|
+
// 애니메이션 실행 함수
|
|
38
|
+
const runAnimation = useCallback((startTime, isReverse = false) => {
|
|
39
|
+
if (!isAnimating)
|
|
40
|
+
return;
|
|
41
|
+
const animate = (currentTime) => {
|
|
42
|
+
if (!isAnimating)
|
|
43
|
+
return;
|
|
44
|
+
const elapsed = currentTime - startTime;
|
|
45
|
+
const currentProgress = Math.min(elapsed / duration, 1);
|
|
46
|
+
// 진행률 계산 (정방향/역방향)
|
|
47
|
+
let finalProgress = isReverse ? 1 - currentProgress : currentProgress;
|
|
48
|
+
// 이징 적용
|
|
49
|
+
const easedProgress = finalProgress;
|
|
50
|
+
setProgress(easedProgress);
|
|
51
|
+
// 업데이트 콜백 호출
|
|
52
|
+
onUpdate?.(easedProgress);
|
|
53
|
+
if (currentProgress < 1) {
|
|
54
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// 애니메이션 완료
|
|
58
|
+
setIsAnimating(false);
|
|
59
|
+
// 루프 또는 요요 처리
|
|
60
|
+
if (loop || yoyo) {
|
|
61
|
+
if (yoyo) {
|
|
62
|
+
setIsReversed(!isReversed);
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
if (isAnimating)
|
|
65
|
+
return;
|
|
66
|
+
setIsAnimating(true);
|
|
67
|
+
runAnimation(Date.now(), !isReversed);
|
|
68
|
+
}, stagger);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
if (isAnimating)
|
|
73
|
+
return;
|
|
74
|
+
setIsAnimating(true);
|
|
75
|
+
runAnimation(Date.now(), isReverse);
|
|
76
|
+
}, stagger);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
onComplete?.();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
animationRef.current = requestAnimationFrame(animate);
|
|
85
|
+
}, [isAnimating, duration, loop, yoyo, stagger, onComplete, onUpdate]);
|
|
86
|
+
// 모션 시작 함수
|
|
87
|
+
const start = useCallback(() => {
|
|
88
|
+
if (!isVisible) {
|
|
89
|
+
setIsVisible(true);
|
|
90
|
+
setIsAnimating(true);
|
|
91
|
+
setProgress(0);
|
|
92
|
+
onStart?.();
|
|
93
|
+
runAnimation(Date.now(), isReversed);
|
|
94
|
+
}
|
|
95
|
+
}, [isVisible, onStart, runAnimation, isReversed]);
|
|
96
|
+
// 재생 함수
|
|
97
|
+
const play = useCallback(() => {
|
|
98
|
+
if (!isAnimating) {
|
|
99
|
+
setIsAnimating(true);
|
|
100
|
+
onStart?.();
|
|
101
|
+
runAnimation(Date.now(), isReversed);
|
|
102
|
+
}
|
|
103
|
+
}, [isAnimating, onStart, runAnimation, isReversed]);
|
|
104
|
+
// 역방향 재생 함수
|
|
105
|
+
const reverse = useCallback(() => {
|
|
106
|
+
setIsReversed(!isReversed);
|
|
107
|
+
if (!isAnimating) {
|
|
108
|
+
setIsAnimating(true);
|
|
109
|
+
onStart?.();
|
|
110
|
+
runAnimation(Date.now(), !isReversed);
|
|
111
|
+
}
|
|
112
|
+
}, [isReversed, isAnimating, onStart, runAnimation]);
|
|
113
|
+
// 진행률 이동 함수
|
|
114
|
+
const seek = useCallback((targetProgress) => {
|
|
115
|
+
const clampedProgress = Math.max(0, Math.min(1, targetProgress));
|
|
116
|
+
setProgress(clampedProgress);
|
|
117
|
+
onUpdate?.(clampedProgress);
|
|
118
|
+
}, [onUpdate]);
|
|
119
|
+
// 특정 속성의 현재 값 가져오기
|
|
120
|
+
const getValue = useCallback((property) => {
|
|
121
|
+
const currentProgress = progress;
|
|
122
|
+
switch (property) {
|
|
123
|
+
case 'scale':
|
|
124
|
+
return interpolate(normalizedScale.from, normalizedScale.to, currentProgress);
|
|
125
|
+
case 'opacity':
|
|
126
|
+
return interpolate(normalizedOpacity.from, normalizedOpacity.to, currentProgress);
|
|
127
|
+
case 'rotate':
|
|
128
|
+
return interpolate(normalizedRotate.from, normalizedRotate.to, currentProgress);
|
|
129
|
+
case 'translateX':
|
|
130
|
+
return interpolate(normalizedTranslateX.from, normalizedTranslateX.to, currentProgress);
|
|
131
|
+
case 'translateY':
|
|
132
|
+
return interpolate(normalizedTranslateY.from, normalizedTranslateY.to, currentProgress);
|
|
133
|
+
case 'skewX':
|
|
134
|
+
return interpolate(normalizedSkewX.from, normalizedSkewX.to, currentProgress);
|
|
135
|
+
case 'skewY':
|
|
136
|
+
return interpolate(normalizedSkewY.from, normalizedSkewY.to, currentProgress);
|
|
137
|
+
case 'blur':
|
|
138
|
+
return interpolate(normalizedBlur.from, normalizedBlur.to, currentProgress);
|
|
139
|
+
case 'brightness':
|
|
140
|
+
return interpolate(normalizedBrightness.from, normalizedBrightness.to, currentProgress);
|
|
141
|
+
case 'contrast':
|
|
142
|
+
return interpolate(normalizedContrast.from, normalizedContrast.to, currentProgress);
|
|
143
|
+
case 'grayscale':
|
|
144
|
+
return interpolate(normalizedGrayscale.from, normalizedGrayscale.to, currentProgress);
|
|
145
|
+
case 'hueRotate':
|
|
146
|
+
return interpolate(normalizedHueRotate.from, normalizedHueRotate.to, currentProgress);
|
|
147
|
+
case 'saturate':
|
|
148
|
+
return interpolate(normalizedSaturate.from, normalizedSaturate.to, currentProgress);
|
|
149
|
+
case 'sepia':
|
|
150
|
+
return interpolate(normalizedSepia.from, normalizedSepia.to, currentProgress);
|
|
151
|
+
default:
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}, [progress, normalizedScale, normalizedOpacity, normalizedRotate, normalizedTranslateX,
|
|
155
|
+
normalizedTranslateY, normalizedSkewX, normalizedSkewY, normalizedBlur, normalizedBrightness,
|
|
156
|
+
normalizedContrast, normalizedGrayscale, normalizedHueRotate, normalizedSaturate, normalizedSepia]);
|
|
157
|
+
// 모션 중단 함수
|
|
158
|
+
const stop = useCallback(() => {
|
|
159
|
+
setIsAnimating(false);
|
|
160
|
+
if (animationRef.current) {
|
|
161
|
+
cancelAnimationFrame(animationRef.current);
|
|
162
|
+
animationRef.current = null;
|
|
163
|
+
}
|
|
164
|
+
onStop?.();
|
|
165
|
+
}, [onStop]);
|
|
166
|
+
// 모션 리셋 함수
|
|
167
|
+
const reset = useCallback(() => {
|
|
168
|
+
setIsVisible(false);
|
|
169
|
+
setIsAnimating(false);
|
|
170
|
+
setProgress(0);
|
|
171
|
+
setIsReversed(false);
|
|
172
|
+
if (animationRef.current) {
|
|
173
|
+
cancelAnimationFrame(animationRef.current);
|
|
174
|
+
animationRef.current = null;
|
|
175
|
+
}
|
|
176
|
+
onReset?.();
|
|
177
|
+
}, [onReset]);
|
|
178
|
+
// 모션 일시정지 함수
|
|
179
|
+
const pause = useCallback(() => {
|
|
180
|
+
setIsAnimating(false);
|
|
181
|
+
if (animationRef.current) {
|
|
182
|
+
cancelAnimationFrame(animationRef.current);
|
|
183
|
+
animationRef.current = null;
|
|
184
|
+
}
|
|
185
|
+
}, []);
|
|
186
|
+
// 모션 재개 함수
|
|
187
|
+
const resume = useCallback(() => {
|
|
188
|
+
if (isVisible && !isAnimating) {
|
|
189
|
+
setIsAnimating(true);
|
|
190
|
+
runAnimation(Date.now(), isReversed);
|
|
191
|
+
}
|
|
192
|
+
}, [isVisible, isAnimating, runAnimation, isReversed]);
|
|
193
|
+
// Intersection Observer 설정
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
if (!ref.current || !autoStart)
|
|
196
|
+
return;
|
|
197
|
+
observerRef.current = new IntersectionObserver((entries) => {
|
|
198
|
+
entries.forEach((entry) => {
|
|
199
|
+
if (entry.isIntersecting) {
|
|
200
|
+
start();
|
|
201
|
+
if (triggerOnce) {
|
|
202
|
+
observerRef.current?.disconnect();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}, { threshold });
|
|
207
|
+
observerRef.current.observe(ref.current);
|
|
208
|
+
return () => {
|
|
209
|
+
if (observerRef.current) {
|
|
210
|
+
observerRef.current.disconnect();
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}, [autoStart, threshold, triggerOnce, start]);
|
|
214
|
+
// 마운트 시 자동 시작
|
|
215
|
+
useEffect(() => {
|
|
216
|
+
if (playOnMount) {
|
|
217
|
+
start();
|
|
218
|
+
}
|
|
219
|
+
}, [playOnMount, start]);
|
|
220
|
+
// 컴포넌트 언마운트 시 정리
|
|
221
|
+
useEffect(() => {
|
|
222
|
+
return () => {
|
|
223
|
+
if (animationRef.current) {
|
|
224
|
+
cancelAnimationFrame(animationRef.current);
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}, []);
|
|
228
|
+
// 현재 진행률에 따른 스타일 계산
|
|
229
|
+
const style = {
|
|
230
|
+
transform: `
|
|
231
|
+
scale(${getValue('scale')})
|
|
232
|
+
rotate(${getValue('rotate')}deg)
|
|
233
|
+
translate(${getValue('translateX')}px, ${getValue('translateY')}px)
|
|
234
|
+
skew(${getValue('skewX')}deg, ${getValue('skewY')}deg)
|
|
235
|
+
`,
|
|
236
|
+
opacity: getValue('opacity'),
|
|
237
|
+
filter: `
|
|
238
|
+
blur(${getValue('blur')}px)
|
|
239
|
+
brightness(${getValue('brightness')}%)
|
|
240
|
+
contrast(${getValue('contrast')}%)
|
|
241
|
+
grayscale(${getValue('grayscale')}%)
|
|
242
|
+
hue-rotate(${getValue('hueRotate')}deg)
|
|
243
|
+
saturate(${getValue('saturate')}%)
|
|
244
|
+
sepia(${getValue('sepia')}%)
|
|
245
|
+
`,
|
|
246
|
+
transition: `all ${duration}ms ${easing}`,
|
|
247
|
+
willChange: 'transform, opacity, filter'
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
ref,
|
|
251
|
+
isVisible,
|
|
252
|
+
isAnimating,
|
|
253
|
+
style,
|
|
254
|
+
progress,
|
|
255
|
+
start,
|
|
256
|
+
stop,
|
|
257
|
+
reset,
|
|
258
|
+
pause,
|
|
259
|
+
resume,
|
|
260
|
+
play,
|
|
261
|
+
reverse,
|
|
262
|
+
seek,
|
|
263
|
+
getValue
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=useMotion.js.map
|