@hua-labs/motion-core 2.2.3 → 2.4.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/dist/index.d.ts CHANGED
@@ -1,614 +1,9 @@
1
+ import { P as PageType, a as PageMotionRef, b as PageMotionsConfig, B as BaseMotionOptions, E as EntranceType, M as MotionElement, c as BaseMotionReturn, F as FadeInOptions, S as SlideOptions, d as ScaleOptions, e as BounceOptions, f as PulseOptions, g as SpringOptions, G as GradientOptions, H as HoverMotionOptions, h as ScrollRevealOptions, R as RepeatOptions, T as ToggleMotionOptions, I as InteractionReturn, i as InViewOptions, j as InViewReturn, k as MouseOptions, l as MouseReturn, m as ReducedMotionReturn, W as WindowSizeOptions, n as WindowSizeReturn, o as ScrollRevealMotionType } from './springPhysics-DLyZ4nbx.js';
2
+ export { p as BuiltInProfileName, D as DeepPartial, q as EasingFunction, r as EasingType, s as GestureConfig, t as GestureOptions, u as MOTION_PRESETS, v as MotionCallback, w as MotionConfig, x as MotionDirection, y as MotionEasing, z as MotionEngine, A as MotionFrame, C as MotionInstance, J as MotionOptions, K as MotionPreset, L as MotionProfile, N as MotionProfileBase, O as MotionProfileEntrance, Q as MotionProfileInteraction, U as MotionProfileProvider, V as MotionProfileProviderProps, X as MotionProfileSpring, Y as MotionProfileStagger, Z as MotionProgressCallback, _ as MotionState, $ as MotionStateCallback, a0 as MotionTrigger, a1 as MotionType, a2 as OrchestrationConfig, a3 as PAGE_MOTIONS, a4 as PageMotionElement, a5 as PerformanceMetrics, a6 as PresetConfig, a7 as ReducedMotionStrategy, a8 as SpringConfig, a9 as SpringPhysicsConfig, aa as SpringResult, ab as TransitionEffects, ac as TransitionOptions, ad as TransitionType, ae as applyEasing, af as calculateSpring, ag as easeIn, ah as easeInOut, ai as easeInOutQuad, aj as easeInQuad, ak as easeOut, al as easeOutQuad, am as easingPresets, an as getAvailableEasings, ao as getEasing, ap as getMotionPreset, aq as getPagePreset, ar as getPresetEasing, as as hua, at as isEasingFunction, au as isValidEasing, av as linear, aw as mergeProfileOverrides, ax as mergeWithPreset, ay as motionEngine, az as neutral, aA as resolveProfile, aB as safeApplyEasing, aC as transitionEffects, aD as useMotionProfile } from './springPhysics-DLyZ4nbx.js';
1
3
  import * as react from 'react';
2
4
  import react__default, { CSSProperties, RefObject } from 'react';
3
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
6
 
5
- /**
6
- * HUA Motion Core - 의존성 제로 모션 엔진
7
- *
8
- * 순수 JavaScript로 구현된 고성능 모션 엔진
9
- * GPU 가속, 레이어 분리, 성능 최적화 포함
10
- */
11
- interface MotionFrame {
12
- progress: number;
13
- properties: {
14
- opacity?: number;
15
- transform?: string;
16
- scale?: number;
17
- translateX?: number;
18
- translateY?: number;
19
- rotate?: number;
20
- rotateX?: number;
21
- rotateY?: number;
22
- rotateZ?: number;
23
- skewX?: number;
24
- skewY?: number;
25
- };
26
- }
27
- interface MotionOptions {
28
- duration: number;
29
- easing: (t: number) => number;
30
- delay?: number;
31
- direction?: 'forward' | 'reverse' | 'alternate';
32
- iterations?: number;
33
- fill?: 'none' | 'forwards' | 'backwards' | 'both';
34
- onStart?: () => void;
35
- onUpdate?: (progress: number) => void;
36
- onComplete?: () => void;
37
- onCancel?: () => void;
38
- }
39
- interface Motion$1 {
40
- id: string;
41
- element: HTMLElement;
42
- isRunning: boolean;
43
- isPaused: boolean;
44
- currentProgress: number;
45
- startTime: number;
46
- pauseTime: number;
47
- options: MotionOptions;
48
- }
49
- declare class MotionEngine {
50
- private motions;
51
- private isRunning;
52
- private animationFrameId;
53
- /**
54
- * 모션 시작
55
- */
56
- motion(element: HTMLElement, motionFrames: MotionFrame[], options: MotionOptions): Promise<string>;
57
- /**
58
- * 모션 중지
59
- */
60
- stop(motionId: string): void;
61
- /**
62
- * 모션 일시정지
63
- */
64
- pause(motionId: string): void;
65
- /**
66
- * 모션 재개
67
- */
68
- resume(motionId: string): void;
69
- /**
70
- * 모든 모션 중지
71
- */
72
- stopAll(): void;
73
- /**
74
- * 모션 상태 확인
75
- */
76
- getMotion(motionId: string): Motion$1 | undefined;
77
- /**
78
- * 실행 중인 모션 수
79
- */
80
- getActiveMotionCount(): number;
81
- /**
82
- * 애니메이션 루프 시작
83
- */
84
- private startAnimationLoop;
85
- /**
86
- * 애니메이션 루프 중지
87
- */
88
- private stopAnimationLoop;
89
- /**
90
- * 메인 애니메이션 루프
91
- */
92
- private animate;
93
- /**
94
- * 모션 프레임 적용
95
- */
96
- private applyMotionFrame;
97
- /**
98
- * GPU 가속 활성화
99
- */
100
- private enableGPUAcceleration;
101
- /**
102
- * 레이어 분리
103
- */
104
- private createLayer;
105
- /**
106
- * 고유 모션 ID 생성
107
- */
108
- private generateMotionId;
109
- /**
110
- * 정리
111
- */
112
- destroy(): void;
113
- }
114
- declare const motionEngine: MotionEngine;
115
-
116
- /**
117
- * HUA Motion Core - 전환 효과 시스템
118
- *
119
- * CSS Motion API를 활용한 고성능 전환 효과들
120
- * GPU 가속 및 레이어 분리 최적화 포함
121
- */
122
-
123
- type TransitionType = 'fade' | 'slide' | 'slide-up' | 'slide-down' | 'slide-left' | 'slide-right' | 'scale' | 'flip' | 'morph' | 'cube' | 'zoom';
124
- interface TransitionOptions extends Omit<MotionOptions, 'easing'> {
125
- type: TransitionType;
126
- easing?: (t: number) => number;
127
- distance?: number;
128
- scale?: number;
129
- perspective?: number;
130
- onTransitionStart?: () => void;
131
- onTransitionComplete?: () => void;
132
- }
133
- declare class TransitionEffects {
134
- private static instance;
135
- private activeTransitions;
136
- static getInstance(): TransitionEffects;
137
- /**
138
- * 페이드 인/아웃 전환
139
- */
140
- fade(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
141
- /**
142
- * 슬라이드 전환
143
- */
144
- slide(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
145
- /**
146
- * 스케일 전환
147
- */
148
- scale(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
149
- /**
150
- * 플립 전환 (3D 회전)
151
- */
152
- flip(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
153
- /**
154
- * 큐브 전환 (3D 큐브 회전)
155
- */
156
- cube(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
157
- /**
158
- * 모프 전환 (복합 변형)
159
- */
160
- morph(element: HTMLElement, options: Omit<TransitionOptions, 'type'>): Promise<void>;
161
- /**
162
- * 전환 중지
163
- */
164
- stopTransition(transitionId: string): void;
165
- /**
166
- * 모든 전환 중지
167
- */
168
- stopAllTransitions(): void;
169
- /**
170
- * 활성 전환 수 확인
171
- */
172
- getActiveTransitionCount(): number;
173
- /**
174
- * GPU 가속 활성화
175
- */
176
- private enableGPUAcceleration;
177
- /**
178
- * 기본 이징 함수
179
- */
180
- private getDefaultEasing;
181
- /**
182
- * 고유 전환 ID 생성
183
- */
184
- private generateTransitionId;
185
- /**
186
- * 정리
187
- */
188
- destroy(): void;
189
- }
190
- declare const transitionEffects: TransitionEffects;
191
-
192
- /**
193
- * HUA Motion Core - 성능 최적화 시스템
194
- *
195
- * GPU 가속, 레이어 관리, 메모리 최적화를 위한 유틸리티들
196
- * 브라우저별 최적화 전략 포함
197
- */
198
- interface PerformanceOptimizerMetrics {
199
- fps: number;
200
- memoryUsage?: number;
201
- gpuTime?: number;
202
- cpuTime?: number;
203
- layerCount: number;
204
- activeMotions: number;
205
- }
206
- interface OptimizationConfig {
207
- enableGPUAcceleration: boolean;
208
- enableLayerSeparation: boolean;
209
- enableMemoryOptimization: boolean;
210
- targetFPS: number;
211
- maxLayerCount: number;
212
- memoryThreshold: number;
213
- }
214
- declare class PerformanceOptimizer {
215
- private static instance;
216
- private config;
217
- private performanceObserver;
218
- private metrics;
219
- private layerRegistry;
220
- private isMonitoring;
221
- constructor();
222
- static getInstance(): PerformanceOptimizer;
223
- /**
224
- * 성능 모니터링 초기화
225
- */
226
- private initializePerformanceMonitoring;
227
- /**
228
- * 성능 메트릭 업데이트
229
- */
230
- private updatePerformanceMetrics;
231
- /**
232
- * FPS 계산
233
- */
234
- private calculateFPS;
235
- /**
236
- * GPU 가속 활성화
237
- */
238
- enableGPUAcceleration(element: HTMLElement): void;
239
- /**
240
- * 레이어 분리 및 최적화
241
- */
242
- createOptimizedLayer(element: HTMLElement): void;
243
- /**
244
- * 레이어 등록
245
- */
246
- private registerLayer;
247
- /**
248
- * 레이어 제거
249
- */
250
- removeLayer(element: HTMLElement): void;
251
- /**
252
- * 레이어 수 제한 체크
253
- */
254
- private checkLayerLimit;
255
- /**
256
- * 오래된 레이어 정리
257
- */
258
- private cleanupOldLayers;
259
- /**
260
- * 메모리 사용량 체크
261
- */
262
- private checkMemoryUsage;
263
- /**
264
- * 메모리 정리
265
- */
266
- private cleanupMemory;
267
- /**
268
- * 성능 최적화 설정 업데이트
269
- */
270
- updateConfig(newConfig: Partial<OptimizationConfig>): void;
271
- /**
272
- * 모든 GPU 가속 비활성화
273
- */
274
- private disableAllGPUAcceleration;
275
- /**
276
- * 모든 레이어 비활성화
277
- */
278
- private disableAllLayers;
279
- /**
280
- * 성능 메트릭 가져오기
281
- */
282
- getMetrics(): PerformanceOptimizerMetrics;
283
- /**
284
- * 성능 모니터링 시작
285
- */
286
- startMonitoring(): void;
287
- /**
288
- * 성능 모니터링 중지
289
- */
290
- stopMonitoring(): void;
291
- /**
292
- * 메트릭 업데이트
293
- */
294
- private updateMetrics;
295
- /**
296
- * 성능 리포트 생성
297
- */
298
- generateReport(): string;
299
- /**
300
- * 바이트 단위 포맷팅
301
- */
302
- private formatBytes;
303
- /**
304
- * 성능 최적화 권장사항
305
- */
306
- getOptimizationRecommendations(): string[];
307
- /**
308
- * 정리
309
- */
310
- destroy(): void;
311
- private lastFrameTime?;
312
- private monitoringInterval?;
313
- }
314
- declare const performanceOptimizer: PerformanceOptimizer;
315
-
316
- type MotionElement = HTMLDivElement | HTMLSpanElement | HTMLButtonElement | HTMLHeadingElement | HTMLParagraphElement | HTMLImageElement;
317
- type MotionStyle = CSSProperties & {
318
- '--motion-delay'?: string;
319
- '--motion-duration'?: string;
320
- '--motion-easing'?: string;
321
- '--motion-progress'?: string;
322
- };
323
- interface BaseMotionOptions {
324
- /** 모션 시작 지연 시간 (ms) */
325
- delay?: number;
326
- /** 모션 지속 시간 (ms) */
327
- duration?: number;
328
- /** Intersection Observer 임계값 (0-1) */
329
- threshold?: number;
330
- /** 한 번만 트리거할지 여부 */
331
- triggerOnce?: boolean;
332
- /** 이징 함수명 */
333
- easing?: string;
334
- /** 자동 시작 여부 */
335
- autoStart?: boolean;
336
- /** 모션 완료 시 콜백 */
337
- onComplete?: () => void;
338
- /** 모션 시작 시 콜백 */
339
- onStart?: () => void;
340
- /** 모션 중단 시 콜백 */
341
- onStop?: () => void;
342
- /** 모션 리셋 시 콜백 */
343
- onReset?: () => void;
344
- }
345
- interface BaseMotionReturn<T extends MotionElement = HTMLDivElement> {
346
- /** DOM 요소 참조 (React 19 호환) */
347
- ref: React.RefObject<T | null>;
348
- /** 요소가 화면에 보이는지 여부 */
349
- isVisible: boolean;
350
- /** 모션이 진행 중인지 여부 */
351
- isAnimating: boolean;
352
- /** 적용할 CSS 스타일 (React 19 호환) - useFadeIn 등에서는 항상 반환됨 */
353
- style: MotionStyle;
354
- /** 적용할 CSS 클래스명 */
355
- className?: string;
356
- /** 모션 진행률 (0-1) - useFadeIn 등에서는 항상 반환됨 */
357
- progress: number;
358
- /** 모션 시작 함수 - useFadeIn 등에서는 항상 반환됨 */
359
- start: () => void;
360
- /** 모션 리셋 함수 - useFadeIn 등에서는 항상 반환됨 */
361
- reset: () => void;
362
- /** 모션 중단 함수 - useFadeIn 등에서는 항상 반환됨 */
363
- stop: () => void;
364
- /** 모션 일시정지 함수 - 일부 훅에서만 제공 */
365
- pause?: () => void;
366
- /** 모션 재개 함수 - 일부 훅에서만 제공 */
367
- resume?: () => void;
368
- }
369
- interface InteractionReturn<T extends MotionElement = HTMLDivElement> extends BaseMotionReturn<T> {
370
- /** 가시성 토글 함수 */
371
- toggle?: () => void;
372
- /** 표시 함수 */
373
- show?: () => void;
374
- /** 숨김 함수 */
375
- hide?: () => void;
376
- }
377
- interface FadeInOptions extends BaseMotionOptions {
378
- /** 초기 투명도 */
379
- initialOpacity?: number;
380
- /** 목표 투명도 */
381
- targetOpacity?: number;
382
- }
383
- interface SlideOptions extends BaseMotionOptions {
384
- /** 슬라이드 방향 */
385
- direction?: 'up' | 'down' | 'left' | 'right';
386
- /** 슬라이드 거리 (px) */
387
- distance?: number;
388
- }
389
- interface ScaleOptions extends BaseMotionOptions {
390
- /** 초기 스케일 */
391
- initialScale?: number;
392
- /** 목표 스케일 */
393
- targetScale?: number;
394
- }
395
- interface BounceOptions extends BaseMotionOptions {
396
- /** 바운스 강도 */
397
- intensity?: number;
398
- /** 바운스 횟수 */
399
- bounces?: number;
400
- }
401
- interface PulseOptions extends BaseMotionOptions {
402
- /** 펄스 강도 */
403
- intensity?: number;
404
- /** 반복 횟수 (-1 = 무한) */
405
- repeatCount?: number;
406
- /** 반복 간격 (ms) */
407
- repeatDelay?: number;
408
- }
409
- interface SpringOptions extends BaseMotionOptions {
410
- /** 스프링 질량 */
411
- mass?: number;
412
- /** 스프링 강성 */
413
- stiffness?: number;
414
- /** 스프링 감쇠 */
415
- damping?: number;
416
- /** 정지 임계값 */
417
- restDelta?: number;
418
- /** 정지 속도 */
419
- restSpeed?: number;
420
- }
421
- interface GestureOptions$1 extends BaseMotionOptions {
422
- /** 호버 제스처 활성화 */
423
- hover?: boolean;
424
- /** 드래그 제스처 활성화 */
425
- drag?: boolean;
426
- /** 핀치 제스처 활성화 */
427
- pinch?: boolean;
428
- /** 스와이프 제스처 활성화 */
429
- swipe?: boolean;
430
- /** 틸트 제스처 활성화 */
431
- tilt?: boolean;
432
- }
433
- type MotionDirection$1 = 'up' | 'down' | 'left' | 'right';
434
- type MotionEasing = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'bounce' | 'elastic';
435
- type MotionTrigger = 'scroll' | 'click' | 'hover' | 'focus' | 'auto';
436
- type MotionCallback = () => void;
437
- type MotionProgressCallback = (progress: number) => void;
438
- type MotionStateCallback<T extends MotionElement = HTMLDivElement> = (state: BaseMotionReturn<T>) => void;
439
- interface PerformanceMetrics {
440
- /** 모션 시작 시간 */
441
- startTime: number;
442
- /** 모션 종료 시간 */
443
- endTime?: number;
444
- /** 총 지속 시간 */
445
- duration: number;
446
- /** FPS */
447
- fps: number;
448
- /** 메모리 사용량 */
449
- memoryUsage?: number;
450
- }
451
- interface MotionConfig {
452
- /** 성능 모니터링 활성화 */
453
- enablePerformanceMonitoring?: boolean;
454
- /** 디버그 모드 활성화 */
455
- debug?: boolean;
456
- /** 로그 레벨 */
457
- logLevel?: 'none' | 'error' | 'warn' | 'info' | 'debug';
458
- }
459
- interface InViewOptions {
460
- /** Intersection Observer 임계값 */
461
- threshold?: number | number[];
462
- /** 루트 마진 */
463
- rootMargin?: string;
464
- /** 한 번만 트리거할지 여부 */
465
- triggerOnce?: boolean;
466
- /** 초기 가시성 상태 */
467
- initialInView?: boolean;
468
- }
469
- interface InViewReturn<T extends HTMLElement = HTMLDivElement> {
470
- /** DOM 요소 참조 */
471
- ref: RefObject<T | null>;
472
- /** 요소가 화면에 보이는지 여부 */
473
- inView: boolean;
474
- /** IntersectionObserver 엔트리 */
475
- entry: IntersectionObserverEntry | null;
476
- }
477
- interface MouseOptions {
478
- /** 타겟 요소 참조 */
479
- targetRef?: RefObject<HTMLElement | null>;
480
- /** 스로틀 시간 (ms) */
481
- throttle?: number;
482
- }
483
- interface MouseReturn {
484
- /** 마우스 X 좌표 (viewport 기준) */
485
- x: number;
486
- /** 마우스 Y 좌표 (viewport 기준) */
487
- y: number;
488
- /** 요소 내 상대 X 좌표 (0-1) */
489
- elementX: number;
490
- /** 요소 내 상대 Y 좌표 (0-1) */
491
- elementY: number;
492
- /** 마우스가 타겟 위에 있는지 여부 */
493
- isOver: boolean;
494
- }
495
- interface ReducedMotionReturn {
496
- /** 사용자가 모션 감소를 선호하는지 여부 */
497
- prefersReducedMotion: boolean;
498
- }
499
- interface WindowSizeOptions {
500
- /** 디바운스 시간 (ms) */
501
- debounce?: number;
502
- /** 초기 너비 */
503
- initialWidth?: number;
504
- /** 초기 높이 */
505
- initialHeight?: number;
506
- }
507
- interface WindowSizeReturn {
508
- /** 윈도우 너비 */
509
- width: number;
510
- /** 윈도우 높이 */
511
- height: number;
512
- /** 마운트 여부 (SSR 대응) */
513
- isMounted: boolean;
514
- }
515
- type ScrollRevealMotionType = 'fadeIn' | 'slideUp' | 'slideLeft' | 'slideRight' | 'scaleIn' | 'bounceIn';
516
- interface ScrollRevealOptions extends BaseMotionOptions {
517
- /** 루트 마진 */
518
- rootMargin?: string;
519
- /** 모션 타입 */
520
- motionType?: ScrollRevealMotionType;
521
- }
522
- interface GradientOptions extends BaseMotionOptions {
523
- /** 그라디언트 색상 배열 */
524
- colors?: string[];
525
- /** 그라디언트 방향 */
526
- direction?: 'horizontal' | 'vertical' | 'diagonal';
527
- /** 그라디언트 크기 (%) */
528
- size?: number;
529
- }
530
- interface ToggleMotionOptions extends BaseMotionOptions {
531
- }
532
- interface RepeatOptions extends BaseMotionOptions {
533
- /** 반복 효과 타입 */
534
- type?: 'pulse' | 'bounce' | 'wave' | 'fade';
535
- /** 효과 강도 */
536
- intensity?: number;
537
- }
538
- interface HoverMotionOptions extends BaseMotionOptions {
539
- /** 호버 시 스케일 */
540
- hoverScale?: number;
541
- /** 호버 시 Y 오프셋 (px) */
542
- hoverY?: number;
543
- /** 호버 시 투명도 */
544
- hoverOpacity?: number;
545
- }
546
-
547
- type PageType = 'home' | 'dashboard' | 'product' | 'blog';
548
- type MotionType$1 = 'hero' | 'title' | 'button' | 'card' | 'text' | 'image';
549
- type EntranceType = 'fadeIn' | 'slideUp' | 'slideLeft' | 'slideRight' | 'scaleIn' | 'bounceIn';
550
- interface PageMotionElement {
551
- type: MotionType$1;
552
- entrance?: EntranceType;
553
- hover?: boolean;
554
- click?: boolean;
555
- delay?: number;
556
- duration?: number;
557
- threshold?: number;
558
- }
559
- interface PageMotionsConfig {
560
- [elementId: string]: PageMotionElement;
561
- }
562
- interface MotionState$1 {
563
- internalVisibility: boolean;
564
- triggeredVisibility: boolean;
565
- finalVisibility: boolean;
566
- opacity: number;
567
- translateY: number;
568
- translateX: number;
569
- scale: number;
570
- rotation: number;
571
- isHovered: boolean;
572
- isClicked: boolean;
573
- isAnimating: boolean;
574
- }
575
- interface PageMotionRef<T extends HTMLElement = HTMLElement> {
576
- ref: React.RefObject<T | null>;
577
- style: React.CSSProperties;
578
- isVisible: boolean;
579
- isHovered: boolean;
580
- isClicked: boolean;
581
- }
582
- interface MotionPreset {
583
- entrance: EntranceType;
584
- delay: number;
585
- duration: number;
586
- hover: boolean;
587
- click: boolean;
588
- }
589
- interface PresetConfig {
590
- [key: string]: MotionPreset;
591
- }
592
- interface SpringConfig {
593
- mass?: number;
594
- stiffness?: number;
595
- damping?: number;
596
- restDelta?: number;
597
- restSpeed?: number;
598
- }
599
- interface GestureConfig {
600
- hover?: boolean;
601
- drag?: boolean;
602
- pinch?: boolean;
603
- swipe?: boolean;
604
- tilt?: boolean;
605
- }
606
- interface OrchestrationConfig {
607
- sequence?: 'sequential' | 'parallel' | 'stagger';
608
- staggerDelay?: number;
609
- staggerDuration?: number;
610
- }
611
-
612
7
  /**
613
8
  * 1단계 API: 프리셋 기반 페이지 모션 (기존 방식)
614
9
  *
@@ -1061,6 +456,193 @@ declare function useGestureMotion(options: GestureMotionOptions): {
1061
456
  isActive: boolean;
1062
457
  };
1063
458
 
459
+ interface ButtonEffectOptions extends BaseMotionOptions {
460
+ type?: 'scale' | 'ripple' | 'glow' | 'shake' | 'bounce' | 'slide' | 'custom';
461
+ scaleAmount?: number;
462
+ rippleColor?: string;
463
+ rippleSize?: number;
464
+ rippleDuration?: number;
465
+ glowColor?: string;
466
+ glowSize?: number;
467
+ glowIntensity?: number;
468
+ shakeAmount?: number;
469
+ shakeFrequency?: number;
470
+ bounceHeight?: number;
471
+ bounceStiffness?: number;
472
+ slideDistance?: number;
473
+ slideDirection?: 'left' | 'right' | 'up' | 'down';
474
+ hoverScale?: number;
475
+ hoverRotate?: number;
476
+ hoverTranslateY?: number;
477
+ hoverTranslateX?: number;
478
+ activeScale?: number;
479
+ activeRotate?: number;
480
+ activeTranslateY?: number;
481
+ activeTranslateX?: number;
482
+ focusScale?: number;
483
+ focusGlow?: boolean;
484
+ disabled?: boolean;
485
+ disabledOpacity?: number;
486
+ autoStart?: boolean;
487
+ }
488
+ declare function useButtonEffect<T extends MotionElement = HTMLButtonElement>(options?: ButtonEffectOptions): BaseMotionReturn<T> & {
489
+ buttonType: string;
490
+ isPressed: boolean;
491
+ isHovered: boolean;
492
+ isFocused: boolean;
493
+ ripplePosition: {
494
+ x: number;
495
+ y: number;
496
+ };
497
+ currentGlowIntensity: number;
498
+ shakeOffset: number;
499
+ bounceOffset: number;
500
+ slideOffset: number;
501
+ pressButton: () => void;
502
+ releaseButton: () => void;
503
+ setButtonState: (state: 'idle' | 'hover' | 'active' | 'focus' | 'disabled') => void;
504
+ };
505
+
506
+ interface VisibilityToggleOptions extends BaseMotionOptions {
507
+ showScale?: number;
508
+ showOpacity?: number;
509
+ showRotate?: number;
510
+ showTranslateY?: number;
511
+ showTranslateX?: number;
512
+ hideScale?: number;
513
+ hideOpacity?: number;
514
+ hideRotate?: number;
515
+ hideTranslateY?: number;
516
+ hideTranslateX?: number;
517
+ }
518
+ declare function useVisibilityToggle<T extends MotionElement = HTMLDivElement>(options?: VisibilityToggleOptions): InteractionReturn<T>;
519
+
520
+ interface ScrollToggleOptions extends BaseMotionOptions {
521
+ showScale?: number;
522
+ showOpacity?: number;
523
+ showRotate?: number;
524
+ showTranslateY?: number;
525
+ showTranslateX?: number;
526
+ hideScale?: number;
527
+ hideOpacity?: number;
528
+ hideRotate?: number;
529
+ hideTranslateY?: number;
530
+ hideTranslateX?: number;
531
+ scrollThreshold?: number;
532
+ scrollDirection?: 'up' | 'down' | 'both';
533
+ }
534
+ declare function useScrollToggle<T extends MotionElement = HTMLDivElement>(options?: ScrollToggleOptions): BaseMotionReturn<T>;
535
+
536
+ interface CardListOptions extends BaseMotionOptions {
537
+ staggerDelay?: number;
538
+ cardScale?: number;
539
+ cardOpacity?: number;
540
+ cardRotate?: number;
541
+ cardTranslateY?: number;
542
+ cardTranslateX?: number;
543
+ initialScale?: number;
544
+ initialOpacity?: number;
545
+ initialRotate?: number;
546
+ initialTranslateY?: number;
547
+ initialTranslateX?: number;
548
+ gridColumns?: number;
549
+ gridGap?: number;
550
+ }
551
+ declare function useCardList<T extends MotionElement = HTMLDivElement>(options?: CardListOptions): BaseMotionReturn<T> & {
552
+ cardStyles: React.CSSProperties[];
553
+ staggerDelay: number;
554
+ gridColumns: number;
555
+ gridGap: number;
556
+ };
557
+
558
+ interface LoadingSpinnerOptions extends BaseMotionOptions {
559
+ type?: 'rotate' | 'pulse' | 'bounce' | 'wave' | 'dots' | 'bars' | 'custom';
560
+ rotationSpeed?: number;
561
+ pulseSpeed?: number;
562
+ bounceHeight?: number;
563
+ waveCount?: number;
564
+ dotCount?: number;
565
+ barCount?: number;
566
+ color?: string;
567
+ backgroundColor?: string;
568
+ size?: number;
569
+ thickness?: number;
570
+ autoStart?: boolean;
571
+ infinite?: boolean;
572
+ }
573
+ declare function useLoadingSpinner<T extends MotionElement = HTMLDivElement>(options?: LoadingSpinnerOptions): BaseMotionReturn<T> & {
574
+ isLoading: boolean;
575
+ spinnerType: string;
576
+ rotationAngle: number;
577
+ pulseScale: number;
578
+ bounceOffset: number;
579
+ waveProgress: number;
580
+ dotProgress: number;
581
+ barProgress: number;
582
+ startLoading: () => void;
583
+ stopLoading: () => void;
584
+ setLoadingState: (loading: boolean) => void;
585
+ };
586
+
587
+ interface NavigationOptions extends BaseMotionOptions {
588
+ type?: 'slide' | 'fade' | 'scale' | 'rotate' | 'custom';
589
+ slideDirection?: 'left' | 'right' | 'up' | 'down';
590
+ staggerDelay?: number;
591
+ itemScale?: number;
592
+ itemOpacity?: number;
593
+ itemRotate?: number;
594
+ itemTranslateY?: number;
595
+ itemTranslateX?: number;
596
+ initialScale?: number;
597
+ initialOpacity?: number;
598
+ initialRotate?: number;
599
+ initialTranslateY?: number;
600
+ initialTranslateX?: number;
601
+ activeScale?: number;
602
+ activeOpacity?: number;
603
+ activeRotate?: number;
604
+ activeTranslateY?: number;
605
+ activeTranslateX?: number;
606
+ hoverScale?: number;
607
+ hoverOpacity?: number;
608
+ hoverRotate?: number;
609
+ hoverTranslateY?: number;
610
+ hoverTranslateX?: number;
611
+ itemCount?: number;
612
+ autoStart?: boolean;
613
+ }
614
+ declare function useNavigation<T extends MotionElement = HTMLDivElement>(options?: NavigationOptions): BaseMotionReturn<T> & {
615
+ isOpen: boolean;
616
+ activeIndex: number;
617
+ itemStyles: React.CSSProperties[];
618
+ openMenu: () => void;
619
+ closeMenu: () => void;
620
+ toggleMenu: () => void;
621
+ setActiveItem: (index: number) => void;
622
+ goToNext: () => void;
623
+ goToPrevious: () => void;
624
+ };
625
+
626
+ interface SkeletonOptions extends BaseMotionOptions {
627
+ /** 스켈레톤 배경색 */
628
+ backgroundColor?: string;
629
+ /** 스켈레톤 하이라이트 색상 */
630
+ highlightColor?: string;
631
+ /** 모션 속도 (ms) */
632
+ motionSpeed?: number;
633
+ /** 스켈레톤 높이 */
634
+ height?: number;
635
+ /** 스켈레톤 너비 */
636
+ width?: number | string;
637
+ /** 보더 반지름 */
638
+ borderRadius?: number;
639
+ /** 웨이브 모션 활성화 여부 */
640
+ wave?: boolean;
641
+ /** 펄스 모션 활성화 여부 */
642
+ pulse?: boolean;
643
+ }
644
+ declare function useSkeleton<T extends MotionElement = HTMLDivElement>(options?: SkeletonOptions): BaseMotionReturn<T>;
645
+
1064
646
  interface TypewriterOptions {
1065
647
  /** 타이핑할 텍스트 */
1066
648
  text: string;
@@ -1236,6 +818,9 @@ interface ElementProgressReturn<T extends HTMLElement = HTMLElement> {
1236
818
  * useScrollProgress의 확장판. 페이지 전체가 아니라
1237
819
  * 특정 요소가 뷰포트를 통과하는 진행률을 추적합니다.
1238
820
  *
821
+ * 공유 스크롤 리스너(subscribeScroll)를 사용해 N개 인스턴스도
822
+ * 단 하나의 scroll/resize 이벤트 + rAF 배칭으로 처리됩니다.
823
+ *
1239
824
  * @example
1240
825
  * ```tsx
1241
826
  * const { ref, progress, isInView } = useElementProgress<HTMLDivElement>()
@@ -1248,47 +833,552 @@ interface ElementProgressReturn<T extends HTMLElement = HTMLElement> {
1248
833
  */
1249
834
  declare function useElementProgress<T extends HTMLElement = HTMLElement>(options?: ElementProgressOptions): ElementProgressReturn<T>;
1250
835
 
1251
- declare const MOTION_PRESETS: PresetConfig;
1252
- declare const PAGE_MOTIONS: Record<PageType, PageMotionsConfig>;
1253
836
  /**
1254
- * 프리셋과 커스텀 설정을 병합
837
+ * Shared IntersectionObserver Pool
838
+ *
839
+ * threshold|rootMargin 조합별로 하나의 IntersectionObserver를 공유합니다.
840
+ * N개 훅 = K개 observer (K = 고유 옵션 조합 수, 보통 1~3).
841
+ *
842
+ * sharedScroll.ts와 동일한 singleton pool 패턴.
843
+ *
844
+ * @example
845
+ * ```ts
846
+ * useEffect(() => {
847
+ * if (!ref.current) return
848
+ * return observeElement(
849
+ * ref.current,
850
+ * (entry) => { if (entry.isIntersecting) start() },
851
+ * { threshold: 0.1 },
852
+ * true // once
853
+ * )
854
+ * }, [])
855
+ * ```
1255
856
  */
1256
- declare function mergeWithPreset(preset: MotionPreset, custom?: Partial<MotionPreset>): MotionPreset;
857
+ type EntryCallback = (entry: IntersectionObserverEntry) => void;
1257
858
  /**
1258
- * 페이지 타입으로 프리셋 가져오기
859
+ * element를 공유 IntersectionObserver에 등록.
860
+ * 반환 함수를 호출하면 구독 해제.
861
+ *
862
+ * @param element - 관찰할 DOM element
863
+ * @param callback - intersection 변화 시 호출되는 콜백 (해당 element의 entry만 전달)
864
+ * @param options - threshold, rootMargin
865
+ * @param once - true이면 첫 intersection 후 자동 unsubscribe
866
+ * @returns unsubscribe 함수
1259
867
  */
1260
- declare function getPagePreset(pageType: PageType): PageMotionsConfig;
868
+ declare function observeElement(element: Element, callback: EntryCallback, options?: {
869
+ threshold?: number | number[];
870
+ rootMargin?: string;
871
+ }, once?: boolean): () => void;
872
+
873
+ interface AutoFadeConfig {
874
+ initialOpacity?: number;
875
+ targetOpacity?: number;
876
+ duration?: number;
877
+ delay?: number;
878
+ repeat?: boolean;
879
+ repeatDelay?: number;
880
+ repeatCount?: number;
881
+ ease?: "linear" | "ease-in" | "ease-out" | "ease-in-out";
882
+ autoStart?: boolean;
883
+ onComplete?: () => void;
884
+ onRepeat?: (count: number) => void;
885
+ showOnMount?: boolean;
886
+ }
887
+ interface AutoFadeReturn {
888
+ opacity: number;
889
+ isAnimating: boolean;
890
+ isVisible: boolean;
891
+ mounted: boolean;
892
+ start: () => void;
893
+ stop: () => void;
894
+ reset: () => void;
895
+ fadeIn: () => void;
896
+ fadeOut: () => void;
897
+ toggle: () => void;
898
+ }
899
+ declare function useAutoFade(options?: AutoFadeConfig): AutoFadeReturn;
900
+
901
+ interface AutoPlayConfig {
902
+ interval?: number;
903
+ delay?: number;
904
+ repeat?: number | "infinite";
905
+ autoStart?: boolean;
906
+ pauseOnHover?: boolean;
907
+ pauseOnBlur?: boolean;
908
+ showOnMount?: boolean;
909
+ }
910
+ declare function useAutoPlay(options?: AutoPlayConfig): {
911
+ isPlaying: boolean;
912
+ isPaused: boolean;
913
+ currentStep: number;
914
+ mounted: boolean;
915
+ start: () => void;
916
+ stop: () => void;
917
+ pause: () => void;
918
+ resume: () => void;
919
+ next: () => void;
920
+ previous: () => void;
921
+ goTo: (step: number) => void;
922
+ };
923
+
924
+ interface AutoScaleConfig {
925
+ initialScale?: number;
926
+ targetScale?: number;
927
+ duration?: number;
928
+ delay?: number;
929
+ repeat?: boolean;
930
+ repeatDelay?: number;
931
+ repeatCount?: number;
932
+ ease?: "linear" | "ease-in" | "ease-out" | "ease-in-out" | "bounce" | "elastic";
933
+ autoStart?: boolean;
934
+ onComplete?: () => void;
935
+ onRepeat?: (count: number) => void;
936
+ showOnMount?: boolean;
937
+ centerTransform?: boolean;
938
+ }
939
+ interface AutoScaleReturn {
940
+ scale: number;
941
+ isAnimating: boolean;
942
+ isVisible: boolean;
943
+ mounted: boolean;
944
+ start: () => void;
945
+ stop: () => void;
946
+ reset: () => void;
947
+ scaleIn: () => void;
948
+ scaleOut: () => void;
949
+ toggle: () => void;
950
+ }
951
+ declare function useAutoScale(options?: AutoScaleConfig): AutoScaleReturn;
952
+
953
+ type SlideDirection = "left" | "right" | "up" | "down" | "left-up" | "left-down" | "right-up" | "right-down";
954
+ interface AutoSlideConfig {
955
+ direction?: SlideDirection;
956
+ distance?: number;
957
+ initialPosition?: {
958
+ x: number;
959
+ y: number;
960
+ };
961
+ targetPosition?: {
962
+ x: number;
963
+ y: number;
964
+ };
965
+ duration?: number;
966
+ delay?: number;
967
+ repeat?: boolean;
968
+ repeatDelay?: number;
969
+ repeatCount?: number;
970
+ ease?: "linear" | "ease-in" | "ease-out" | "ease-in-out";
971
+ autoStart?: boolean;
972
+ onComplete?: () => void;
973
+ onRepeat?: (count: number) => void;
974
+ showOnMount?: boolean;
975
+ }
976
+ interface AutoSlideReturn {
977
+ position: {
978
+ x: number;
979
+ y: number;
980
+ };
981
+ isAnimating: boolean;
982
+ isVisible: boolean;
983
+ mounted: boolean;
984
+ start: () => void;
985
+ stop: () => void;
986
+ reset: () => void;
987
+ slideIn: () => void;
988
+ slideOut: () => void;
989
+ toggle: () => void;
990
+ }
991
+ declare function useAutoSlide(options?: AutoSlideConfig): AutoSlideReturn;
992
+
993
+ interface MotionStep$1 {
994
+ id: string;
995
+ motion: () => void;
996
+ delay?: number;
997
+ duration?: number;
998
+ onComplete?: () => void;
999
+ }
1000
+ interface MotionOrchestraOptions {
1001
+ mode?: "sequential" | "parallel" | "stagger";
1002
+ staggerDelay?: number;
1003
+ autoStart?: boolean;
1004
+ loop?: boolean;
1005
+ onComplete?: () => void;
1006
+ }
1007
+ declare function useMotionOrchestra(options?: MotionOrchestraOptions): {
1008
+ addMotion: (step: MotionStep$1) => void;
1009
+ removeMotion: (id: string) => void;
1010
+ play: () => void;
1011
+ stop: () => void;
1012
+ pause: () => void;
1013
+ resume: () => void;
1014
+ isPlaying: boolean;
1015
+ currentStep: number;
1016
+ completedSteps: Set<string>;
1017
+ totalSteps: number;
1018
+ };
1019
+
1020
+ interface MotionStep {
1021
+ id: string;
1022
+ duration: number;
1023
+ delay?: number;
1024
+ ease?: "linear" | "ease-in" | "ease-out" | "ease-in-out" | "bounce" | "elastic";
1025
+ onStart?: () => void;
1026
+ onUpdate?: (progress: number) => void;
1027
+ onComplete?: () => void;
1028
+ onError?: (error: Error) => void;
1029
+ }
1030
+ interface OrchestrationConfig {
1031
+ autoStart?: boolean;
1032
+ loop?: boolean;
1033
+ loopCount?: number;
1034
+ loopDelay?: number;
1035
+ timeline?: MotionStep[];
1036
+ duration?: number;
1037
+ speed?: number;
1038
+ reverse?: boolean;
1039
+ onStart?: () => void;
1040
+ onComplete?: () => void;
1041
+ onLoop?: (count: number) => void;
1042
+ onError?: (error: Error) => void;
1043
+ onProgress?: (progress: number) => void;
1044
+ onStepStart?: (stepId: string) => void;
1045
+ onStepComplete?: (stepId: string) => void;
1046
+ }
1047
+ interface OrchestrationReturn {
1048
+ isPlaying: boolean;
1049
+ isPaused: boolean;
1050
+ currentTime: number;
1051
+ progress: number;
1052
+ currentStep: string | null;
1053
+ loopCount: number;
1054
+ error: string | null;
1055
+ play: () => void;
1056
+ pause: () => void;
1057
+ stop: () => void;
1058
+ reset: () => void;
1059
+ seek: (time: number) => void;
1060
+ setSpeed: (speed: number) => void;
1061
+ reverse: () => void;
1062
+ addStep: (step: MotionStep) => void;
1063
+ removeStep: (stepId: string) => void;
1064
+ updateStep: (stepId: string, updates: Partial<MotionStep>) => void;
1065
+ reorderSteps: (stepIds: string[]) => void;
1066
+ getStepProgress: (stepId: string) => number;
1067
+ getStepTime: (stepId: string) => number;
1068
+ getTotalDuration: () => number;
1069
+ }
1070
+ declare function useOrchestration(options?: OrchestrationConfig): OrchestrationReturn;
1071
+
1072
+ interface SequenceConfig {
1073
+ autoStart?: boolean;
1074
+ loop?: boolean;
1075
+ }
1076
+ interface SequenceItem {
1077
+ hook: () => any;
1078
+ delay?: number;
1079
+ }
1080
+ declare function useSequence(sequence: SequenceItem[], options?: SequenceConfig): {
1081
+ start: () => void;
1082
+ stop: () => void;
1083
+ pause: () => void;
1084
+ resume: () => void;
1085
+ reset: () => void;
1086
+ isPlaying: boolean;
1087
+ currentIndex: number;
1088
+ totalMotions: number;
1089
+ ref: any;
1090
+ };
1091
+
1092
+ interface LayoutMotionConfig {
1093
+ from: {
1094
+ width?: number | string;
1095
+ height?: number | string;
1096
+ flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
1097
+ justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
1098
+ alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
1099
+ gap?: number | string;
1100
+ gridTemplateColumns?: string;
1101
+ gridTemplateRows?: string;
1102
+ gridGap?: number | string;
1103
+ };
1104
+ to: {
1105
+ width?: number | string;
1106
+ height?: number | string;
1107
+ flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
1108
+ justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
1109
+ alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
1110
+ gap?: number | string;
1111
+ gridTemplateColumns?: string;
1112
+ gridTemplateRows?: string;
1113
+ gridGap?: number | string;
1114
+ };
1115
+ duration?: number;
1116
+ easing?: string;
1117
+ autoStart?: boolean;
1118
+ onComplete?: () => void;
1119
+ }
1120
+ interface LayoutState {
1121
+ isAnimating: boolean;
1122
+ progress: number;
1123
+ currentStyle: React.CSSProperties;
1124
+ }
1125
+ declare function useLayoutMotion(config: LayoutMotionConfig): {
1126
+ ref: react.RefObject<HTMLDivElement | null>;
1127
+ state: LayoutState;
1128
+ start: () => void;
1129
+ stop: () => void;
1130
+ reset: () => void;
1131
+ };
1132
+ declare function createLayoutTransition(from: LayoutMotionConfig["from"], to: LayoutMotionConfig["to"], options?: Partial<LayoutMotionConfig>): {
1133
+ from: {
1134
+ width?: number | string;
1135
+ height?: number | string;
1136
+ flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
1137
+ justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
1138
+ alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
1139
+ gap?: number | string;
1140
+ gridTemplateColumns?: string;
1141
+ gridTemplateRows?: string;
1142
+ gridGap?: number | string;
1143
+ };
1144
+ to: {
1145
+ width?: number | string;
1146
+ height?: number | string;
1147
+ flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";
1148
+ justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
1149
+ alignItems?: "flex-start" | "flex-end" | "center" | "stretch" | "baseline";
1150
+ gap?: number | string;
1151
+ gridTemplateColumns?: string;
1152
+ gridTemplateRows?: string;
1153
+ gridGap?: number | string;
1154
+ };
1155
+ duration: number;
1156
+ easing: string;
1157
+ autoStart: boolean;
1158
+ onComplete: (() => void) | undefined;
1159
+ };
1160
+
1161
+ interface KeyboardToggleConfig {
1162
+ initialState?: boolean;
1163
+ keys?: string[];
1164
+ keyCode?: number;
1165
+ keyCombo?: string[];
1166
+ toggleOnKeyDown?: boolean;
1167
+ toggleOnKeyUp?: boolean;
1168
+ toggleOnKeyPress?: boolean;
1169
+ autoReset?: boolean;
1170
+ resetDelay?: number;
1171
+ preventDefault?: boolean;
1172
+ stopPropagation?: boolean;
1173
+ requireFocus?: boolean;
1174
+ showOnMount?: boolean;
1175
+ }
1176
+ interface KeyboardToggleReturn {
1177
+ isActive: boolean;
1178
+ mounted: boolean;
1179
+ toggle: () => void;
1180
+ activate: () => void;
1181
+ deactivate: () => void;
1182
+ reset: () => void;
1183
+ keyboardHandlers: {
1184
+ onKeyDown?: (event: React.KeyboardEvent) => void;
1185
+ onKeyUp?: (event: React.KeyboardEvent) => void;
1186
+ onKeyPress?: (event: React.KeyboardEvent) => void;
1187
+ };
1188
+ ref: React.RefObject<HTMLElement | null>;
1189
+ }
1190
+ declare function useKeyboardToggle(options?: KeyboardToggleConfig): KeyboardToggleReturn;
1191
+
1192
+ type ScrollDirection = "up" | "down" | "idle";
1193
+ interface ScrollDirectionConfig {
1194
+ threshold?: number;
1195
+ idleDelay?: number;
1196
+ showOnMount?: boolean;
1197
+ }
1198
+ declare function useScrollDirection(options?: ScrollDirectionConfig): {
1199
+ direction: ScrollDirection;
1200
+ mounted: boolean;
1201
+ };
1202
+
1203
+ interface StickyToggleConfig {
1204
+ offset?: number;
1205
+ behavior?: "smooth" | "auto";
1206
+ showOnMount?: boolean;
1207
+ }
1208
+ declare function useStickyToggle(options?: StickyToggleConfig): {
1209
+ isSticky: boolean;
1210
+ mounted: boolean;
1211
+ };
1212
+
1213
+ interface InteractiveConfig {
1214
+ hoverScale?: number;
1215
+ clickScale?: number;
1216
+ duration?: number;
1217
+ }
1218
+ interface InteractiveState {
1219
+ scale: number;
1220
+ isHovered: boolean;
1221
+ isClicked: boolean;
1222
+ }
1223
+ declare function useInteractive(config?: InteractiveConfig): {
1224
+ ref: (element: HTMLDivElement | null) => void;
1225
+ scale: number;
1226
+ isHovered: boolean;
1227
+ isClicked: boolean;
1228
+ handleMouseEnter: () => void;
1229
+ handleMouseLeave: () => void;
1230
+ handleMouseDown: () => void;
1231
+ handleMouseUp: () => void;
1232
+ };
1233
+
1234
+ interface PerformanceMonitorConfig {
1235
+ threshold?: number;
1236
+ onPerformanceIssue?: (fps: number) => void;
1237
+ }
1238
+ interface PerformanceMonitorState {
1239
+ fps: number;
1240
+ isLowPerformance: boolean;
1241
+ frameCount: number;
1242
+ }
1243
+ declare function usePerformanceMonitor(config?: PerformanceMonitorConfig): {
1244
+ ref: (element: HTMLDivElement | null) => void;
1245
+ fps: number;
1246
+ isLowPerformance: boolean;
1247
+ frameCount: number;
1248
+ };
1249
+
1250
+ interface LanguageConfig {
1251
+ motionType: "fadeIn" | "slideUp" | "slideLeft" | "slideRight" | "scaleIn" | "bounceIn";
1252
+ duration?: number;
1253
+ delay?: number;
1254
+ threshold?: number;
1255
+ pauseOnLanguageChange?: boolean;
1256
+ restartOnLanguageChange?: boolean;
1257
+ currentLanguage?: string;
1258
+ }
1259
+ declare function useLanguageAwareMotion(options: LanguageConfig): {
1260
+ ref: react.RefObject<HTMLElement | null>;
1261
+ isVisible: boolean;
1262
+ isPaused: boolean;
1263
+ style: {
1264
+ opacity: number;
1265
+ transform: string;
1266
+ transition: string;
1267
+ } | {
1268
+ opacity: number;
1269
+ transition: string;
1270
+ transform?: undefined;
1271
+ };
1272
+ pauseMotion: () => void;
1273
+ resumeMotion: () => void;
1274
+ restartMotion: () => void;
1275
+ currentLanguage: string;
1276
+ };
1277
+
1278
+ interface GameLoopConfig {
1279
+ fps?: number;
1280
+ autoStart?: boolean;
1281
+ maxFPS?: number;
1282
+ minFPS?: number;
1283
+ showOnMount?: boolean;
1284
+ }
1285
+ interface GameState {
1286
+ isRunning: boolean;
1287
+ fps: number;
1288
+ deltaTime: number;
1289
+ elapsedTime: number;
1290
+ frameCount: number;
1291
+ mounted: boolean;
1292
+ }
1293
+ interface GameLoopReturn {
1294
+ isRunning: boolean;
1295
+ fps: number;
1296
+ deltaTime: number;
1297
+ elapsedTime: number;
1298
+ frameCount: number;
1299
+ mounted: boolean;
1300
+ start: () => void;
1301
+ stop: () => void;
1302
+ pause: () => void;
1303
+ resume: () => void;
1304
+ reset: () => void;
1305
+ onUpdate: (callback: (deltaTime: number, elapsedTime: number) => void) => void;
1306
+ onRender: (callback: (deltaTime: number, elapsedTime: number) => void) => void;
1307
+ }
1308
+ declare function useGameLoop(options?: GameLoopConfig): GameLoopReturn;
1309
+
1310
+ interface AutoMotionConfig {
1311
+ duration?: number;
1312
+ delay?: number;
1313
+ autoStart?: boolean;
1314
+ easing?: string;
1315
+ type?: "fade" | "slide" | "scale" | "rotate";
1316
+ }
1317
+ interface MotionConfig {
1318
+ duration?: number;
1319
+ delay?: number;
1320
+ autoStart?: boolean;
1321
+ easing?: string;
1322
+ type?: "fade" | "slide" | "scale" | "rotate";
1323
+ }
1324
+ interface MotionFromToConfig {
1325
+ from: Record<string, any>;
1326
+ to: Record<string, any>;
1327
+ duration?: number;
1328
+ delay?: number;
1329
+ autoStart?: boolean;
1330
+ ease?: string;
1331
+ }
1332
+ declare function useMotion(configOrFrom?: MotionConfig | Record<string, any>, to?: Record<string, any>, options?: {
1333
+ duration?: number;
1334
+ delay?: number;
1335
+ autoStart?: boolean;
1336
+ ease?: string;
1337
+ }): {
1338
+ ref: (element: HTMLDivElement | null) => void;
1339
+ style: react__default.CSSProperties;
1340
+ transform: string;
1341
+ opacity: number;
1342
+ backgroundColor: string | undefined;
1343
+ isAnimating: boolean;
1344
+ start: () => void;
1345
+ stop: () => void;
1346
+ reset: () => void;
1347
+ };
1348
+
1349
+ interface ViewportToggleConfig {
1350
+ threshold?: number;
1351
+ rootMargin?: string;
1352
+ trigger?: "enter" | "exit" | "both";
1353
+ once?: boolean;
1354
+ showOnMount?: boolean;
1355
+ }
1356
+ /**
1357
+ * IntersectionObserver를 사용해 뷰포트 진입/이탈을 감지하는 훅.
1358
+ * (구 hua-pro의 useVisibilityToggle — animation lifecycle 기반의
1359
+ * motion-core useVisibilityToggle과 충돌을 피해 이름을 변경함)
1360
+ */
1361
+ declare function useViewportToggle(options?: ViewportToggleConfig): {
1362
+ ref: react.RefObject<HTMLElement | null>;
1363
+ isVisible: boolean;
1364
+ mounted: boolean;
1365
+ };
1366
+
1367
+ interface ScrollPositionToggleConfig {
1368
+ threshold?: number;
1369
+ showOnMount?: boolean;
1370
+ smooth?: boolean;
1371
+ }
1261
1372
  /**
1262
- * 모션 타입으로 기본 프리셋 가져오기
1373
+ * window.pageYOffset 기준 스크롤 위치 임계값에 따라 가시성을 토글하는 훅.
1374
+ * (구 hua-pro의 useScrollToggle — animation lifecycle 기반의
1375
+ * motion-core useScrollToggle과 충돌을 피해 이름을 변경함)
1263
1376
  */
1264
- declare function getMotionPreset(type: string): MotionPreset;
1265
-
1266
- type EasingFunction = (t: number) => number;
1267
- declare const linear: EasingFunction;
1268
- declare const easeIn: EasingFunction;
1269
- declare const easeOut: EasingFunction;
1270
- declare const easeInOut: EasingFunction;
1271
- declare const easeInQuad: EasingFunction;
1272
- declare const easeOutQuad: EasingFunction;
1273
- declare const easeInOutQuad: EasingFunction;
1274
- type EasingType = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInQuint' | 'easeOutQuint' | 'easeInOutQuint' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo' | 'easeInCirc' | 'easeOutCirc' | 'easeInOutCirc' | 'easeInBounce' | 'easeOutBounce' | 'easeInOutBounce' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeInElastic' | 'easeOutElastic' | 'easeInOutElastic' | 'pulse' | 'pulseSmooth' | 'skeletonWave' | 'blink';
1275
- declare function isValidEasing(easingName: string): boolean;
1276
- declare function getEasing(easingName: unknown): EasingFunction;
1277
- declare function applyEasing(t: number, easingName: string | EasingFunction): number;
1278
- declare function safeApplyEasing(t: number, easingName: unknown): number;
1279
- declare function getAvailableEasings(): string[];
1280
- declare function isEasingFunction(value: any): value is EasingFunction;
1281
- declare const easingPresets: {
1282
- readonly default: "easeOut";
1283
- readonly smooth: "easeInOutCubic";
1284
- readonly fast: "easeOutQuad";
1285
- readonly slow: "easeInOutSine";
1286
- readonly bouncy: "easeOutBounce";
1287
- readonly elastic: "easeOutElastic";
1288
- readonly fade: "easeInOut";
1289
- readonly scale: "easeOutBack";
1377
+ declare function useScrollPositionToggle(options?: ScrollPositionToggleConfig): {
1378
+ isVisible: boolean;
1379
+ scrollToTop: () => void;
1380
+ mounted: boolean;
1290
1381
  };
1291
- declare function getPresetEasing(preset: keyof typeof easingPresets): EasingFunction;
1292
1382
 
1293
1383
  type MotionAs = 'div' | 'span' | 'section' | 'article' | 'header' | 'footer' | 'main' | 'nav';
1294
1384
  interface MotionProps extends react__default.HTMLAttributes<HTMLElement> {
@@ -1323,6 +1413,108 @@ interface MotionProps extends react__default.HTMLAttributes<HTMLElement> {
1323
1413
  */
1324
1414
  declare function Motion({ as: Component, type, effects, scroll, delay, duration, children, className, style: userStyle, ...rest }: MotionProps): react_jsx_runtime.JSX.Element;
1325
1415
 
1416
+ interface CountUpOptions {
1417
+ /** 목표 숫자 */
1418
+ end: number;
1419
+ /** 숫자 뒤에 붙는 접미사 (%, +, 명 등) */
1420
+ suffix?: string;
1421
+ /** 애니메이션 지속 시간 (ms) */
1422
+ duration?: number;
1423
+ /** 시작 지연 시간 (ms) */
1424
+ delay?: number;
1425
+ /** 애니메이션 활성화 여부 (true가 되면 시작, 한 번만 실행) */
1426
+ active?: boolean;
1427
+ }
1428
+ interface CountUpReturn {
1429
+ /** 현재 숫자 값 */
1430
+ value: number;
1431
+ /** 접미사 포함 표시 문자열 */
1432
+ display: string;
1433
+ }
1434
+ /**
1435
+ * useCountUp — 숫자 카운트업 애니메이션
1436
+ *
1437
+ * 통계, 대시보드, 메트릭 수치 강조에 적합.
1438
+ * ease-out cubic 이징으로 자연스러운 감속 효과.
1439
+ *
1440
+ * @example
1441
+ * ```tsx
1442
+ * const { display } = useCountUp({ end: 1200, suffix: '+', active: isInView })
1443
+ * return <span>{display}</span>
1444
+ * ```
1445
+ */
1446
+ declare function useCountUp(options: CountUpOptions): CountUpReturn;
1447
+
1448
+ interface ClipRevealOptions {
1449
+ /** 시작 지연 시간 (ms) */
1450
+ delay?: number;
1451
+ /** 애니메이션 지속 시간 (ms) */
1452
+ duration?: number;
1453
+ /** CSS 이징 함수 */
1454
+ easing?: string;
1455
+ /** 애니메이션 활성화 여부 (true가 되면 시작, 한 번만 실행) */
1456
+ active?: boolean;
1457
+ }
1458
+ interface ClipRevealReturn {
1459
+ /** overflow:hidden 컨테이너에 적용할 스타일 */
1460
+ containerStyle: CSSProperties;
1461
+ /** 슬라이딩 텍스트에 적용할 스타일 */
1462
+ textStyle: CSSProperties;
1463
+ /** 등장 완료 여부 */
1464
+ isVisible: boolean;
1465
+ }
1466
+ /**
1467
+ * useClipReveal — overflow clip으로 텍스트가 아래→위로 등장
1468
+ *
1469
+ * 커버 타이틀, 히어로 헤드라인, 큰 문구에 적합.
1470
+ * 컨테이너에 overflow:hidden을 적용하고, 내부 텍스트가 translateY로 올라옴.
1471
+ *
1472
+ * @example
1473
+ * ```tsx
1474
+ * const { containerStyle, textStyle } = useClipReveal({ delay: 200, active: isInView })
1475
+ * return (
1476
+ * <span style={containerStyle}>
1477
+ * <span style={textStyle}>Hello World</span>
1478
+ * </span>
1479
+ * )
1480
+ * ```
1481
+ */
1482
+ declare function useClipReveal(options?: ClipRevealOptions): ClipRevealReturn;
1483
+
1484
+ interface BlurInOptions {
1485
+ /** 시작 지연 시간 (ms) */
1486
+ delay?: number;
1487
+ /** 애니메이션 지속 시간 (ms) */
1488
+ duration?: number;
1489
+ /** 초기 블러 강도 (px) */
1490
+ blurAmount?: number;
1491
+ /** 초기 스케일 (0~1) */
1492
+ scale?: number;
1493
+ /** CSS 이징 함수 */
1494
+ easing?: string;
1495
+ /** 애니메이션 활성화 여부 (true가 되면 시작, 한 번만 실행) */
1496
+ active?: boolean;
1497
+ }
1498
+ interface BlurInReturn {
1499
+ /** 요소에 적용할 스타일 */
1500
+ style: CSSProperties;
1501
+ /** 등장 완료 여부 */
1502
+ isVisible: boolean;
1503
+ }
1504
+ /**
1505
+ * useBlurIn — 블러에서 선명하게 + 스케일 등장
1506
+ *
1507
+ * 인용구, 임팩트 문구, 핵심 메시지에 적합.
1508
+ * blur + scale + opacity 세 가지가 동시에 전환됨.
1509
+ *
1510
+ * @example
1511
+ * ```tsx
1512
+ * const { style } = useBlurIn({ blurAmount: 12, scale: 0.95, active: isInView })
1513
+ * return <blockquote style={style}>Deep insight here</blockquote>
1514
+ * ```
1515
+ */
1516
+ declare function useBlurIn(options?: BlurInOptions): BlurInReturn;
1517
+
1326
1518
  interface UseStaggerOptions {
1327
1519
  /** 자식 아이템 개수 */
1328
1520
  count: number;
@@ -1363,4 +1555,4 @@ interface UseStaggerReturn {
1363
1555
  */
1364
1556
  declare function useStagger(options: UseStaggerOptions): UseStaggerReturn;
1365
1557
 
1366
- export { type BaseMotionOptions, type BaseMotionReturn, type BounceOptions, type CustomCursorOptions, type CustomCursorReturn, type EasingFunction, type EasingType, type ElementProgressOptions, type ElementProgressReturn, type EntranceType, type FadeInOptions, type GestureConfig, type GestureOptions$1 as GestureOptions, type GradientOptions, type HoverMotionOptions, type InViewOptions, type InViewReturn, type InteractionReturn, MOTION_PRESETS, type MagneticCursorOptions, type MagneticCursorReturn, Motion, type MotionCallback, type MotionConfig, type MotionDirection$1 as MotionDirection, type MotionEasing, type MotionEffects, type MotionElement, MotionEngine, type MotionFrame, type Motion$1 as MotionInstance, type MotionOptions, type MotionPreset, type MotionProgressCallback, type MotionProps, type MotionState$1 as MotionState, type MotionStateCallback, type MotionTrigger, type MotionType$1 as MotionType, type MouseOptions, type MouseReturn, type OptimizationConfig, type OrchestrationConfig, PAGE_MOTIONS, type PageMotionElement, type PageMotionRef, type PageMotionsConfig, type PageType, type PerformanceMetrics, PerformanceOptimizer, type PerformanceOptimizerMetrics, type PresetConfig, type PulseOptions, type ReducedMotionReturn, type RepeatOptions, type ScaleOptions, type ScrollRevealMotionType, type ScrollRevealOptions, type SlideOptions, type SmoothScrollOptions, type SmoothScrollReturn, type SpringConfig, type SpringOptions, type ToggleMotionOptions, TransitionEffects, type TransitionOptions, type TransitionType, type TypewriterOptions, type TypewriterReturn, type UseStaggerOptions, type UseStaggerReturn, type UseUnifiedMotionOptions, type WindowSizeOptions, type WindowSizeReturn, applyEasing, easeIn, easeInOut, easeInOutQuad, easeInQuad, easeOut, easeOutQuad, easingPresets, getAvailableEasings, getEasing, getMotionPreset, getPagePreset, getPresetEasing, isEasingFunction, isValidEasing, linear, mergeWithPreset, motionEngine, performanceOptimizer, safeApplyEasing, transitionEffects, useBounceIn, useClickToggle, useCustomCursor, useElementProgress, useFadeIn, useFocusToggle, useGesture, useGestureMotion, useGradient, useHoverMotion, useInView, useMagneticCursor, useMotionState, useMouse, usePageMotions, usePulse, useReducedMotion, useRepeat, useScaleIn, useScrollProgress, useScrollReveal, useSimplePageMotion, useSlideDown, useSlideLeft, useSlideRight, useSlideUp, useSmartMotion, useSmoothScroll, useSpringMotion, useStagger, useToggleMotion, useTypewriter, useUnifiedMotion, useWindowSize };
1558
+ export { type AutoFadeConfig, type AutoMotionConfig, type AutoPlayConfig, type AutoScaleConfig, type AutoSlideConfig, BaseMotionOptions, BaseMotionReturn, type BlurInOptions, type BlurInReturn, BounceOptions, type ButtonEffectOptions, type CardListOptions, type ClipRevealOptions, type ClipRevealReturn, type CountUpOptions, type CountUpReturn, type CustomCursorOptions, type CustomCursorReturn, type ElementProgressOptions, type ElementProgressReturn, EntranceType, FadeInOptions, type GameLoopConfig, type GameState, GradientOptions, HoverMotionOptions, InViewOptions, InViewReturn, InteractionReturn, type InteractiveConfig, type InteractiveState, type KeyboardToggleConfig, type LanguageConfig, type LayoutMotionConfig, type LayoutState, type LoadingSpinnerOptions, type MagneticCursorOptions, type MagneticCursorReturn, Motion, type MotionEffects, MotionElement, type MotionFromToConfig, type MotionProps, MouseOptions, MouseReturn, type NavigationOptions, PageMotionRef, PageMotionsConfig, PageType, type PerformanceMonitorConfig, type PerformanceMonitorState, PulseOptions, ReducedMotionReturn, RepeatOptions, ScaleOptions, type ScrollDirectionConfig, type ScrollPositionToggleConfig, ScrollRevealMotionType, ScrollRevealOptions, type ScrollToggleOptions, type SequenceConfig, type SkeletonOptions, SlideOptions, type SmoothScrollOptions, type SmoothScrollReturn, SpringOptions, type StickyToggleConfig, ToggleMotionOptions, type TypewriterOptions, type TypewriterReturn, type MotionConfig as UseMotionConfig, type OrchestrationConfig as UseOrchestrationConfig, type UseStaggerOptions, type UseStaggerReturn, type UseUnifiedMotionOptions, type ViewportToggleConfig, type VisibilityToggleOptions, WindowSizeOptions, WindowSizeReturn, createLayoutTransition, observeElement, useAutoFade, useAutoPlay, useAutoScale, useAutoSlide, useBlurIn, useBounceIn, useButtonEffect, useCardList, useClickToggle, useClipReveal, useCountUp, useCustomCursor, useElementProgress, useFadeIn, useFocusToggle, useGameLoop, useGesture, useGestureMotion, useGradient, useHoverMotion, useInView, useInteractive, useKeyboardToggle, useLanguageAwareMotion, useLayoutMotion, useLoadingSpinner, useMagneticCursor, useMotion, useMotionOrchestra, useMotionState, useMouse, useNavigation, useOrchestration, usePageMotions, usePerformanceMonitor, usePulse, useReducedMotion, useRepeat, useScaleIn, useScrollDirection, useScrollPositionToggle, useScrollProgress, useScrollReveal, useScrollToggle, useSequence, useSimplePageMotion, useSkeleton, useSlideDown, useSlideLeft, useSlideRight, useSlideUp, useSmartMotion, useSmoothScroll, useSpringMotion, useStagger, useStickyToggle, useToggleMotion, useTypewriter, useUnifiedMotion, useViewportToggle, useVisibilityToggle, useWindowSize };