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