@frybynite/image-cloud 0.1.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.
@@ -0,0 +1,1514 @@
1
+ declare interface AdaptiveSizingConfig {
2
+ enabled: boolean;
3
+ minSize: number;
4
+ maxSize: number;
5
+ }
6
+
7
+ declare interface AdaptiveSizingResult {
8
+ height: number;
9
+ }
10
+
11
+ /**
12
+ * Animate an element along a path using requestAnimationFrame
13
+ */
14
+ export declare function animatePath(options: PathAnimationOptions): void;
15
+
16
+ export declare interface AnimationConfig {
17
+ duration: number;
18
+ easing: AnimationEasingConfig;
19
+ queue: AnimationQueueConfig;
20
+ performance?: AnimationPerformanceConfig;
21
+ entry?: EntryAnimationConfig;
22
+ }
23
+
24
+ declare interface AnimationEasingConfig {
25
+ default: string;
26
+ bounce: string;
27
+ focus: string;
28
+ }
29
+
30
+ export declare class AnimationEngine {
31
+ private config;
32
+ private activeAnimations;
33
+ private animationIdCounter;
34
+ constructor(config: AnimationConfig);
35
+ /**
36
+ * Build transform string from transform params
37
+ * Always starts with centering transform to match image positioning system
38
+ */
39
+ private buildTransformString;
40
+ /**
41
+ * Start a cancellable transform animation using Web Animations API
42
+ * @param element - The element to animate
43
+ * @param from - Starting transform state
44
+ * @param to - Ending transform state
45
+ * @param duration - Animation duration in ms (optional)
46
+ * @param easing - CSS easing function (optional)
47
+ * @returns AnimationHandle that can be used to cancel or query the animation
48
+ */
49
+ animateTransformCancellable(element: HTMLElement, from: TransformParams, to: TransformParams, duration?: number | null, easing?: string | null): AnimationHandle;
50
+ /**
51
+ * Cancel an active animation
52
+ * @param handle - The animation handle to cancel
53
+ * @param commitStyle - If true, keeps current position; if false, no style change
54
+ * @returns Snapshot of where the animation was when cancelled
55
+ */
56
+ cancelAnimation(handle: AnimationHandle, commitStyle?: boolean): AnimationSnapshot;
57
+ /**
58
+ * Cancel all animations on an element
59
+ * Uses Web Animations API to find and cancel ALL animations, not just tracked ones
60
+ * @param element - The element to cancel animations for
61
+ */
62
+ cancelAllAnimations(element: HTMLElement): void;
63
+ /**
64
+ * Get current transform state of an element (works mid-animation)
65
+ * Uses DOMMatrix to parse the computed transform
66
+ * @param element - The element to query
67
+ * @returns Current transform snapshot
68
+ */
69
+ getCurrentTransform(element: HTMLElement): AnimationSnapshot;
70
+ /**
71
+ * Check if an element has an active animation
72
+ * @param element - The element to check
73
+ * @returns True if animation is in progress
74
+ */
75
+ hasActiveAnimation(element: HTMLElement): boolean;
76
+ /**
77
+ * Get animation handle for an element if it exists
78
+ * @param element - The element to query
79
+ * @returns AnimationHandle or undefined
80
+ */
81
+ getAnimationHandle(element: HTMLElement): AnimationHandle | undefined;
82
+ /**
83
+ * Animate element transform with smooth easing (CSS transitions - legacy method)
84
+ * @param element - The element to animate
85
+ * @param properties - Transform properties {x, y, rotation, scale}
86
+ * @param duration - Animation duration in ms (optional)
87
+ * @param easing - CSS easing function (optional)
88
+ * @returns Promise that resolves when animation completes
89
+ */
90
+ animateTransform(element: HTMLElement, properties: TransformParams, duration?: number | null, easing?: string | null): Promise<void>;
91
+ /**
92
+ * Reset element to its original transform
93
+ * @param element - The element to reset
94
+ * @param originalState - Original transform state {x, y, rotation, scale}
95
+ * @returns Promise that resolves when animation completes
96
+ */
97
+ resetTransform(element: HTMLElement, originalState: TransformParams | ImageLayout): Promise<void>;
98
+ /**
99
+ * Remove transition styles from element
100
+ * @param element - The element to clear
101
+ */
102
+ clearTransition(element: HTMLElement): void;
103
+ /**
104
+ * Utility: Wait for a specified duration
105
+ * @param ms - Milliseconds to wait
106
+ * @returns Promise that resolves after the specified duration
107
+ */
108
+ wait(ms: number): Promise<void>;
109
+ }
110
+
111
+ /**
112
+ * Handle for a cancellable animation using Web Animations API
113
+ */
114
+ declare interface AnimationHandle {
115
+ id: string;
116
+ element: HTMLElement;
117
+ animation: Animation;
118
+ fromState: TransformParams;
119
+ toState: TransformParams;
120
+ startTime: number;
121
+ duration: number;
122
+ }
123
+
124
+ declare interface AnimationParams {
125
+ startTransform: string;
126
+ duration: number;
127
+ delay: number;
128
+ easing: string;
129
+ }
130
+
131
+ declare interface AnimationPerformanceConfig {
132
+ useGPU?: boolean;
133
+ reduceMotion?: boolean;
134
+ }
135
+
136
+ declare interface AnimationQueueConfig {
137
+ enabled: boolean;
138
+ interval: number;
139
+ maxConcurrent?: number;
140
+ }
141
+
142
+ /**
143
+ * Snapshot of an element's current transform state
144
+ * Used for capturing position mid-animation
145
+ */
146
+ declare interface AnimationSnapshot {
147
+ x: number;
148
+ y: number;
149
+ rotation: number;
150
+ scale: number;
151
+ }
152
+
153
+ declare interface BorderConfig {
154
+ width?: number;
155
+ color?: string;
156
+ radius?: number;
157
+ style?: BorderStyle;
158
+ }
159
+
160
+ export declare type BorderStyle = 'solid' | 'dashed' | 'dotted' | 'double' | 'none' | 'groove' | 'ridge' | 'inset' | 'outset' | 'hidden';
161
+
162
+ /**
163
+ * Bounce path presets - overshoot and settle animations
164
+ */
165
+ export declare const BOUNCE_PRESETS: Record<BouncePreset, BouncePathConfig>;
166
+
167
+ export declare interface BouncePathConfig {
168
+ overshoot: number;
169
+ bounces: 1 | 2 | 3;
170
+ decayRatio: number;
171
+ }
172
+
173
+ export declare type BouncePreset = 'energetic' | 'playful' | 'subtle';
174
+
175
+ export declare interface ClusterAlgorithmConfig {
176
+ clusterCount: number | 'auto';
177
+ clusterSpread: number;
178
+ clusterSpacing: number;
179
+ density: 'uniform' | 'varied';
180
+ overlap: number;
181
+ distribution: 'gaussian' | 'uniform';
182
+ }
183
+
184
+ declare interface ClusterLayoutOptions extends Partial<LayoutConfig> {
185
+ fixedHeight?: number;
186
+ }
187
+
188
+ export declare class ClusterPlacementGenerator implements PlacementGenerator {
189
+ private config;
190
+ private imageConfig;
191
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
192
+ /**
193
+ * Generate cluster layout positions for images
194
+ * @param imageCount - Number of images to layout
195
+ * @param containerBounds - Container dimensions {width, height}
196
+ * @param options - Optional overrides (includes fixedHeight)
197
+ * @returns Array of layout objects with position, rotation, scale
198
+ */
199
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: ClusterLayoutOptions): ImageLayout[];
200
+ /**
201
+ * Calculate optimal number of clusters based on image count and container
202
+ */
203
+ private calculateClusterCount;
204
+ /**
205
+ * Generate cluster center positions with spacing constraints
206
+ */
207
+ private generateClusterCenters;
208
+ /**
209
+ * Calculate spread for a cluster (may vary if density='varied')
210
+ */
211
+ private calculateClusterSpread;
212
+ /**
213
+ * Generate a random number with approximately Gaussian distribution
214
+ * Using Box-Muller transform
215
+ */
216
+ private gaussianRandom;
217
+ /**
218
+ * Utility: Generate random number between min and max
219
+ */
220
+ private random;
221
+ }
222
+
223
+ export declare class CompositeLoader implements ImageLoader {
224
+ private loaders;
225
+ private debugLogging;
226
+ private _prepared;
227
+ private _discoveredUrls;
228
+ constructor(config: CompositeLoaderConfig);
229
+ /**
230
+ * Prepare all loaders in parallel and combine their results
231
+ * @param filter - Filter to apply to discovered images
232
+ */
233
+ prepare(filter: IImageFilter): Promise<void>;
234
+ /**
235
+ * Get the combined number of discovered images
236
+ * @throws Error if called before prepare()
237
+ */
238
+ imagesLength(): number;
239
+ /**
240
+ * Get the combined ordered list of image URLs
241
+ * @throws Error if called before prepare()
242
+ */
243
+ imageURLs(): string[];
244
+ /**
245
+ * Check if the loader has been prepared
246
+ */
247
+ isPrepared(): boolean;
248
+ /**
249
+ * Debug logging helper
250
+ * @param args - Arguments to log
251
+ */
252
+ private log;
253
+ }
254
+
255
+ export declare interface CompositeLoaderConfig {
256
+ loaders: ImageLoader[];
257
+ debugLogging?: boolean;
258
+ }
259
+
260
+ export declare interface CompositeLoaderConfigJson {
261
+ loaders: LoaderConfig[];
262
+ debugLogging?: boolean;
263
+ }
264
+
265
+ export declare interface ContainerBounds {
266
+ width: number;
267
+ height: number;
268
+ }
269
+
270
+ /**
271
+ * Default configuration object
272
+ * Frozen to prevent accidental modifications
273
+ */
274
+ export declare const DEFAULT_CONFIG: ImageCloudConfig;
275
+
276
+ declare interface DropShadowConfig {
277
+ x: number;
278
+ y: number;
279
+ blur: number;
280
+ color: string;
281
+ }
282
+
283
+ /**
284
+ * Elastic path presets - spring-like oscillation animations
285
+ */
286
+ export declare const ELASTIC_PRESETS: Record<ElasticPreset, ElasticPathConfig>;
287
+
288
+ export declare interface ElasticPathConfig {
289
+ stiffness: number;
290
+ damping: number;
291
+ mass: number;
292
+ oscillations: number;
293
+ }
294
+
295
+ export declare type ElasticPreset = 'gentle' | 'bouncy' | 'wobbly' | 'snappy';
296
+
297
+ declare interface EntryAnimationConfig {
298
+ start: EntryStartConfig;
299
+ timing: EntryTimingConfig;
300
+ easing: string;
301
+ path?: EntryPathConfig;
302
+ rotation?: EntryRotationConfig;
303
+ scale?: EntryScaleConfig;
304
+ }
305
+
306
+ export declare class EntryAnimationEngine {
307
+ private config;
308
+ private layoutAlgorithm;
309
+ private resolvedStartPosition;
310
+ private pathConfig;
311
+ private rotationConfig;
312
+ private scaleConfig;
313
+ constructor(config: EntryAnimationConfig, layoutAlgorithm: LayoutAlgorithm);
314
+ /**
315
+ * Get the effective start position, considering layout-aware defaults
316
+ */
317
+ private resolveStartPosition;
318
+ /**
319
+ * Calculate the starting position for an image's entry animation
320
+ */
321
+ calculateStartPosition(finalPosition: {
322
+ x: number;
323
+ y: number;
324
+ }, imageSize: {
325
+ width: number;
326
+ height: number;
327
+ }, containerBounds: ContainerBounds, imageIndex: number, totalImages: number): StartPosition;
328
+ /**
329
+ * Calculate start position from the nearest edge (current default behavior)
330
+ */
331
+ private calculateNearestEdge;
332
+ /**
333
+ * Calculate start position from a specific edge
334
+ */
335
+ private calculateEdgePosition;
336
+ /**
337
+ * Calculate start position from center with scale animation
338
+ */
339
+ private calculateCenterPosition;
340
+ /**
341
+ * Calculate start position from a random edge
342
+ */
343
+ private calculateRandomEdge;
344
+ /**
345
+ * Calculate start position on a circle around the container
346
+ */
347
+ private calculateCircularPosition;
348
+ /**
349
+ * Get animation parameters for an image
350
+ */
351
+ getAnimationParams(imageIndex: number): AnimationParams;
352
+ /**
353
+ * Build a CSS transform string for the start position
354
+ * Uses pixel-based centering offset for reliable cross-browser behavior
355
+ */
356
+ buildStartTransform(startPosition: StartPosition, finalPosition: {
357
+ x: number;
358
+ y: number;
359
+ }, finalRotation: number, finalScale: number, imageWidth?: number, imageHeight?: number, startRotation?: number, startScale?: number): string;
360
+ /**
361
+ * Build the final CSS transform string
362
+ * Uses pixel-based centering offset for reliable cross-browser behavior
363
+ */
364
+ buildFinalTransform(rotation: number, scale: number, imageWidth?: number, imageHeight?: number): string;
365
+ /**
366
+ * Get the transition CSS for entry animation
367
+ * For JS-animated paths, only animate opacity (transform handled by JS)
368
+ */
369
+ getTransitionCSS(): string;
370
+ /**
371
+ * Check if the current path type requires JavaScript animation
372
+ */
373
+ requiresJSAnimation(): boolean;
374
+ /**
375
+ * Get the path configuration
376
+ */
377
+ getPathConfig(): EntryPathConfig;
378
+ /**
379
+ * Get the path type
380
+ */
381
+ getPathType(): EntryPathType;
382
+ /**
383
+ * Get animation timing configuration
384
+ */
385
+ getTiming(): {
386
+ duration: number;
387
+ stagger: number;
388
+ };
389
+ /**
390
+ * Get the rotation configuration
391
+ */
392
+ getRotationConfig(): EntryRotationConfig;
393
+ /**
394
+ * Get the rotation mode
395
+ */
396
+ getRotationMode(): EntryRotationMode;
397
+ /**
398
+ * Calculate the starting rotation for an entry animation
399
+ * @param finalRotation - The final rotation from the layout
400
+ * @returns The starting rotation in degrees
401
+ */
402
+ calculateStartRotation(finalRotation: number): number;
403
+ /**
404
+ * Resolve spin direction based on config
405
+ * @returns 1 for clockwise, -1 for counterclockwise
406
+ */
407
+ private resolveSpinDirection;
408
+ /**
409
+ * Check if the current rotation mode requires JavaScript animation
410
+ * (as opposed to CSS transitions)
411
+ */
412
+ requiresJSRotation(): boolean;
413
+ /**
414
+ * Calculate wobble rotation for a given animation progress
415
+ * @param progress - Animation progress from 0 to 1
416
+ * @param finalRotation - The final rotation in degrees
417
+ * @returns The current rotation in degrees
418
+ */
419
+ calculateWobbleRotation(progress: number, finalRotation: number): number;
420
+ /**
421
+ * Get the scale configuration
422
+ */
423
+ getScaleConfig(): EntryScaleConfig;
424
+ /**
425
+ * Get the scale mode
426
+ */
427
+ getScaleMode(): EntryScaleMode;
428
+ /**
429
+ * Calculate the starting scale for an entry animation
430
+ * @param finalScale - The final scale from the layout
431
+ * @returns The starting scale
432
+ */
433
+ calculateStartScale(finalScale: number): number;
434
+ /**
435
+ * Check if the current scale mode requires JavaScript animation
436
+ * (as opposed to CSS transitions)
437
+ */
438
+ requiresJSScale(): boolean;
439
+ /**
440
+ * Calculate pop scale for a given animation progress
441
+ * @param progress - Animation progress from 0 to 1
442
+ * @param finalScale - The final scale value
443
+ * @returns The current scale value with bounce effect
444
+ */
445
+ calculatePopScale(progress: number, finalScale: number): number;
446
+ /**
447
+ * Generate keyframes for scale bounce animation
448
+ */
449
+ private generateScaleBounceKeyframes;
450
+ /**
451
+ * Easing function for smooth transitions
452
+ */
453
+ private easeOutQuad;
454
+ }
455
+
456
+ declare interface EntryCircularConfig {
457
+ radius?: number | string;
458
+ distribution?: 'even' | 'random';
459
+ }
460
+
461
+ export declare interface EntryPathConfig {
462
+ type: EntryPathType;
463
+ bouncePreset?: BouncePreset;
464
+ elasticPreset?: ElasticPreset;
465
+ wavePreset?: WavePathPreset;
466
+ bounce?: Partial<BouncePathConfig>;
467
+ elastic?: Partial<ElasticPathConfig>;
468
+ wave?: Partial<WavePathConfig>;
469
+ }
470
+
471
+ export declare type EntryPathType = 'linear' | 'arc' | 'bounce' | 'elastic' | 'wave';
472
+
473
+ declare interface EntryRotationConfig {
474
+ mode: EntryRotationMode;
475
+ startRotation?: number | {
476
+ min: number;
477
+ max: number;
478
+ };
479
+ spinCount?: number;
480
+ direction?: 'clockwise' | 'counterclockwise' | 'auto' | 'random';
481
+ wobble?: {
482
+ amplitude: number;
483
+ frequency: number;
484
+ decay: boolean;
485
+ };
486
+ }
487
+
488
+ declare type EntryRotationMode = 'none' | 'settle' | 'spin' | 'wobble' | 'random';
489
+
490
+ declare interface EntryScaleConfig {
491
+ mode: EntryScaleMode;
492
+ startScale?: number;
493
+ range?: {
494
+ min: number;
495
+ max: number;
496
+ };
497
+ pop?: EntryScalePopConfig;
498
+ }
499
+
500
+ declare type EntryScaleMode = 'none' | 'grow' | 'shrink' | 'pop' | 'random';
501
+
502
+ declare interface EntryScalePopConfig {
503
+ overshoot: number;
504
+ bounces: number;
505
+ }
506
+
507
+ declare interface EntryStartConfig {
508
+ position: EntryStartPosition;
509
+ offset?: number;
510
+ circular?: EntryCircularConfig;
511
+ }
512
+
513
+ declare type EntryStartPosition = 'nearest-edge' | 'top' | 'bottom' | 'left' | 'right' | 'center' | 'random-edge' | 'circular';
514
+
515
+ declare interface EntryTimingConfig {
516
+ duration: number;
517
+ stagger: number;
518
+ }
519
+
520
+ declare interface FilterConfig {
521
+ grayscale?: number;
522
+ blur?: number;
523
+ brightness?: number;
524
+ contrast?: number;
525
+ saturate?: number;
526
+ opacity?: number;
527
+ sepia?: number;
528
+ hueRotate?: number;
529
+ invert?: number;
530
+ dropShadow?: DropShadowConfig | string;
531
+ }
532
+
533
+ declare interface FocusInteractionConfig {
534
+ scalePercent: number;
535
+ zIndex: number;
536
+ animationDuration?: number;
537
+ }
538
+
539
+ export declare type GalleryConfig = ImageCloudConfig;
540
+
541
+ declare interface GestureInteractionConfig {
542
+ pinchToZoom?: boolean;
543
+ doubleTapToFocus?: boolean;
544
+ }
545
+
546
+ declare interface GoogleDriveFilesSource {
547
+ type: 'files';
548
+ files: string[];
549
+ }
550
+
551
+ declare interface GoogleDriveFolderSource {
552
+ type: 'folder';
553
+ folders: string[];
554
+ recursive?: boolean;
555
+ }
556
+
557
+ export declare class GoogleDriveLoader implements ImageLoader {
558
+ private apiKey;
559
+ private apiEndpoint;
560
+ private debugLogging;
561
+ private sources;
562
+ private _prepared;
563
+ private _discoveredUrls;
564
+ constructor(config?: Partial<GoogleDriveLoaderConfig>);
565
+ /**
566
+ * Prepare the loader by discovering all images from configured sources
567
+ * @param filter - Filter to apply to discovered images
568
+ */
569
+ prepare(filter: IImageFilter): Promise<void>;
570
+ /**
571
+ * Get the number of discovered images
572
+ * @throws Error if called before prepare()
573
+ */
574
+ imagesLength(): number;
575
+ /**
576
+ * Get the ordered list of image URLs
577
+ * @throws Error if called before prepare()
578
+ */
579
+ imageURLs(): string[];
580
+ /**
581
+ * Check if the loader has been prepared
582
+ */
583
+ isPrepared(): boolean;
584
+ /**
585
+ * Extract folder ID from various Google Drive URL formats
586
+ * @param folderUrl - Google Drive folder URL
587
+ * @returns Folder ID or null if invalid
588
+ */
589
+ extractFolderId(folderUrl: string): string | null;
590
+ /**
591
+ * Load images from a Google Drive folder
592
+ * @param folderUrl - Google Drive folder URL
593
+ * @param filter - Filter to apply to discovered images
594
+ * @param recursive - Whether to include images from subfolders
595
+ * @returns Promise resolving to array of image URLs
596
+ */
597
+ private loadFromFolder;
598
+ /**
599
+ * Load images from a single folder (non-recursive)
600
+ * @param folderId - Google Drive folder ID
601
+ * @param filter - Filter to apply to discovered images
602
+ * @returns Promise resolving to array of image URLs
603
+ */
604
+ private loadImagesFromSingleFolder;
605
+ /**
606
+ * Load specific files by their URLs or IDs
607
+ * @param fileUrls - Array of Google Drive file URLs or IDs
608
+ * @param filter - Filter to apply to discovered images
609
+ * @returns Promise resolving to array of image URLs
610
+ */
611
+ private loadFiles;
612
+ /**
613
+ * Extract file ID from Google Drive file URL
614
+ * @param fileUrl - Google Drive file URL or file ID
615
+ * @returns File ID or null if invalid
616
+ */
617
+ private extractFileId;
618
+ /**
619
+ * Recursively load images from a folder and all its subfolders
620
+ * @param folderId - Google Drive folder ID
621
+ * @param filter - Filter to apply to discovered images
622
+ * @returns Promise resolving to array of image URLs
623
+ */
624
+ private loadImagesRecursively;
625
+ /**
626
+ * Direct loading method (no API key required, but less reliable)
627
+ * Uses embedded folder view to scrape image IDs
628
+ * @param folderId - Google Drive folder ID
629
+ * @param filter - Filter to apply (not used in fallback mode)
630
+ * @returns Promise resolving to array of image URLs
631
+ */
632
+ private loadImagesDirectly;
633
+ /**
634
+ * Manually add image URLs (for testing or when auto-loading fails)
635
+ * @param imageIds - Array of Google Drive file IDs
636
+ * @returns Array of direct image URLs
637
+ */
638
+ manualImageUrls(imageIds: string[]): string[];
639
+ /**
640
+ * Debug logging helper
641
+ * @param args - Arguments to log
642
+ */
643
+ private log;
644
+ }
645
+
646
+ export declare interface GoogleDriveLoaderConfig {
647
+ apiKey: string;
648
+ sources: GoogleDriveSource[];
649
+ apiEndpoint?: string;
650
+ allowedExtensions?: string[];
651
+ debugLogging?: boolean;
652
+ }
653
+
654
+ declare type GoogleDriveSource = GoogleDriveFolderSource | GoogleDriveFilesSource;
655
+
656
+ export declare interface GridAlgorithmConfig {
657
+ columns: number | 'auto';
658
+ rows: number | 'auto';
659
+ stagger: 'none' | 'row' | 'column';
660
+ jitter: number;
661
+ overlap: number;
662
+ fillDirection: 'row' | 'column';
663
+ alignment: 'start' | 'center' | 'end';
664
+ gap: number;
665
+ overflowOffset: number;
666
+ }
667
+
668
+ declare interface GridLayoutOptions extends Partial<LayoutConfig> {
669
+ fixedHeight?: number;
670
+ }
671
+
672
+ export declare class GridPlacementGenerator implements PlacementGenerator {
673
+ private config;
674
+ private imageConfig;
675
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
676
+ /**
677
+ * Generate grid layout positions for images
678
+ * @param imageCount - Number of images to layout
679
+ * @param containerBounds - Container dimensions {width, height}
680
+ * @param options - Optional overrides (includes fixedHeight)
681
+ * @returns Array of layout objects with position, rotation, scale
682
+ */
683
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: GridLayoutOptions): ImageLayout[];
684
+ /**
685
+ * Calculate optimal grid dimensions based on image count and container
686
+ */
687
+ private calculateGridDimensions;
688
+ /**
689
+ * Utility: Generate random number between min and max
690
+ */
691
+ private random;
692
+ }
693
+
694
+ /**
695
+ * ImageFilter interface for filtering images by extension
696
+ * Implemented by the ImageFilter class in loaders/ImageFilter.ts
697
+ */
698
+ export declare interface IImageFilter {
699
+ isAllowed(filename: string): boolean;
700
+ getAllowedExtensions(): string[];
701
+ }
702
+
703
+ declare class ImageCloud {
704
+ private containerId;
705
+ private containerRef;
706
+ private fullConfig;
707
+ private imagesLoaded;
708
+ private imageElements;
709
+ private imageLayouts;
710
+ private currentImageHeight;
711
+ private currentFocusIndex;
712
+ private hoveredImage;
713
+ private resizeTimeout;
714
+ private displayQueue;
715
+ private queueInterval;
716
+ private loadGeneration;
717
+ private defaultStyles;
718
+ private hoverStyles;
719
+ private defaultClassName;
720
+ private hoverClassName;
721
+ private animationEngine;
722
+ private entryAnimationEngine;
723
+ private layoutEngine;
724
+ private zoomEngine;
725
+ private imageLoader;
726
+ private imageFilter;
727
+ private containerEl;
728
+ private loadingEl;
729
+ private errorEl;
730
+ constructor(options?: ImageCloudOptions);
731
+ /**
732
+ * Create image filter based on config
733
+ */
734
+ private createImageFilter;
735
+ /**
736
+ * Create appropriate image loader based on config
737
+ */
738
+ private createLoader;
739
+ /**
740
+ * Create a loader from a LoaderConfig object (supports recursive composite loaders)
741
+ */
742
+ private createLoaderFromConfig;
743
+ /**
744
+ * Initialize the gallery
745
+ */
746
+ init(): Promise<void>;
747
+ private setupUI;
748
+ private setupEventListeners;
749
+ /**
750
+ * Navigate to the next image (Right arrow)
751
+ */
752
+ private navigateToNextImage;
753
+ /**
754
+ * Navigate to the previous image (Left arrow)
755
+ */
756
+ private navigateToPreviousImage;
757
+ /**
758
+ * Navigate to a specific image by index
759
+ */
760
+ private navigateToImage;
761
+ private handleResize;
762
+ private getImageHeight;
763
+ /**
764
+ * Get container bounds for layout calculations
765
+ */
766
+ private getContainerBounds;
767
+ /**
768
+ * Load images using the unified loader interface
769
+ */
770
+ private loadImages;
771
+ /**
772
+ * Helper for debug logging
773
+ */
774
+ private logDebug;
775
+ private createImageCloud;
776
+ private handleImageClick;
777
+ /**
778
+ * Clear the image cloud and reset state
779
+ */
780
+ clearImageCloud(): void;
781
+ private showLoading;
782
+ private showError;
783
+ private hideError;
784
+ /**
785
+ * Destroy the gallery and clean up resources
786
+ */
787
+ destroy(): void;
788
+ }
789
+ export { ImageCloud }
790
+ export { ImageCloud as ImageGallery }
791
+
792
+ export declare interface ImageCloudConfig {
793
+ loader: LoaderConfig;
794
+ image: ImageConfig;
795
+ layout: LayoutConfig;
796
+ animation: AnimationConfig;
797
+ interaction: InteractionConfig;
798
+ rendering: RenderingConfig;
799
+ styling?: ImageStylingConfig;
800
+ debug: boolean;
801
+ }
802
+
803
+ export declare interface ImageCloudOptions {
804
+ container?: string | HTMLElement;
805
+ loader?: Partial<LoaderConfig>;
806
+ image?: Partial<ImageConfig>;
807
+ layout?: Partial<LayoutConfig>;
808
+ animation?: Partial<AnimationConfig>;
809
+ interaction?: Partial<InteractionConfig>;
810
+ rendering?: Partial<RenderingConfig>;
811
+ styling?: Partial<ImageStylingConfig>;
812
+ debug?: boolean;
813
+ }
814
+
815
+ /**
816
+ * Combined image configuration
817
+ */
818
+ declare interface ImageConfig {
819
+ sizing?: ImageSizingConfig;
820
+ rotation?: ImageRotationConfig;
821
+ }
822
+
823
+ /**
824
+ * ImageFilter.ts
825
+ * Filters images by extension, designed for future extensibility
826
+ * (e.g., size filters, date filters, etc.)
827
+ */
828
+ export declare class ImageFilter {
829
+ private allowedExtensions;
830
+ /**
831
+ * Create a new ImageFilter
832
+ * @param extensions - Array of allowed file extensions (without dots)
833
+ * Defaults to common image formats if not provided
834
+ */
835
+ constructor(extensions?: string[]);
836
+ /**
837
+ * Check if a filename has an allowed extension
838
+ * @param filename - The filename to check (can include path or query string)
839
+ * @returns True if the file extension is allowed
840
+ */
841
+ isAllowed(filename: string): boolean;
842
+ /**
843
+ * Get the list of allowed extensions
844
+ * @returns Array of allowed extensions
845
+ */
846
+ getAllowedExtensions(): string[];
847
+ }
848
+
849
+ export declare type ImageGalleryOptions = ImageCloudOptions;
850
+
851
+ /**
852
+ * Type definitions for Image Gallery Library
853
+ */
854
+ export declare interface ImageLayout {
855
+ id: number;
856
+ x: number;
857
+ y: number;
858
+ rotation: number;
859
+ scale: number;
860
+ baseSize: number;
861
+ zIndex?: number;
862
+ borderColor?: string;
863
+ }
864
+
865
+ /**
866
+ * ImageLoader interface with consistent lifecycle pattern:
867
+ * 1. Constructor - Initialize with required parameters, throw if missing
868
+ * 2. prepare(filter) - Async discovery of images, accepts filter
869
+ * 3. imagesLength() - Return count of images (after prepare)
870
+ * 4. imageURLs() - Return ordered list of URLs (after prepare)
871
+ */
872
+ export declare interface ImageLoader {
873
+ /**
874
+ * Async preparation - discovers images and applies filter
875
+ * Succeeds even if 0 images found (gallery handles empty state)
876
+ * @param filter - Filter to apply to discovered images
877
+ */
878
+ prepare(filter: IImageFilter): Promise<void>;
879
+ /**
880
+ * Get the number of discovered images
881
+ * @throws Error if called before prepare() completes
882
+ */
883
+ imagesLength(): number;
884
+ /**
885
+ * Get the ordered list of image URLs
886
+ * @throws Error if called before prepare() completes
887
+ */
888
+ imageURLs(): string[];
889
+ /**
890
+ * Check if the loader has been prepared
891
+ */
892
+ isPrepared(): boolean;
893
+ }
894
+
895
+ /**
896
+ * Image rotation configuration
897
+ */
898
+ declare interface ImageRotationConfig {
899
+ mode: ImageRotationMode;
900
+ range?: ImageRotationRange;
901
+ }
902
+
903
+ /**
904
+ * Image rotation mode
905
+ */
906
+ declare type ImageRotationMode = 'none' | 'random' | 'tangent';
907
+
908
+ /**
909
+ * Image rotation range configuration
910
+ */
911
+ declare interface ImageRotationRange {
912
+ min: number;
913
+ max: number;
914
+ }
915
+
916
+ /**
917
+ * Image sizing configuration
918
+ */
919
+ declare interface ImageSizingConfig {
920
+ baseHeight?: number | ResponsiveBaseHeight;
921
+ variance?: ImageVarianceConfig;
922
+ scaleDecay?: number;
923
+ }
924
+
925
+ declare interface ImageStyleState {
926
+ className?: string | string[];
927
+ border?: BorderConfig;
928
+ borderTop?: Partial<BorderConfig>;
929
+ borderRight?: Partial<BorderConfig>;
930
+ borderBottom?: Partial<BorderConfig>;
931
+ borderLeft?: Partial<BorderConfig>;
932
+ borderRadiusTopLeft?: number;
933
+ borderRadiusTopRight?: number;
934
+ borderRadiusBottomRight?: number;
935
+ borderRadiusBottomLeft?: number;
936
+ shadow?: ShadowPreset | string;
937
+ filter?: FilterConfig;
938
+ opacity?: number;
939
+ cursor?: string;
940
+ outline?: OutlineConfig;
941
+ objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
942
+ aspectRatio?: string;
943
+ }
944
+
945
+ declare interface ImageStylingConfig {
946
+ default?: ImageStyleState;
947
+ hover?: Partial<ImageStyleState>;
948
+ focused?: Partial<ImageStyleState>;
949
+ }
950
+
951
+ /**
952
+ * Image variance configuration
953
+ * Controls random size variation applied to images
954
+ */
955
+ declare interface ImageVarianceConfig {
956
+ min: number;
957
+ max: number;
958
+ }
959
+
960
+ declare interface InteractionConfig {
961
+ focus: FocusInteractionConfig;
962
+ navigation?: NavigationInteractionConfig;
963
+ gestures?: GestureInteractionConfig;
964
+ }
965
+
966
+ export declare type LayoutAlgorithm = 'random' | 'radial' | 'grid' | 'spiral' | 'cluster' | 'wave';
967
+
968
+ export declare interface LayoutConfig {
969
+ algorithm: LayoutAlgorithm;
970
+ sizing: LayoutSizingConfig;
971
+ spacing: LayoutSpacingConfig;
972
+ targetCoverage?: number;
973
+ densityFactor?: number;
974
+ debugRadials?: boolean;
975
+ debugCenters?: boolean;
976
+ grid?: GridAlgorithmConfig;
977
+ spiral?: SpiralAlgorithmConfig;
978
+ cluster?: ClusterAlgorithmConfig;
979
+ wave?: WaveAlgorithmConfig;
980
+ }
981
+
982
+ export declare class LayoutEngine {
983
+ private config;
984
+ private imageConfig;
985
+ private breakpoints;
986
+ private layouts;
987
+ private generator;
988
+ constructor(config: LayoutEngineConfig);
989
+ /**
990
+ * Initialize the appropriate generator based on config type
991
+ * @returns Initialized placement generator
992
+ */
993
+ private initGenerator;
994
+ /**
995
+ * Generate layout positions for images
996
+ * @param imageCount - Number of images to layout
997
+ * @param containerBounds - Container dimensions {width, height}
998
+ * @param options - Optional overrides for configuration (e.g. fixedHeight)
999
+ * @returns Array of layout objects with position, rotation, scale
1000
+ */
1001
+ generateLayout(imageCount: number, containerBounds: ContainerBounds, options?: Partial<LayoutConfig>): ImageLayout[];
1002
+ /**
1003
+ * Get the original layout state for an image
1004
+ * @param imageId - The image ID (number or string)
1005
+ * @returns Original layout state or undefined if not found
1006
+ */
1007
+ getOriginalState(imageId: number | string): ImageLayout | undefined;
1008
+ /**
1009
+ * Reset all stored layouts
1010
+ */
1011
+ reset(): void;
1012
+ /**
1013
+ * Update config dynamically (useful for responsive changes)
1014
+ * @param newConfig - Updated configuration
1015
+ */
1016
+ updateConfig(newConfig: Partial<LayoutEngineConfig>): void;
1017
+ /**
1018
+ * Resolve the effective base height based on image config and current viewport
1019
+ * @param viewportWidth - Current viewport width
1020
+ * @returns Resolved base height or undefined if should auto-calculate
1021
+ */
1022
+ resolveBaseHeight(viewportWidth: number): number | undefined;
1023
+ /**
1024
+ * Calculate adaptive image size based on container dimensions and image count
1025
+ * @param containerBounds - Container dimensions {width, height}
1026
+ * @param imageCount - Number of images to display
1027
+ * @param responsiveHeight - Current responsive breakpoint height (upper bound)
1028
+ * @param viewportWidth - Current viewport width for baseHeight resolution
1029
+ * @returns Calculated sizing result with height
1030
+ */
1031
+ calculateAdaptiveSize(containerBounds: ContainerBounds, imageCount: number, responsiveHeight: number, viewportWidth: number): AdaptiveSizingResult;
1032
+ /**
1033
+ * Utility: Clamp a value between min and max
1034
+ */
1035
+ private clamp;
1036
+ }
1037
+
1038
+ declare interface LayoutEngineConfig {
1039
+ layout: LayoutConfig;
1040
+ image: ImageConfig;
1041
+ breakpoints?: {
1042
+ mobile: number;
1043
+ tablet?: number;
1044
+ };
1045
+ }
1046
+
1047
+ declare interface LayoutSizingConfig {
1048
+ base: number;
1049
+ responsive: ResponsiveHeight[];
1050
+ adaptive?: AdaptiveSizingConfig;
1051
+ }
1052
+
1053
+ declare interface LayoutSpacingConfig {
1054
+ padding: number;
1055
+ minGap: number;
1056
+ }
1057
+
1058
+ export declare interface LoaderConfig {
1059
+ type: 'googleDrive' | 'static' | 'composite';
1060
+ googleDrive?: GoogleDriveLoaderConfig;
1061
+ static?: StaticLoaderConfig;
1062
+ composite?: CompositeLoaderConfigJson;
1063
+ }
1064
+
1065
+ declare interface NavigationInteractionConfig {
1066
+ keyboard?: boolean;
1067
+ swipe?: boolean;
1068
+ mouseWheel?: boolean;
1069
+ }
1070
+
1071
+ declare interface OutlineConfig {
1072
+ width?: number;
1073
+ color?: string;
1074
+ style?: BorderStyle;
1075
+ offset?: number;
1076
+ }
1077
+
1078
+ declare interface PathAnimationOptions {
1079
+ element: HTMLElement;
1080
+ startPosition: Point;
1081
+ endPosition: Point;
1082
+ pathConfig: EntryPathConfig;
1083
+ duration: number;
1084
+ imageWidth: number;
1085
+ imageHeight: number;
1086
+ rotation: number;
1087
+ scale: number;
1088
+ onComplete?: () => void;
1089
+ rotationConfig?: EntryRotationConfig;
1090
+ startRotation?: number;
1091
+ scaleConfig?: EntryScaleConfig;
1092
+ startScale?: number;
1093
+ }
1094
+
1095
+ declare interface PerformanceRenderingConfig {
1096
+ lazyLoad?: boolean;
1097
+ preloadCount?: number;
1098
+ imageQuality?: 'auto' | 'high' | 'medium' | 'low';
1099
+ }
1100
+
1101
+ export declare interface PlacementGenerator {
1102
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: Partial<LayoutConfig>): ImageLayout[];
1103
+ }
1104
+
1105
+ declare interface Point {
1106
+ x: number;
1107
+ y: number;
1108
+ }
1109
+
1110
+ declare interface RadialLayoutOptions extends Partial<LayoutConfig> {
1111
+ fixedHeight?: number;
1112
+ }
1113
+
1114
+ export declare class RadialPlacementGenerator implements PlacementGenerator {
1115
+ private config;
1116
+ private imageConfig;
1117
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1118
+ /**
1119
+ * Generate radial layout positions for images
1120
+ * @param imageCount - Number of images to layout
1121
+ * @param containerBounds - Container dimensions {width, height}
1122
+ * @param options - Optional overrides
1123
+ * @returns Array of layout objects with position, rotation, scale
1124
+ */
1125
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: RadialLayoutOptions): ImageLayout[];
1126
+ /**
1127
+ * Estimate image width based on height
1128
+ * Assumes landscape aspect ratio (approximately 1.4:1)
1129
+ * @param height - Image height
1130
+ * @returns Estimated width
1131
+ */
1132
+ private estimateWidth;
1133
+ /**
1134
+ * Utility: Generate random number between min and max
1135
+ * @param min - Minimum value
1136
+ * @param max - Maximum value
1137
+ * @returns Random number in range
1138
+ */
1139
+ private random;
1140
+ }
1141
+
1142
+ declare interface RandomLayoutOptions extends Partial<LayoutConfig> {
1143
+ fixedHeight?: number;
1144
+ }
1145
+
1146
+ export declare class RandomPlacementGenerator implements PlacementGenerator {
1147
+ private config;
1148
+ private imageConfig;
1149
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1150
+ /**
1151
+ * Generate random layout positions for images
1152
+ * @param imageCount - Number of images to layout
1153
+ * @param containerBounds - Container dimensions {width, height}
1154
+ * @param options - Optional overrides (includes fixedHeight)
1155
+ * @returns Array of layout objects with position, rotation, scale
1156
+ */
1157
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: RandomLayoutOptions): ImageLayout[];
1158
+ /**
1159
+ * Utility: Generate random number between min and max
1160
+ * @param min - Minimum value
1161
+ * @param max - Maximum value
1162
+ * @returns Random number in range
1163
+ */
1164
+ private random;
1165
+ }
1166
+
1167
+ declare interface RenderingConfig {
1168
+ responsive: ResponsiveRenderingConfig;
1169
+ ui: UIRenderingConfig;
1170
+ performance?: PerformanceRenderingConfig;
1171
+ }
1172
+
1173
+ /**
1174
+ * Check if a path type requires JavaScript animation (vs CSS transitions)
1175
+ */
1176
+ export declare function requiresJSAnimation(pathType: EntryPathType): boolean;
1177
+
1178
+ /**
1179
+ * Responsive base height configuration
1180
+ * Can be a simple number or responsive breakpoint object
1181
+ */
1182
+ declare interface ResponsiveBaseHeight {
1183
+ default: number;
1184
+ tablet?: number;
1185
+ mobile?: number;
1186
+ }
1187
+
1188
+ export declare interface ResponsiveHeight {
1189
+ minWidth: number;
1190
+ height: number;
1191
+ }
1192
+
1193
+ export declare interface ResponsiveRenderingConfig {
1194
+ breakpoints: {
1195
+ mobile: number;
1196
+ tablet?: number;
1197
+ desktop?: number;
1198
+ };
1199
+ mobileDetection: () => boolean;
1200
+ }
1201
+
1202
+ declare type ShadowPreset = 'none' | 'sm' | 'md' | 'lg' | 'glow';
1203
+
1204
+ export declare interface SpiralAlgorithmConfig {
1205
+ spiralType: 'golden' | 'archimedean' | 'logarithmic';
1206
+ direction: 'clockwise' | 'counterclockwise';
1207
+ tightness: number;
1208
+ scaleDecay: number;
1209
+ startAngle: number;
1210
+ }
1211
+
1212
+ declare interface SpiralLayoutOptions extends Partial<LayoutConfig> {
1213
+ fixedHeight?: number;
1214
+ }
1215
+
1216
+ export declare class SpiralPlacementGenerator implements PlacementGenerator {
1217
+ private config;
1218
+ private imageConfig;
1219
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1220
+ /**
1221
+ * Generate spiral layout positions for images
1222
+ * @param imageCount - Number of images to layout
1223
+ * @param containerBounds - Container dimensions {width, height}
1224
+ * @param options - Optional overrides (includes fixedHeight)
1225
+ * @returns Array of layout objects with position, rotation, scale
1226
+ */
1227
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: SpiralLayoutOptions): ImageLayout[];
1228
+ /**
1229
+ * Calculate tangent angle for spiral curve at given position
1230
+ * This aligns the image along the spiral's direction of travel
1231
+ */
1232
+ private calculateSpiralTangent;
1233
+ /**
1234
+ * Calculate radius for golden spiral (Vogel's model)
1235
+ * Creates even distribution like sunflower seeds
1236
+ */
1237
+ private calculateGoldenRadius;
1238
+ /**
1239
+ * Calculate radius for Archimedean spiral
1240
+ * r = a + b*θ (constant spacing between arms)
1241
+ */
1242
+ private calculateArchimedeanRadius;
1243
+ /**
1244
+ * Calculate radius for logarithmic (equiangular) spiral
1245
+ * r = a * e^(b*θ)
1246
+ */
1247
+ private calculateLogarithmicRadius;
1248
+ /**
1249
+ * Utility: Generate random number between min and max
1250
+ */
1251
+ private random;
1252
+ }
1253
+
1254
+ declare interface StartPosition {
1255
+ x: number;
1256
+ y: number;
1257
+ useScale?: boolean;
1258
+ }
1259
+
1260
+ export declare class StaticImageLoader implements ImageLoader {
1261
+ private validateUrls;
1262
+ private validationTimeout;
1263
+ private validationMethod;
1264
+ private sources;
1265
+ private debugLogging;
1266
+ private _prepared;
1267
+ private _discoveredUrls;
1268
+ constructor(config?: Partial<StaticLoaderConfig>);
1269
+ /**
1270
+ * Prepare the loader by discovering all images from configured sources
1271
+ * @param filter - Filter to apply to discovered images
1272
+ */
1273
+ prepare(filter: IImageFilter): Promise<void>;
1274
+ /**
1275
+ * Get the number of discovered images
1276
+ * @throws Error if called before prepare()
1277
+ */
1278
+ imagesLength(): number;
1279
+ /**
1280
+ * Get the ordered list of image URLs
1281
+ * @throws Error if called before prepare()
1282
+ */
1283
+ imageURLs(): string[];
1284
+ /**
1285
+ * Check if the loader has been prepared
1286
+ */
1287
+ isPrepared(): boolean;
1288
+ /**
1289
+ * Process a single source object
1290
+ * @param source - Source configuration with type, urls, basePath, files
1291
+ * @param filter - Filter to apply to discovered images
1292
+ * @returns Promise resolving to array of valid URLs from this source
1293
+ */
1294
+ private processSource;
1295
+ /**
1296
+ * Process a list of direct URLs
1297
+ * @param urls - Array of image URLs
1298
+ * @param filter - Filter to apply to discovered images
1299
+ * @returns Promise resolving to array of validated URLs
1300
+ */
1301
+ private processUrls;
1302
+ /**
1303
+ * Process a path-based source
1304
+ * @param basePath - Base path (relative or absolute)
1305
+ * @param files - Array of filenames
1306
+ * @param filter - Filter to apply to discovered images
1307
+ * @returns Promise resolving to array of validated URLs
1308
+ */
1309
+ private processPath;
1310
+ /**
1311
+ * Validate a single URL using HEAD request
1312
+ * @param url - URL to validate
1313
+ * @returns Promise resolving to true if valid and accessible
1314
+ */
1315
+ private validateUrl;
1316
+ /**
1317
+ * Construct full URL from basePath and filename
1318
+ * @param basePath - Base path (relative or absolute)
1319
+ * @param filename - Filename to append
1320
+ * @returns Complete URL
1321
+ */
1322
+ private constructUrl;
1323
+ /**
1324
+ * Check if URL is absolute (contains protocol)
1325
+ * @param url - URL to check
1326
+ * @returns True if absolute URL
1327
+ */
1328
+ private isAbsoluteUrl;
1329
+ /**
1330
+ * Debug logging helper
1331
+ * @param args - Arguments to log
1332
+ */
1333
+ private log;
1334
+ }
1335
+
1336
+ export declare interface StaticLoaderConfig {
1337
+ sources: StaticSource[];
1338
+ validateUrls?: boolean;
1339
+ validationTimeout?: number;
1340
+ validationMethod?: 'head' | 'simple' | 'none';
1341
+ failOnAllMissing?: boolean;
1342
+ allowedExtensions?: string[];
1343
+ debugLogging?: boolean;
1344
+ }
1345
+
1346
+ export declare interface StaticSource {
1347
+ type: StaticSourceType;
1348
+ urls?: string[];
1349
+ basePath?: string;
1350
+ files?: string[];
1351
+ }
1352
+
1353
+ declare type StaticSourceType = 'urls' | 'path';
1354
+
1355
+ export declare interface TransformParams {
1356
+ x?: number;
1357
+ y?: number;
1358
+ rotation?: number;
1359
+ scale?: number;
1360
+ }
1361
+
1362
+ export declare interface UIRenderingConfig {
1363
+ showLoadingSpinner: boolean;
1364
+ showImageCounter?: boolean;
1365
+ showThumbnails?: boolean;
1366
+ theme?: 'light' | 'dark' | 'auto';
1367
+ }
1368
+
1369
+ /**
1370
+ * Wave path presets - sinusoidal path animations
1371
+ */
1372
+ export declare const WAVE_PATH_PRESETS: Record<WavePathPreset, WavePathConfig>;
1373
+
1374
+ declare interface WaveAlgorithmConfig {
1375
+ rows: number;
1376
+ amplitude: number;
1377
+ frequency: number;
1378
+ phaseShift: number;
1379
+ synchronization: 'offset' | 'synchronized' | 'alternating';
1380
+ }
1381
+
1382
+ export declare interface WavePathConfig {
1383
+ amplitude: number;
1384
+ frequency: number;
1385
+ decay: boolean;
1386
+ decayRate: number;
1387
+ phase: number;
1388
+ }
1389
+
1390
+ export declare type WavePathPreset = 'gentle' | 'playful' | 'serpentine' | 'flutter';
1391
+
1392
+ export declare class ZoomEngine {
1393
+ private config;
1394
+ private animationEngine;
1395
+ private state;
1396
+ private currentFocus;
1397
+ private focusData;
1398
+ private outgoing;
1399
+ private incoming;
1400
+ private focusGeneration;
1401
+ private defaultStyles;
1402
+ private focusedStyles;
1403
+ private defaultClassName;
1404
+ private focusedClassName;
1405
+ constructor(config: FocusInteractionConfig, animationEngine: AnimationEngine, styling?: ImageStylingConfig);
1406
+ /**
1407
+ * Get current state machine state
1408
+ */
1409
+ getState(): ZoomState;
1410
+ /**
1411
+ * Check if any animation is in progress
1412
+ */
1413
+ isAnimating(): boolean;
1414
+ /**
1415
+ * Normalize scalePercent value
1416
+ */
1417
+ private normalizeScalePercent;
1418
+ /**
1419
+ * Calculate target dimensions for focused image
1420
+ * Returns actual pixel dimensions instead of scale factor for sharper rendering
1421
+ */
1422
+ private calculateFocusDimensions;
1423
+ /**
1424
+ * Calculate the transform needed to center an image (position only, no scale)
1425
+ * Scale is handled by animating actual dimensions for sharper rendering
1426
+ */
1427
+ private calculateFocusTransform;
1428
+ /**
1429
+ * Build transform string for dimension-based zoom (no scale in transform)
1430
+ */
1431
+ private buildDimensionZoomTransform;
1432
+ /**
1433
+ * Create a Web Animation that animates both transform (position) and dimensions
1434
+ * This provides sharper zoom by re-rendering at target size instead of scaling pixels
1435
+ */
1436
+ private animateWithDimensions;
1437
+ /**
1438
+ * Apply focused styling to an element
1439
+ */
1440
+ private applyFocusedStyling;
1441
+ /**
1442
+ * Remove focused styling from an element
1443
+ */
1444
+ private removeFocusedStyling;
1445
+ /**
1446
+ * Start focus animation for an image using dimension-based zoom
1447
+ * Animates actual width/height for sharper rendering instead of transform scale
1448
+ * @param fromTransform - Optional starting transform (for mid-animation reversals)
1449
+ * @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
1450
+ */
1451
+ private startFocusAnimation;
1452
+ /**
1453
+ * Start unfocus animation for an image using dimension-based zoom
1454
+ * Animates back to original dimensions for consistent behavior
1455
+ * @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
1456
+ */
1457
+ private startUnfocusAnimation;
1458
+ /**
1459
+ * Handle animation completion
1460
+ */
1461
+ private waitForAnimation;
1462
+ /**
1463
+ * Reset an element instantly to its original position and dimensions (no animation)
1464
+ */
1465
+ private resetElementInstantly;
1466
+ /**
1467
+ * Focus (zoom) an image to center of container
1468
+ * Implements cross-animation when swapping focus
1469
+ */
1470
+ focusImage(imageElement: HTMLElement, containerBounds: ContainerBounds, originalState: ImageLayout): Promise<void>;
1471
+ /**
1472
+ * Unfocus current image, returning it to original position
1473
+ */
1474
+ unfocusImage(): Promise<void>;
1475
+ /**
1476
+ * Swap focus from current image to a new one (alias for focusImage with cross-animation)
1477
+ */
1478
+ swapFocus(newImageElement: HTMLElement, containerBounds: ContainerBounds, originalState: ImageLayout): Promise<void>;
1479
+ /**
1480
+ * Get currently focused image element
1481
+ */
1482
+ getCurrentFocus(): HTMLElement | null;
1483
+ /**
1484
+ * Check if an image is currently focused (stable state)
1485
+ */
1486
+ isFocused(imageElement: HTMLElement): boolean;
1487
+ /**
1488
+ * Check if an image is the target of current focus animation
1489
+ */
1490
+ isTargetingFocus(imageElement: HTMLElement): boolean;
1491
+ /**
1492
+ * Check if an image is involved in any focus/animation state
1493
+ * Returns true if the image is focused, animating in, or animating out
1494
+ * Useful for hover state management - don't apply hover to animating images
1495
+ */
1496
+ isInvolved(imageElement: HTMLElement): boolean;
1497
+ /**
1498
+ * Reset zoom state (cancels all animations)
1499
+ */
1500
+ reset(): void;
1501
+ }
1502
+
1503
+ /**
1504
+ * State machine states for zoom/focus animations
1505
+ */
1506
+ declare enum ZoomState {
1507
+ IDLE = "idle",// No focus, no animations
1508
+ FOCUSING = "focusing",// Single image animating in
1509
+ FOCUSED = "focused",// Stable focused state
1510
+ UNFOCUSING = "unfocusing",// Single image animating out
1511
+ CROSS_ANIMATING = "cross_animating"
1512
+ }
1513
+
1514
+ export { }