@hua-labs/motion-core 2.0.0 → 2.1.0-alpha.0.1

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.
Files changed (130) hide show
  1. package/README.md +16 -19
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/core/MotionEngine.d.ts +111 -0
  4. package/dist/core/MotionEngine.d.ts.map +1 -0
  5. package/dist/core/MotionEngine.js +206 -0
  6. package/dist/core/MotionEngine.js.map +1 -0
  7. package/dist/core/PerformanceOptimizer.d.ts +124 -0
  8. package/dist/core/PerformanceOptimizer.d.ts.map +1 -0
  9. package/dist/core/PerformanceOptimizer.js +334 -0
  10. package/dist/core/PerformanceOptimizer.js.map +1 -0
  11. package/dist/core/TransitionEffects.d.ts +76 -0
  12. package/dist/core/TransitionEffects.d.ts.map +1 -0
  13. package/dist/core/TransitionEffects.js +321 -0
  14. package/dist/core/TransitionEffects.js.map +1 -0
  15. package/dist/hooks/useBounceIn.d.ts +11 -2
  16. package/dist/hooks/useBounceIn.d.ts.map +1 -1
  17. package/dist/hooks/useBounceIn.js +48 -114
  18. package/dist/hooks/useBounceIn.js.map +1 -1
  19. package/dist/hooks/useClickToggle.d.ts +28 -13
  20. package/dist/hooks/useClickToggle.d.ts.map +1 -1
  21. package/dist/hooks/useClickToggle.js +125 -90
  22. package/dist/hooks/useClickToggle.js.map +1 -1
  23. package/dist/hooks/useFadeIn.d.ts +0 -14
  24. package/dist/hooks/useFadeIn.d.ts.map +1 -1
  25. package/dist/hooks/useFadeIn.js +17 -43
  26. package/dist/hooks/useFadeIn.js.map +1 -1
  27. package/dist/hooks/useFocusToggle.d.ts +28 -13
  28. package/dist/hooks/useFocusToggle.d.ts.map +1 -1
  29. package/dist/hooks/useFocusToggle.js +125 -87
  30. package/dist/hooks/useFocusToggle.js.map +1 -1
  31. package/dist/hooks/useGesture.d.ts +45 -0
  32. package/dist/hooks/useGesture.d.ts.map +1 -0
  33. package/dist/hooks/useGesture.js +274 -0
  34. package/dist/hooks/useGesture.js.map +1 -0
  35. package/dist/hooks/useGestureMotion.d.ts +26 -0
  36. package/dist/hooks/useGestureMotion.d.ts.map +1 -0
  37. package/dist/hooks/useGestureMotion.js +167 -0
  38. package/dist/hooks/useGestureMotion.js.map +1 -0
  39. package/dist/hooks/useGradient.d.ts +10 -21
  40. package/dist/hooks/useGradient.d.ts.map +1 -1
  41. package/dist/hooks/useGradient.js +70 -127
  42. package/dist/hooks/useGradient.js.map +1 -1
  43. package/dist/hooks/useHoverMotion.d.ts +4 -14
  44. package/dist/hooks/useHoverMotion.d.ts.map +1 -1
  45. package/dist/hooks/useHoverMotion.js +31 -82
  46. package/dist/hooks/useHoverMotion.js.map +1 -1
  47. package/dist/hooks/useMotionState.d.ts +27 -24
  48. package/dist/hooks/useMotionState.d.ts.map +1 -1
  49. package/dist/hooks/useMotionState.js +186 -103
  50. package/dist/hooks/useMotionState.js.map +1 -1
  51. package/dist/hooks/usePageMotions.d.ts +17 -0
  52. package/dist/hooks/usePageMotions.d.ts.map +1 -0
  53. package/dist/hooks/usePageMotions.js +352 -0
  54. package/dist/hooks/usePageMotions.js.map +1 -0
  55. package/dist/hooks/usePulse.d.ts +8 -1
  56. package/dist/hooks/usePulse.d.ts.map +1 -1
  57. package/dist/hooks/usePulse.js +75 -101
  58. package/dist/hooks/usePulse.js.map +1 -1
  59. package/dist/hooks/useRepeat.d.ts +17 -22
  60. package/dist/hooks/useRepeat.d.ts.map +1 -1
  61. package/dist/hooks/useRepeat.js +48 -162
  62. package/dist/hooks/useRepeat.js.map +1 -1
  63. package/dist/hooks/useScaleIn.d.ts +12 -2
  64. package/dist/hooks/useScaleIn.d.ts.map +1 -1
  65. package/dist/hooks/useScaleIn.js +46 -85
  66. package/dist/hooks/useScaleIn.js.map +1 -1
  67. package/dist/hooks/useScrollProgress.d.ts +8 -18
  68. package/dist/hooks/useScrollProgress.d.ts.map +1 -1
  69. package/dist/hooks/useScrollProgress.js +28 -130
  70. package/dist/hooks/useScrollProgress.js.map +1 -1
  71. package/dist/hooks/useScrollReveal.d.ts +12 -15
  72. package/dist/hooks/useScrollReveal.d.ts.map +1 -1
  73. package/dist/hooks/useScrollReveal.js +93 -72
  74. package/dist/hooks/useScrollReveal.js.map +1 -1
  75. package/dist/hooks/useSimplePageMotion.d.ts +29 -0
  76. package/dist/hooks/useSimplePageMotion.d.ts.map +1 -0
  77. package/dist/hooks/useSimplePageMotion.js +145 -0
  78. package/dist/hooks/useSimplePageMotion.js.map +1 -0
  79. package/dist/hooks/useSlideLeft.d.ts +12 -2
  80. package/dist/hooks/useSlideLeft.d.ts.map +1 -1
  81. package/dist/hooks/useSlideLeft.js +46 -85
  82. package/dist/hooks/useSlideLeft.js.map +1 -1
  83. package/dist/hooks/useSlideRight.d.ts +12 -2
  84. package/dist/hooks/useSlideRight.d.ts.map +1 -1
  85. package/dist/hooks/useSlideRight.js +46 -85
  86. package/dist/hooks/useSlideRight.js.map +1 -1
  87. package/dist/hooks/useSlideUp.d.ts.map +1 -1
  88. package/dist/hooks/useSlideUp.js +40 -29
  89. package/dist/hooks/useSlideUp.js.map +1 -1
  90. package/dist/hooks/useSmartMotion.d.ts +31 -0
  91. package/dist/hooks/useSmartMotion.d.ts.map +1 -0
  92. package/dist/hooks/useSmartMotion.js +257 -0
  93. package/dist/hooks/useSmartMotion.js.map +1 -0
  94. package/dist/hooks/useSpringMotion.d.ts +14 -24
  95. package/dist/hooks/useSpringMotion.d.ts.map +1 -1
  96. package/dist/hooks/useSpringMotion.js +109 -161
  97. package/dist/hooks/useSpringMotion.js.map +1 -1
  98. package/dist/hooks/useToggleMotion.d.ts +16 -0
  99. package/dist/hooks/useToggleMotion.d.ts.map +1 -0
  100. package/dist/hooks/useToggleMotion.js +53 -0
  101. package/dist/hooks/useToggleMotion.js.map +1 -0
  102. package/dist/hooks/useUnifiedMotion.d.ts +51 -0
  103. package/dist/hooks/useUnifiedMotion.d.ts.map +1 -0
  104. package/dist/hooks/useUnifiedMotion.js +106 -0
  105. package/dist/hooks/useUnifiedMotion.js.map +1 -0
  106. package/dist/index.d.ts +14 -10
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +37 -17
  109. package/dist/index.js.map +1 -1
  110. package/dist/managers/MotionStateManager.d.ts +63 -0
  111. package/dist/managers/MotionStateManager.d.ts.map +1 -0
  112. package/dist/managers/MotionStateManager.js +159 -0
  113. package/dist/managers/MotionStateManager.js.map +1 -0
  114. package/dist/presets/index.d.ts +16 -0
  115. package/dist/presets/index.d.ts.map +1 -0
  116. package/dist/presets/index.js +120 -0
  117. package/dist/presets/index.js.map +1 -0
  118. package/dist/types/common.d.ts +155 -0
  119. package/dist/types/common.d.ts.map +1 -0
  120. package/dist/types/common.js +5 -0
  121. package/dist/types/common.js.map +1 -0
  122. package/dist/types/index.d.ts +63 -95
  123. package/dist/types/index.d.ts.map +1 -1
  124. package/dist/types/index.js +2 -2
  125. package/dist/types/index.js.map +1 -1
  126. package/dist/utils/easing.d.ts +80 -26
  127. package/dist/utils/easing.d.ts.map +1 -1
  128. package/dist/utils/easing.js +202 -67
  129. package/dist/utils/easing.js.map +1 -1
  130. package/package.json +15 -15
@@ -0,0 +1,167 @@
1
+ import { useRef, useEffect, useState, useCallback } from 'react';
2
+ export function useGestureMotion(options) {
3
+ const { gestureType, duration = 300, easing = 'ease-out', sensitivity = 1, enabled = true, onGestureStart, onGestureEnd } = options;
4
+ const elementRef = useRef(null);
5
+ const [gestureState, setGestureState] = useState({
6
+ isActive: false,
7
+ x: 0,
8
+ y: 0,
9
+ deltaX: 0,
10
+ deltaY: 0,
11
+ scale: 1,
12
+ rotation: 0
13
+ });
14
+ const [motionStyle, setMotionStyle] = useState({});
15
+ // 제스처 시작점 저장
16
+ const startPoint = useRef({ x: 0, y: 0 });
17
+ const isDragging = useRef(false);
18
+ // 모션 스타일 업데이트
19
+ const updateMotionStyle = useCallback(() => {
20
+ if (!enabled)
21
+ return;
22
+ const { isActive, deltaX, deltaY, scale, rotation } = gestureState;
23
+ let transform = '';
24
+ switch (gestureType) {
25
+ case 'hover':
26
+ transform = isActive
27
+ ? `scale(${1 + sensitivity * 0.05}) translateY(-${sensitivity * 2}px)`
28
+ : 'scale(1) translateY(0)';
29
+ break;
30
+ case 'drag':
31
+ transform = isActive
32
+ ? `translate(${deltaX * sensitivity}px, ${deltaY * sensitivity}px)`
33
+ : 'translate(0, 0)';
34
+ break;
35
+ case 'pinch':
36
+ transform = `scale(${scale})`;
37
+ break;
38
+ case 'swipe':
39
+ transform = isActive
40
+ ? `translateX(${deltaX * sensitivity}px) rotateY(${deltaX * 0.1}deg)`
41
+ : 'translateX(0) rotateY(0)';
42
+ break;
43
+ case 'tilt':
44
+ transform = isActive
45
+ ? `rotateX(${deltaY * 0.1}deg) rotateY(${deltaX * 0.1}deg)`
46
+ : 'rotateX(0) rotateY(0)';
47
+ break;
48
+ }
49
+ setMotionStyle({
50
+ transform,
51
+ transition: isActive ? 'none' : `all ${duration}ms ${easing}`,
52
+ cursor: gestureType === 'drag' && isActive ? 'grabbing' : 'pointer'
53
+ });
54
+ }, [gestureState, gestureType, enabled, duration, easing, sensitivity]);
55
+ // 마우스 이벤트 핸들러
56
+ const handleMouseDown = useCallback((e) => {
57
+ if (!enabled || gestureType !== 'drag')
58
+ return;
59
+ isDragging.current = true;
60
+ startPoint.current = { x: e.clientX, y: e.clientY };
61
+ setGestureState(prev => ({ ...prev, isActive: true }));
62
+ onGestureStart?.();
63
+ }, [enabled, gestureType, onGestureStart]);
64
+ const handleMouseMove = useCallback((e) => {
65
+ if (!enabled || !isDragging.current)
66
+ return;
67
+ const deltaX = e.clientX - startPoint.current.x;
68
+ const deltaY = e.clientY - startPoint.current.y;
69
+ setGestureState(prev => ({
70
+ ...prev,
71
+ x: e.clientX,
72
+ y: e.clientY,
73
+ deltaX,
74
+ deltaY
75
+ }));
76
+ }, [enabled]);
77
+ const handleMouseUp = useCallback(() => {
78
+ if (!enabled)
79
+ return;
80
+ isDragging.current = false;
81
+ setGestureState(prev => ({ ...prev, isActive: false }));
82
+ onGestureEnd?.();
83
+ }, [enabled, onGestureEnd]);
84
+ // 호버 이벤트 핸들러
85
+ const handleMouseEnter = useCallback(() => {
86
+ if (!enabled || gestureType !== 'hover')
87
+ return;
88
+ setGestureState(prev => ({ ...prev, isActive: true }));
89
+ onGestureStart?.();
90
+ }, [enabled, gestureType, onGestureStart]);
91
+ const handleMouseLeave = useCallback(() => {
92
+ if (!enabled || gestureType !== 'hover')
93
+ return;
94
+ setGestureState(prev => ({ ...prev, isActive: false }));
95
+ onGestureEnd?.();
96
+ }, [enabled, gestureType, onGestureEnd]);
97
+ // 터치 이벤트 핸들러 (모바일 지원)
98
+ const handleTouchStart = useCallback((e) => {
99
+ if (!enabled)
100
+ return;
101
+ const touch = e.touches[0];
102
+ startPoint.current = { x: touch.clientX, y: touch.clientY };
103
+ setGestureState(prev => ({ ...prev, isActive: true }));
104
+ onGestureStart?.();
105
+ }, [enabled, onGestureStart]);
106
+ const handleTouchMove = useCallback((e) => {
107
+ if (!enabled)
108
+ return;
109
+ const touch = e.touches[0];
110
+ const deltaX = touch.clientX - startPoint.current.x;
111
+ const deltaY = touch.clientY - startPoint.current.y;
112
+ setGestureState(prev => ({
113
+ ...prev,
114
+ x: touch.clientX,
115
+ y: touch.clientY,
116
+ deltaX,
117
+ deltaY
118
+ }));
119
+ }, [enabled]);
120
+ const handleTouchEnd = useCallback(() => {
121
+ if (!enabled)
122
+ return;
123
+ setGestureState(prev => ({ ...prev, isActive: false }));
124
+ onGestureEnd?.();
125
+ }, [enabled, onGestureEnd]);
126
+ // 이벤트 리스너 등록
127
+ useEffect(() => {
128
+ if (!elementRef.current)
129
+ return;
130
+ const element = elementRef.current;
131
+ // 마우스 이벤트
132
+ if (gestureType === 'hover') {
133
+ element.addEventListener('mouseenter', handleMouseEnter);
134
+ element.addEventListener('mouseleave', handleMouseLeave);
135
+ }
136
+ else if (gestureType === 'drag') {
137
+ element.addEventListener('mousedown', handleMouseDown);
138
+ document.addEventListener('mousemove', handleMouseMove);
139
+ document.addEventListener('mouseup', handleMouseUp);
140
+ }
141
+ // 터치 이벤트
142
+ element.addEventListener('touchstart', handleTouchStart);
143
+ element.addEventListener('touchmove', handleTouchMove);
144
+ element.addEventListener('touchend', handleTouchEnd);
145
+ return () => {
146
+ element.removeEventListener('mouseenter', handleMouseEnter);
147
+ element.removeEventListener('mouseleave', handleMouseLeave);
148
+ element.removeEventListener('mousedown', handleMouseDown);
149
+ document.removeEventListener('mousemove', handleMouseMove);
150
+ document.removeEventListener('mouseup', handleMouseUp);
151
+ element.removeEventListener('touchstart', handleTouchStart);
152
+ element.removeEventListener('touchmove', handleTouchMove);
153
+ element.removeEventListener('touchend', handleTouchEnd);
154
+ };
155
+ }, [gestureType, handleMouseEnter, handleMouseLeave, handleMouseDown, handleMouseMove, handleMouseUp, handleTouchStart, handleTouchMove, handleTouchEnd]);
156
+ // 모션 스타일 업데이트
157
+ useEffect(() => {
158
+ updateMotionStyle();
159
+ }, [updateMotionStyle]);
160
+ return {
161
+ ref: elementRef,
162
+ gestureState,
163
+ motionStyle,
164
+ isActive: gestureState.isActive
165
+ };
166
+ }
167
+ //# sourceMappingURL=useGestureMotion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGestureMotion.js","sourceRoot":"","sources":["../../src/hooks/useGestureMotion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAsBhE,MAAM,UAAU,gBAAgB,CAAC,OAA6B;IAC5D,MAAM,EACJ,WAAW,EACX,QAAQ,GAAG,GAAG,EACd,MAAM,GAAG,UAAU,EACnB,WAAW,GAAG,CAAC,EACf,OAAO,GAAG,IAAI,EACd,cAAc,EACd,YAAY,EACb,GAAG,OAAO,CAAA;IAEX,MAAM,UAAU,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAA;IACnD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAe;QAC7D,QAAQ,EAAE,KAAK;QACf,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,MAAM,EAAE,CAAC;QACT,MAAM,EAAE,CAAC;QACT,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAA;IACF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAsB,EAAE,CAAC,CAAA;IAEvE,aAAa;IACb,MAAM,UAAU,GAAG,MAAM,CAA2B,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACnE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAEhC,cAAc;IACd,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAA;QAElE,IAAI,SAAS,GAAG,EAAE,CAAA;QAElB,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,OAAO;gBACV,SAAS,GAAG,QAAQ;oBAClB,CAAC,CAAC,SAAS,CAAC,GAAG,WAAW,GAAG,IAAI,iBAAiB,WAAW,GAAG,CAAC,KAAK;oBACtE,CAAC,CAAC,wBAAwB,CAAA;gBAC5B,MAAK;YAEP,KAAK,MAAM;gBACT,SAAS,GAAG,QAAQ;oBAClB,CAAC,CAAC,aAAa,MAAM,GAAG,WAAW,OAAO,MAAM,GAAG,WAAW,KAAK;oBACnE,CAAC,CAAC,iBAAiB,CAAA;gBACrB,MAAK;YAEP,KAAK,OAAO;gBACV,SAAS,GAAG,SAAS,KAAK,GAAG,CAAA;gBAC7B,MAAK;YAEP,KAAK,OAAO;gBACV,SAAS,GAAG,QAAQ;oBAClB,CAAC,CAAC,cAAc,MAAM,GAAG,WAAW,eAAe,MAAM,GAAG,GAAG,MAAM;oBACrE,CAAC,CAAC,0BAA0B,CAAA;gBAC9B,MAAK;YAEP,KAAK,MAAM;gBACT,SAAS,GAAG,QAAQ;oBAClB,CAAC,CAAC,WAAW,MAAM,GAAG,GAAG,gBAAgB,MAAM,GAAG,GAAG,MAAM;oBAC3D,CAAC,CAAC,uBAAuB,CAAA;gBAC3B,MAAK;QACT,CAAC;QAED,cAAc,CAAC;YACb,SAAS;YACT,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,QAAQ,MAAM,MAAM,EAAE;YAC7D,MAAM,EAAE,WAAW,KAAK,MAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;SACpE,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAA;IAEvE,cAAc;IACd,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAa,EAAE,EAAE;QACpD,IAAI,CAAC,OAAO,IAAI,WAAW,KAAK,MAAM;YAAE,OAAM;QAE9C,UAAU,CAAC,OAAO,GAAG,IAAI,CAAA;QACzB,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAA;QAEnD,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACtD,cAAc,EAAE,EAAE,CAAA;IACpB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAA;IAE1C,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAa,EAAE,EAAE;QACpD,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAM;QAE3C,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QAC/C,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QAE/C,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvB,GAAG,IAAI;YACP,CAAC,EAAE,CAAC,CAAC,OAAO;YACZ,CAAC,EAAE,CAAC,CAAC,OAAO;YACZ,MAAM;YACN,MAAM;SACP,CAAC,CAAC,CAAA;IACL,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,UAAU,CAAC,OAAO,GAAG,KAAK,CAAA;QAC1B,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QACvD,YAAY,EAAE,EAAE,CAAA;IAClB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAA;IAE3B,aAAa;IACb,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,IAAI,CAAC,OAAO,IAAI,WAAW,KAAK,OAAO;YAAE,OAAM;QAE/C,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACtD,cAAc,EAAE,EAAE,CAAA;IACpB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAA;IAE1C,MAAM,gBAAgB,GAAG,WAAW,CAAC,GAAG,EAAE;QACxC,IAAI,CAAC,OAAO,IAAI,WAAW,KAAK,OAAO;YAAE,OAAM;QAE/C,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QACvD,YAAY,EAAE,EAAE,CAAA;IAClB,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;IAExC,sBAAsB;IACtB,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAa,EAAE,EAAE;QACrD,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC1B,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,CAAA;QAE3D,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACtD,cAAc,EAAE,EAAE,CAAA;IACpB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAA;IAE7B,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,CAAa,EAAE,EAAE;QACpD,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;QAEnD,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvB,GAAG,IAAI;YACP,CAAC,EAAE,KAAK,CAAC,OAAO;YAChB,CAAC,EAAE,KAAK,CAAC,OAAO;YAChB,MAAM;YACN,MAAM;SACP,CAAC,CAAC,CAAA;IACL,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;IAEb,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;QACtC,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QACvD,YAAY,EAAE,EAAE,CAAA;IAClB,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAA;IAE3B,aAAa;IACb,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAM;QAE/B,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAA;QAElC,UAAU;QACV,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO,CAAC,gBAAgB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;YACxD,OAAO,CAAC,gBAAgB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;QAC1D,CAAC;aAAM,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YACtD,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YACvD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;QACrD,CAAC;QAED,SAAS;QACT,OAAO,CAAC,gBAAgB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;QACxD,OAAO,CAAC,gBAAgB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;QACtD,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QAEpD,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,mBAAmB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;YAC3D,OAAO,CAAC,mBAAmB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;YAC3D,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YACzD,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YAC1D,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;YACtD,OAAO,CAAC,mBAAmB,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAA;YAC3D,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAA;YACzD,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAA;QACzD,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC,CAAA;IAEzJ,cAAc;IACd,SAAS,CAAC,GAAG,EAAE;QACb,iBAAiB,EAAE,CAAA;IACrB,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAEvB,OAAO;QACL,GAAG,EAAE,UAAU;QACf,YAAY;QACZ,WAAW;QACX,QAAQ,EAAE,YAAY,CAAC,QAAQ;KAChC,CAAA;AACH,CAAC"}
@@ -1,25 +1,14 @@
1
- import { BaseMotionOptions, BaseMotionReturn, MotionElement } from '../types';
2
- export interface GradientOptions extends BaseMotionOptions {
3
- colors: string[];
4
- direction?: 'to-right' | 'to-left' | 'to-bottom' | 'to-top' | 'to-bottom-right' | 'to-bottom-left' | 'to-top-right' | 'to-top-left';
5
- gradientType?: 'linear' | 'radial';
6
- startPosition?: number;
7
- endPosition?: number;
8
- animateColors?: boolean;
9
- animateDirection?: boolean;
10
- animatePosition?: boolean;
11
- colorTransitionDuration?: number;
12
- directionTransitionDuration?: number;
13
- positionTransitionDuration?: number;
1
+ import { BaseMotionReturn, MotionElement } from '../types';
2
+ export interface GradientOptions {
3
+ colors?: string[];
4
+ duration?: number;
5
+ direction?: 'horizontal' | 'vertical' | 'diagonal';
6
+ size?: number;
7
+ easing?: 'linear' | 'ease-in-out' | 'ease-in' | 'ease-out';
14
8
  autoStart?: boolean;
15
9
  }
16
- export declare function useGradient<T extends MotionElement = HTMLDivElement>(options: GradientOptions): BaseMotionReturn<T> & {
17
- currentColors: string[];
18
- currentDirection: string;
19
- currentStartPosition: number;
20
- currentEndPosition: number;
21
- setColors: (colors: string[]) => void;
22
- setDirection: (direction: 'to-right' | 'to-left' | 'to-bottom' | 'to-top' | 'to-bottom-right' | 'to-bottom-left' | 'to-top-right' | 'to-top-left') => void;
23
- setPositions: (start: number, end: number) => void;
10
+ export declare function useGradient<T extends MotionElement = HTMLDivElement>(options?: GradientOptions): BaseMotionReturn<T> & {
11
+ style: React.CSSProperties;
24
12
  };
13
+ export declare const createGradientKeyframes: (name?: string) => void;
25
14
  //# sourceMappingURL=useGradient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useGradient.d.ts","sourceRoot":"","sources":["../../src/hooks/useGradient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE7E,MAAM,WAAW,eAAgB,SAAQ,iBAAiB;IACxD,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,SAAS,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,cAAc,GAAG,aAAa,CAAA;IACnI,YAAY,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAClC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,aAAa,GAAG,cAAc,EAClE,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAAC,CAAC,CAAC,GAAG;IACvB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,gBAAgB,EAAE,MAAM,CAAA;IACxB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,CAAC,SAAS,EAAE,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,iBAAiB,GAAG,gBAAgB,GAAG,cAAc,GAAG,aAAa,KAAK,IAAI,CAAA;IAC1J,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CACnD,CAkLA"}
1
+ {"version":3,"file":"useGradient.d.ts","sourceRoot":"","sources":["../../src/hooks/useGradient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAa,MAAM,UAAU,CAAA;AAErE,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,YAAY,GAAG,UAAU,GAAG,UAAU,CAAA;IAClD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAA;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAID,wBAAgB,WAAW,CAAC,CAAC,SAAS,aAAa,GAAG,cAAc,EAClE,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CAAC,CAAC,CAAC,GAAG;IACvB,KAAK,EAAE,KAAK,CAAC,aAAa,CAAA;CAC3B,CAsFA;AAGD,eAAO,MAAM,uBAAuB,GAAI,OAAM,MAAwB,SAarE,CAAA"}
@@ -1,144 +1,87 @@
1
- import { useRef, useState, useEffect, useCallback } from 'react';
2
- export function useGradient(options) {
3
- const { duration = 1000, easing = 'ease-in-out', colors, direction = 'to-right', gradientType = 'linear', startPosition = 0, endPosition = 100, animateColors = true, animateDirection = false, animatePosition = false, colorTransitionDuration = 1000, directionTransitionDuration = 500, positionTransitionDuration = 800, autoStart = 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 [currentColors, setCurrentColors] = useState(colors);
9
- const [currentDirection, setCurrentDirection] = useState(direction);
10
- const [currentStartPosition, setCurrentStartPosition] = useState(startPosition);
11
- const [currentEndPosition, setCurrentEndPosition] = useState(endPosition);
12
- // 색상 변경 함수
13
- const setColors = useCallback((newColors) => {
14
- if (!animateColors) {
15
- setCurrentColors(newColors);
16
- return;
17
- }
18
- setIsAnimating(true);
19
- setProgress(0);
20
- onStart?.();
21
- setTimeout(() => {
22
- setCurrentColors(newColors);
23
- setIsAnimating(false);
24
- setProgress(1);
25
- onComplete?.();
26
- }, colorTransitionDuration);
27
- }, [animateColors, colorTransitionDuration, onStart, onComplete]);
28
- // 방향 변경 함수
29
- const setDirection = useCallback((newDirection) => {
30
- if (!animateDirection) {
31
- setCurrentDirection(newDirection);
32
- return;
33
- }
34
- setIsAnimating(true);
35
- setProgress(0);
36
- onStart?.();
37
- setTimeout(() => {
38
- setCurrentDirection(newDirection);
39
- setIsAnimating(false);
40
- setProgress(1);
41
- onComplete?.();
42
- }, directionTransitionDuration);
43
- }, [animateDirection, directionTransitionDuration, onStart, onComplete]);
44
- // 위치 변경 함수
45
- const setPositions = useCallback((start, end) => {
46
- if (!animatePosition) {
47
- setCurrentStartPosition(start);
48
- setCurrentEndPosition(end);
49
- return;
50
- }
51
- setIsAnimating(true);
52
- setProgress(0);
53
- onStart?.();
54
- setTimeout(() => {
55
- setCurrentStartPosition(start);
56
- setCurrentEndPosition(end);
57
- setIsAnimating(false);
58
- setProgress(1);
59
- onComplete?.();
60
- }, positionTransitionDuration);
61
- }, [animatePosition, positionTransitionDuration, onStart, onComplete]);
62
- // 모션 시작 함수
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ const defaultColors = ['#60a5fa', '#34d399', '#fbbf24', '#f87171'];
3
+ export function useGradient(options = {}) {
4
+ const { colors = defaultColors, duration = 6000, direction = 'diagonal', size = 300, easing = 'ease-in-out', autoStart = false } = options;
5
+ const [isAnimating, setIsAnimating] = useState(autoStart);
6
+ const [isVisible, setIsVisible] = useState(true);
7
+ const [motionProgress, setMotionProgress] = useState(0);
8
+ const getGradientStyle = useCallback(() => {
9
+ const gradientDirection = direction === 'horizontal' ? '90deg' :
10
+ direction === 'vertical' ? '180deg' : '135deg';
11
+ const background = `linear-gradient(${gradientDirection}, ${colors.join(', ')})`;
12
+ const backgroundSize = `${size}% ${size}%`;
13
+ const easingFunction = easing === 'linear' ? 'linear' :
14
+ easing === 'ease-in' ? 'ease-in' :
15
+ easing === 'ease-out' ? 'ease-out' : 'ease-in-out';
16
+ return {
17
+ background,
18
+ backgroundSize,
19
+ animation: isAnimating ? `gradientShift ${duration}ms ${easingFunction} infinite` : 'none',
20
+ backgroundPosition: isAnimating ? undefined : `${motionProgress}% 50%`
21
+ };
22
+ }, [colors, direction, size, duration, easing, isAnimating, motionProgress]);
63
23
  const start = useCallback(() => {
64
- if (!isVisible) {
65
- setIsVisible(true);
66
- setIsAnimating(true);
67
- setProgress(0);
68
- onStart?.();
69
- setTimeout(() => {
70
- setIsAnimating(false);
71
- setProgress(1);
72
- onComplete?.();
73
- }, duration);
74
- }
75
- }, [isVisible, duration, onStart, onComplete]);
76
- // 모션 중단 함수
77
- const stop = useCallback(() => {
24
+ setIsAnimating(true);
25
+ }, []);
26
+ const pause = useCallback(() => {
78
27
  setIsAnimating(false);
79
- onStop?.();
80
- }, [onStop]);
81
- // 모션 리셋 함수
28
+ }, []);
29
+ const resume = useCallback(() => {
30
+ setIsAnimating(true);
31
+ }, []);
82
32
  const reset = useCallback(() => {
83
- setIsVisible(false);
33
+ // 모션 완전 정지
84
34
  setIsAnimating(false);
85
- setProgress(0);
86
- setCurrentColors(colors);
87
- setCurrentDirection(direction);
88
- setCurrentStartPosition(startPosition);
89
- setCurrentEndPosition(endPosition);
90
- onReset?.();
91
- }, [colors, direction, startPosition, endPosition, onReset]);
92
- // 모션 일시정지 함수
93
- const pause = useCallback(() => {
35
+ // 진행률 초기화
36
+ setMotionProgress(0);
37
+ }, []);
38
+ const stop = useCallback(() => {
94
39
  setIsAnimating(false);
95
40
  }, []);
96
- // 모션 재개 함수
97
- const resume = useCallback(() => {
98
- if (isVisible) {
99
- setIsAnimating(true);
100
- }
101
- }, [isVisible]);
102
- // 자동 시작
103
41
  useEffect(() => {
104
- if (autoStart) {
105
- start();
106
- }
107
- }, [autoStart, start]);
108
- // 그라데이션 스타일 생성
109
- const getGradientStyle = () => {
110
- let background;
111
- if (gradientType === 'radial') {
112
- background = `radial-gradient(circle at ${currentStartPosition}% ${currentEndPosition}%, ${currentColors.join(', ')})`;
113
- }
114
- else {
115
- background = `linear-gradient(${currentDirection}, ${currentColors.join(', ')})`;
42
+ if (!isAnimating) {
43
+ const interval = setInterval(() => {
44
+ setMotionProgress(prev => {
45
+ const newProgress = prev + (100 / (duration / 16)); // 60fps 기준
46
+ return newProgress >= 100 ? 0 : newProgress;
47
+ });
48
+ }, 16);
49
+ return () => clearInterval(interval);
116
50
  }
117
- return {
118
- background,
119
- transition: `all ${duration}ms ${easing}`,
120
- willChange: 'background'
121
- };
122
- };
123
- const style = getGradientStyle();
51
+ }, [isAnimating, duration]);
52
+ // 초기 상태 설정만 하고 이후에는 수동으로 제어
53
+ useEffect(() => {
54
+ setIsAnimating(autoStart);
55
+ }, [autoStart]);
124
56
  return {
125
- ref,
57
+ ref: { current: null }, // useGradient는 ref를 직접 사용하지 않음
126
58
  isVisible,
127
59
  isAnimating,
128
- style,
129
- progress,
60
+ style: getGradientStyle(),
61
+ progress: motionProgress / 100,
130
62
  start,
131
- stop,
132
- reset,
133
63
  pause,
134
64
  resume,
135
- currentColors,
136
- currentDirection,
137
- currentStartPosition,
138
- currentEndPosition,
139
- setColors,
140
- setDirection,
141
- setPositions
65
+ reset,
66
+ stop
142
67
  };
143
68
  }
69
+ // CSS 키프레임 생성 함수
70
+ export const createGradientKeyframes = (name = 'gradientShift') => {
71
+ const style = document.createElement('style');
72
+ style.textContent = `
73
+ @keyframes ${name} {
74
+ 0%, 100% { background-position: 0% 50%; }
75
+ 50% { background-position: 100% 50%; }
76
+ }
77
+ `;
78
+ if (!document.head.querySelector(`style[data-gradient="${name}"]`)) {
79
+ style.setAttribute('data-gradient', name);
80
+ document.head.appendChild(style);
81
+ }
82
+ };
83
+ // 자동으로 키프레임 생성
84
+ if (typeof document !== 'undefined') {
85
+ createGradientKeyframes();
86
+ }
144
87
  //# sourceMappingURL=useGradient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useGradient.js","sourceRoot":"","sources":["../../src/hooks/useGradient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useGradient.js","sourceRoot":"","sources":["../../src/hooks/useGradient.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,5 @@
1
- import { BaseMotionOptions, InteractionReturn, MotionElement } from '../types';
2
- export interface HoverMotionOptions extends BaseMotionOptions {
3
- hoverScale?: number;
4
- hoverOpacity?: number;
5
- hoverRotate?: number;
6
- hoverTranslateY?: number;
7
- hoverTranslateX?: number;
8
- initialScale?: number;
9
- initialOpacity?: number;
10
- initialRotate?: number;
11
- initialTranslateY?: number;
12
- initialTranslateX?: number;
13
- }
14
- export declare function useHoverMotion<T extends MotionElement = HTMLDivElement>(options?: HoverMotionOptions): InteractionReturn<T>;
1
+ export declare function useHoverMotion(motionHook: (() => any) | any, options?: {
2
+ onHover?: 'start' | 'reverse';
3
+ onLeave?: 'reverse' | 'reset';
4
+ }): any;
15
5
  //# sourceMappingURL=useHoverMotion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useHoverMotion.d.ts","sourceRoot":"","sources":["../../src/hooks/useHoverMotion.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAE9E,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,aAAa,GAAG,cAAc,EACrE,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAAC,CAAC,CAAC,CA4HtB"}
1
+ {"version":3,"file":"useHoverMotion.d.ts","sourceRoot":"","sources":["../../src/hooks/useHoverMotion.ts"],"names":[],"mappings":"AAEA,wBAAgB,cAAc,CAC5B,UAAU,EAAE,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,EAC7B,OAAO,GAAE;IACP,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC7B,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;CACzB,OAuDP"}
@@ -1,63 +1,30 @@
1
- import { useRef, useState, useCallback, useEffect } from 'react';
2
- export function useHoverMotion(options = {}) {
3
- const { duration = 300, easing = 'ease-out', hoverScale = 1.05, hoverOpacity = 1, hoverRotate = 0, hoverTranslateY = 0, hoverTranslateX = 0, initialScale = 1, initialOpacity = 1, initialRotate = 0, initialTranslateY = 0, initialTranslateX = 0, onComplete, onStart, onStop, onReset } = options;
4
- const ref = useRef(null);
5
- const [isHovered, setIsHovered] = useState(false);
6
- const [isAnimating, setIsAnimating] = useState(false);
7
- const [progress, setProgress] = useState(0);
8
- // 호버 시작
1
+ import { useRef, useEffect, useCallback } from 'react';
2
+ export function useHoverMotion(motionHook, options = {}) {
3
+ const { onHover = 'start', onLeave = 'reverse' } = options;
4
+ const elementRef = useRef(null);
5
+ const motionRef = useRef(null);
6
+ // motion 객체를 ref로 안정화
7
+ if (!motionRef.current) {
8
+ motionRef.current = typeof motionHook === 'function' ? motionHook() : motionHook;
9
+ }
9
10
  const handleMouseEnter = useCallback(() => {
10
- setIsHovered(true);
11
- setIsAnimating(true);
12
- setProgress(0);
13
- onStart?.();
14
- // 애니메이션 완료 시
15
- setTimeout(() => {
16
- setIsAnimating(false);
17
- setProgress(1);
18
- onComplete?.();
19
- }, duration);
20
- }, [duration, onStart, onComplete]);
21
- // 호버 종료
11
+ if (onHover === 'start') {
12
+ motionRef.current?.start();
13
+ }
14
+ else if (onHover === 'reverse') {
15
+ motionRef.current?.reset();
16
+ }
17
+ }, [onHover]);
22
18
  const handleMouseLeave = useCallback(() => {
23
- setIsHovered(false);
24
- setIsAnimating(true);
25
- setProgress(1);
26
- // 애니메이션 완료
27
- setTimeout(() => {
28
- setIsAnimating(false);
29
- setProgress(0);
30
- }, duration);
31
- }, [duration]);
32
- // 모션 시작 함수 (프로그래매틱 제어용)
33
- const start = useCallback(() => {
34
- handleMouseEnter();
35
- }, [handleMouseEnter]);
36
- // 모션 중단 함수
37
- const stop = useCallback(() => {
38
- setIsAnimating(false);
39
- onStop?.();
40
- }, [onStop]);
41
- // 모션 리셋 함수
42
- const reset = useCallback(() => {
43
- setIsHovered(false);
44
- setIsAnimating(false);
45
- setProgress(0);
46
- onReset?.();
47
- }, [onReset]);
48
- // 모션 일시정지 함수
49
- const pause = useCallback(() => {
50
- setIsAnimating(false);
51
- }, []);
52
- // 모션 재개 함수
53
- const resume = useCallback(() => {
54
- if (isHovered) {
55
- setIsAnimating(true);
19
+ if (onLeave === 'reverse') {
20
+ motionRef.current?.stop(); // stop 사용으로 현재 상태 유지
21
+ }
22
+ else if (onLeave === 'reset') {
23
+ motionRef.current?.reset(); // reset 사용으로 초기 상태로 복원
56
24
  }
57
- }, [isHovered]);
58
- // 이벤트 리스너 설정
25
+ }, [onLeave]);
59
26
  useEffect(() => {
60
- const element = ref.current;
27
+ const element = elementRef.current;
61
28
  if (!element)
62
29
  return;
63
30
  element.addEventListener('mouseenter', handleMouseEnter);
@@ -67,33 +34,15 @@ export function useHoverMotion(options = {}) {
67
34
  element.removeEventListener('mouseleave', handleMouseLeave);
68
35
  };
69
36
  }, [handleMouseEnter, handleMouseLeave]);
70
- // 스타일 계산
71
- const style = {
72
- transform: `
73
- scale(${isHovered ? hoverScale : initialScale})
74
- rotate(${isHovered ? hoverRotate : initialRotate}deg)
75
- translate(${isHovered ? hoverTranslateX : initialTranslateX}px, ${isHovered ? hoverTranslateY : initialTranslateY}px)
76
- `,
77
- opacity: isHovered ? hoverOpacity : initialOpacity,
78
- transition: `all ${duration}ms ${easing}`,
79
- willChange: 'transform, opacity'
80
- };
37
+ const setRef = useCallback((element) => {
38
+ elementRef.current = element;
39
+ if (motionRef.current?.ref) {
40
+ motionRef.current.ref(element);
41
+ }
42
+ }, []);
81
43
  return {
82
- ref,
83
- isVisible: isHovered,
84
- isAnimating,
85
- style,
86
- progress,
87
- start,
88
- stop,
89
- reset,
90
- pause,
91
- resume,
92
- // 새로운 직관적 API 추가
93
- hover: handleMouseEnter,
94
- leave: handleMouseLeave,
95
- // 상태 속성 추가
96
- isHovered
44
+ ...motionRef.current,
45
+ ref: setRef
97
46
  };
98
47
  }
99
48
  //# sourceMappingURL=useHoverMotion.js.map