@frybynite/image-cloud 0.5.2 → 0.6.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.
Files changed (89) hide show
  1. package/README.md +46 -13
  2. package/dist/composite-CtUxtN2l.js +96 -0
  3. package/dist/composite-CtUxtN2l.js.map +1 -0
  4. package/dist/google-drive-CC-qFSV1.js +260 -0
  5. package/dist/google-drive-CC-qFSV1.js.map +1 -0
  6. package/dist/image-cloud-auto-init.js +345 -759
  7. package/dist/image-cloud-auto-init.js.map +1 -1
  8. package/dist/image-cloud.js +1248 -1204
  9. package/dist/image-cloud.js.map +1 -1
  10. package/dist/image-cloud.umd.js +5 -5
  11. package/dist/image-cloud.umd.js.map +1 -1
  12. package/dist/index.d.ts +1654 -23
  13. package/dist/loaders/all.d.ts +1654 -0
  14. package/dist/loaders/all.js +496 -0
  15. package/dist/loaders/all.js.map +1 -0
  16. package/dist/loaders/composite.d.ts +1654 -0
  17. package/dist/loaders/composite.js +96 -0
  18. package/dist/loaders/composite.js.map +1 -0
  19. package/dist/loaders/google-drive.d.ts +1654 -0
  20. package/dist/loaders/google-drive.js +260 -0
  21. package/dist/loaders/google-drive.js.map +1 -0
  22. package/dist/loaders/static.d.ts +1654 -0
  23. package/dist/loaders/static.js +219 -0
  24. package/dist/loaders/static.js.map +1 -0
  25. package/dist/react.d.ts +1654 -1
  26. package/dist/react.js +434 -848
  27. package/dist/react.js.map +1 -1
  28. package/dist/static-ejylHtQ4.js +219 -0
  29. package/dist/static-ejylHtQ4.js.map +1 -0
  30. package/dist/vue.d.ts +1654 -1
  31. package/dist/vue.js +442 -856
  32. package/dist/vue.js.map +1 -1
  33. package/dist/web-component.d.ts +1654 -1
  34. package/dist/web-component.js +429 -843
  35. package/dist/web-component.js.map +1 -1
  36. package/package.json +28 -15
  37. package/dist/ImageCloud.d.ts +0 -99
  38. package/dist/ImageCloud.d.ts.map +0 -1
  39. package/dist/config/adapter.d.ts +0 -50
  40. package/dist/config/adapter.d.ts.map +0 -1
  41. package/dist/config/defaults.d.ts +0 -118
  42. package/dist/config/defaults.d.ts.map +0 -1
  43. package/dist/config/types.d.ts +0 -599
  44. package/dist/config/types.d.ts.map +0 -1
  45. package/dist/engines/AnimationEngine.d.ts +0 -82
  46. package/dist/engines/AnimationEngine.d.ts.map +0 -1
  47. package/dist/engines/EntryAnimationEngine.d.ts +0 -161
  48. package/dist/engines/EntryAnimationEngine.d.ts.map +0 -1
  49. package/dist/engines/LayoutEngine.d.ts +0 -68
  50. package/dist/engines/LayoutEngine.d.ts.map +0 -1
  51. package/dist/engines/PathAnimator.d.ts +0 -50
  52. package/dist/engines/PathAnimator.d.ts.map +0 -1
  53. package/dist/engines/SwipeEngine.d.ts +0 -53
  54. package/dist/engines/SwipeEngine.d.ts.map +0 -1
  55. package/dist/engines/ZoomEngine.d.ts +0 -139
  56. package/dist/engines/ZoomEngine.d.ts.map +0 -1
  57. package/dist/image-cloud-auto-init.d.ts +0 -14
  58. package/dist/image-cloud-auto-init.d.ts.map +0 -1
  59. package/dist/index.d.ts.map +0 -1
  60. package/dist/layouts/ClusterPlacementLayout.d.ts +0 -40
  61. package/dist/layouts/ClusterPlacementLayout.d.ts.map +0 -1
  62. package/dist/layouts/GridPlacementLayout.d.ts +0 -27
  63. package/dist/layouts/GridPlacementLayout.d.ts.map +0 -1
  64. package/dist/layouts/RadialPlacementLayout.d.ts +0 -33
  65. package/dist/layouts/RadialPlacementLayout.d.ts.map +0 -1
  66. package/dist/layouts/RandomPlacementLayout.d.ts +0 -26
  67. package/dist/layouts/RandomPlacementLayout.d.ts.map +0 -1
  68. package/dist/layouts/SpiralPlacementLayout.d.ts +0 -43
  69. package/dist/layouts/SpiralPlacementLayout.d.ts.map +0 -1
  70. package/dist/layouts/WavePlacementLayout.d.ts +0 -48
  71. package/dist/layouts/WavePlacementLayout.d.ts.map +0 -1
  72. package/dist/loaders/CompositeLoader.d.ts +0 -37
  73. package/dist/loaders/CompositeLoader.d.ts.map +0 -1
  74. package/dist/loaders/GoogleDriveLoader.d.ts +0 -90
  75. package/dist/loaders/GoogleDriveLoader.d.ts.map +0 -1
  76. package/dist/loaders/ImageFilter.d.ts +0 -26
  77. package/dist/loaders/ImageFilter.d.ts.map +0 -1
  78. package/dist/loaders/StaticImageLoader.d.ts +0 -85
  79. package/dist/loaders/StaticImageLoader.d.ts.map +0 -1
  80. package/dist/react/index.d.ts +0 -16
  81. package/dist/react/index.d.ts.map +0 -1
  82. package/dist/styles/functionalStyles.d.ts +0 -11
  83. package/dist/styles/functionalStyles.d.ts.map +0 -1
  84. package/dist/utils/styleUtils.d.ts +0 -54
  85. package/dist/utils/styleUtils.d.ts.map +0 -1
  86. package/dist/vue/index.d.ts +0 -18
  87. package/dist/vue/index.d.ts.map +0 -1
  88. package/dist/web-component/index.d.ts +0 -15
  89. package/dist/web-component/index.d.ts.map +0 -1
@@ -1 +1,1654 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/web-component/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,MAAM,CAAC,kBAAkB,WAAkC;IAE3D,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,UAAU,CAA+B;IAEjD,iBAAiB,IAAI,IAAI;IAQzB,oBAAoB,IAAI,IAAI;IAQ5B,wBAAwB,CACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,GACtB,IAAI;IAQP,WAAW,IAAI,UAAU,GAAG,IAAI;IAIhC,OAAO,CAAC,WAAW;IAmCnB,OAAO,CAAC,KAAK;IAsBb,OAAO,CAAC,QAAQ;CAIjB;AAQD,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
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
+ * Uses dynamic imports to trigger loader registration and enable tree-shaking
761
+ */
762
+ private createLoader;
763
+ /**
764
+ * Create a single loader from a LoaderEntry, merging shared config
765
+ * Uses dynamic imports to trigger loader registration and enable tree-shaking
766
+ */
767
+ private createLoaderFromEntry;
768
+ /**
769
+ * Initialize the gallery
770
+ */
771
+ init(): Promise<void>;
772
+ private setupUI;
773
+ private resolveElement;
774
+ private createDefaultLoadingElement;
775
+ private createDefaultErrorElement;
776
+ private createDefaultCounterElement;
777
+ private setupEventListeners;
778
+ /**
779
+ * Navigate to the next image (Right arrow)
780
+ */
781
+ private navigateToNextImage;
782
+ /**
783
+ * Navigate to the previous image (Left arrow)
784
+ */
785
+ private navigateToPreviousImage;
786
+ /**
787
+ * Navigate to a specific image by index
788
+ */
789
+ private handleResize;
790
+ private getImageHeight;
791
+ /**
792
+ * Get container bounds for layout calculations
793
+ */
794
+ private getContainerBounds;
795
+ /**
796
+ * Load images using the unified loader interface
797
+ */
798
+ private loadImages;
799
+ /**
800
+ * Helper for debug logging
801
+ */
802
+ private logDebug;
803
+ private createImageCloud;
804
+ private handleImageClick;
805
+ /**
806
+ * Clear the image cloud and reset state
807
+ */
808
+ clearImageCloud(): void;
809
+ private showLoading;
810
+ private showError;
811
+ private hideError;
812
+ private updateCounter;
813
+ private hideCounter;
814
+ /**
815
+ * Destroy the gallery and clean up resources
816
+ */
817
+ destroy(): void;
818
+ }
819
+ export { ImageCloud }
820
+ export { ImageCloud as ImageGallery }
821
+
822
+ export declare interface ImageCloudConfig {
823
+ loaders: LoaderEntry[];
824
+ config: ConfigSection;
825
+ image: ImageConfig;
826
+ layout: LayoutConfig;
827
+ animation: AnimationConfig;
828
+ interaction: InteractionConfig;
829
+ rendering: RenderingConfig;
830
+ styling?: ImageStylingConfig;
831
+ }
832
+
833
+ export declare interface ImageCloudOptions {
834
+ container?: string | HTMLElement;
835
+ images?: string[];
836
+ loaders?: LoaderEntry[];
837
+ config?: ConfigSection;
838
+ image?: Partial<ImageConfig>;
839
+ layout?: Partial<LayoutConfig>;
840
+ animation?: Partial<AnimationConfig>;
841
+ interaction?: Partial<InteractionConfig>;
842
+ rendering?: Partial<RenderingConfig>;
843
+ styling?: Partial<ImageStylingConfig>;
844
+ }
845
+
846
+ /**
847
+ * Combined image configuration
848
+ */
849
+ declare interface ImageConfig {
850
+ sizing?: ImageSizingConfig;
851
+ rotation?: ImageRotationConfig;
852
+ }
853
+
854
+ /**
855
+ * ImageFilter.ts
856
+ * Filters images by extension, designed for future extensibility
857
+ * (e.g., size filters, date filters, etc.)
858
+ */
859
+ export declare class ImageFilter {
860
+ private allowedExtensions;
861
+ /**
862
+ * Create a new ImageFilter
863
+ * @param extensions - Array of allowed file extensions (without dots)
864
+ * Defaults to common image formats if not provided
865
+ */
866
+ constructor(extensions?: string[]);
867
+ /**
868
+ * Check if a filename has an allowed extension
869
+ * @param filename - The filename to check (can include path or query string)
870
+ * @returns True if the file extension is allowed
871
+ */
872
+ isAllowed(filename: string): boolean;
873
+ /**
874
+ * Get the list of allowed extensions
875
+ * @returns Array of allowed extensions
876
+ */
877
+ getAllowedExtensions(): string[];
878
+ }
879
+
880
+ export declare type ImageGalleryOptions = ImageCloudOptions;
881
+
882
+ /**
883
+ * Type definitions for Image Gallery Library
884
+ */
885
+ export declare interface ImageLayout {
886
+ id: number;
887
+ x: number;
888
+ y: number;
889
+ rotation: number;
890
+ scale: number;
891
+ baseSize: number;
892
+ zIndex?: number;
893
+ }
894
+
895
+ /**
896
+ * ImageLoader interface with consistent lifecycle pattern:
897
+ * 1. Constructor - Initialize with required parameters, throw if missing
898
+ * 2. prepare(filter) - Async discovery of images, accepts filter
899
+ * 3. imagesLength() - Return count of images (after prepare)
900
+ * 4. imageURLs() - Return ordered list of URLs (after prepare)
901
+ */
902
+ export declare interface ImageLoader {
903
+ /**
904
+ * Async preparation - discovers images and applies filter
905
+ * Succeeds even if 0 images found (gallery handles empty state)
906
+ * @param filter - Filter to apply to discovered images
907
+ */
908
+ prepare(filter: IImageFilter): Promise<void>;
909
+ /**
910
+ * Get the number of discovered images
911
+ * @throws Error if called before prepare() completes
912
+ */
913
+ imagesLength(): number;
914
+ /**
915
+ * Get the ordered list of image URLs
916
+ * @throws Error if called before prepare() completes
917
+ */
918
+ imageURLs(): string[];
919
+ /**
920
+ * Check if the loader has been prepared
921
+ */
922
+ isPrepared(): boolean;
923
+ }
924
+
925
+ /**
926
+ * Image rotation configuration
927
+ */
928
+ declare interface ImageRotationConfig {
929
+ mode: ImageRotationMode;
930
+ range?: ImageRotationRange;
931
+ }
932
+
933
+ /**
934
+ * Image rotation mode
935
+ */
936
+ declare type ImageRotationMode = 'none' | 'random' | 'tangent';
937
+
938
+ /**
939
+ * Image rotation range configuration
940
+ */
941
+ declare interface ImageRotationRange {
942
+ min: number;
943
+ max: number;
944
+ }
945
+
946
+ /**
947
+ * Image sizing configuration
948
+ */
949
+ declare interface ImageSizingConfig {
950
+ mode: SizingMode;
951
+ height?: number | FixedModeHeight;
952
+ minSize?: number;
953
+ maxSize?: number;
954
+ variance?: ImageVarianceConfig;
955
+ }
956
+
957
+ declare interface ImageStyleState {
958
+ className?: string | string[];
959
+ border?: BorderConfig;
960
+ borderTop?: Partial<BorderConfig>;
961
+ borderRight?: Partial<BorderConfig>;
962
+ borderBottom?: Partial<BorderConfig>;
963
+ borderLeft?: Partial<BorderConfig>;
964
+ borderRadiusTopLeft?: number;
965
+ borderRadiusTopRight?: number;
966
+ borderRadiusBottomRight?: number;
967
+ borderRadiusBottomLeft?: number;
968
+ shadow?: ShadowPreset | string;
969
+ filter?: FilterConfig;
970
+ opacity?: number;
971
+ cursor?: string;
972
+ outline?: OutlineConfig;
973
+ objectFit?: 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
974
+ aspectRatio?: string;
975
+ }
976
+
977
+ declare interface ImageStylingConfig {
978
+ default?: ImageStyleState;
979
+ hover?: Partial<ImageStyleState>;
980
+ focused?: Partial<ImageStyleState>;
981
+ }
982
+
983
+ /**
984
+ * Image variance configuration
985
+ * Controls random size variation applied to images
986
+ */
987
+ declare interface ImageVarianceConfig {
988
+ min: number;
989
+ max: number;
990
+ }
991
+
992
+ /**
993
+ * Inject functional styles into document head.
994
+ * Idempotent - safe to call multiple times.
995
+ */
996
+ export declare function injectFunctionalStyles(): void;
997
+
998
+ declare interface InteractionConfig {
999
+ focus: FocusInteractionConfig;
1000
+ navigation?: NavigationInteractionConfig;
1001
+ gestures?: GestureInteractionConfig;
1002
+ }
1003
+
1004
+ export declare type LayoutAlgorithm = 'random' | 'radial' | 'grid' | 'spiral' | 'cluster' | 'wave';
1005
+
1006
+ export declare interface LayoutConfig {
1007
+ algorithm: LayoutAlgorithm;
1008
+ spacing: LayoutSpacingConfig;
1009
+ scaleDecay?: number;
1010
+ responsive?: ResponsiveBreakpoints;
1011
+ targetCoverage?: number;
1012
+ densityFactor?: number;
1013
+ grid?: GridAlgorithmConfig;
1014
+ spiral?: SpiralAlgorithmConfig;
1015
+ cluster?: ClusterAlgorithmConfig;
1016
+ wave?: WaveAlgorithmConfig;
1017
+ }
1018
+
1019
+ export declare class LayoutEngine {
1020
+ private config;
1021
+ private imageConfig;
1022
+ private layouts;
1023
+ private placementLayout;
1024
+ constructor(config: LayoutEngineConfig);
1025
+ /**
1026
+ * Initialize the appropriate placement layout based on config type
1027
+ * @returns Initialized placement layout
1028
+ */
1029
+ private initLayout;
1030
+ /**
1031
+ * Generate layout positions for images
1032
+ * @param imageCount - Number of images to layout
1033
+ * @param containerBounds - Container dimensions {width, height}
1034
+ * @param options - Optional overrides for configuration (e.g. fixedHeight)
1035
+ * @returns Array of layout objects with position, rotation, scale
1036
+ */
1037
+ generateLayout(imageCount: number, containerBounds: ContainerBounds, options?: Partial<LayoutConfig>): ImageLayout[];
1038
+ /**
1039
+ * Get the original layout state for an image
1040
+ * @param imageId - The image ID (number or string)
1041
+ * @returns Original layout state or undefined if not found
1042
+ */
1043
+ getOriginalState(imageId: number | string): ImageLayout | undefined;
1044
+ /**
1045
+ * Reset all stored layouts
1046
+ */
1047
+ reset(): void;
1048
+ /**
1049
+ * Update config dynamically (useful for responsive changes)
1050
+ * @param newConfig - Updated configuration
1051
+ */
1052
+ updateConfig(newConfig: Partial<LayoutEngineConfig>): void;
1053
+ /**
1054
+ * Get responsive breakpoints from layout config
1055
+ */
1056
+ private getBreakpoints;
1057
+ /**
1058
+ * Resolve breakpoint name based on viewport width
1059
+ */
1060
+ resolveBreakpoint(viewportWidth: number): 'mobile' | 'tablet' | 'screen';
1061
+ /**
1062
+ * Resolve the effective base height based on image config and current viewport
1063
+ * @param viewportWidth - Current viewport width
1064
+ * @returns Resolved base height or undefined if should auto-calculate (adaptive mode)
1065
+ */
1066
+ resolveBaseHeight(viewportWidth: number): number | undefined;
1067
+ /**
1068
+ * Calculate adaptive image size based on container dimensions and image count
1069
+ * @param containerBounds - Container dimensions {width, height}
1070
+ * @param imageCount - Number of images to display
1071
+ * @param maxHeight - Maximum height constraint (upper bound)
1072
+ * @param viewportWidth - Current viewport width for baseHeight resolution
1073
+ * @returns Calculated sizing result with height
1074
+ */
1075
+ calculateAdaptiveSize(containerBounds: ContainerBounds, imageCount: number, maxHeight: number, viewportWidth: number): AdaptiveSizingResult;
1076
+ /**
1077
+ * Utility: Clamp a value between min and max
1078
+ */
1079
+ private clamp;
1080
+ }
1081
+
1082
+ declare interface LayoutEngineConfig {
1083
+ layout: LayoutConfig;
1084
+ image: ImageConfig;
1085
+ }
1086
+
1087
+ declare interface LayoutSpacingConfig {
1088
+ padding: number;
1089
+ minGap: number;
1090
+ }
1091
+
1092
+ export declare type LoaderEntry = StaticLoaderEntry | GoogleDriveLoaderEntry;
1093
+
1094
+ declare interface NavigationInteractionConfig {
1095
+ keyboard?: boolean;
1096
+ swipe?: boolean;
1097
+ mouseWheel?: boolean;
1098
+ }
1099
+
1100
+ declare interface OutlineConfig {
1101
+ width?: number;
1102
+ color?: string;
1103
+ style?: BorderStyle;
1104
+ offset?: number;
1105
+ }
1106
+
1107
+ declare interface PathAnimationOptions {
1108
+ element: HTMLElement;
1109
+ startPosition: Point;
1110
+ endPosition: Point;
1111
+ pathConfig: EntryPathConfig;
1112
+ duration: number;
1113
+ imageWidth: number;
1114
+ imageHeight: number;
1115
+ rotation: number;
1116
+ scale: number;
1117
+ onComplete?: () => void;
1118
+ rotationConfig?: EntryRotationConfig;
1119
+ startRotation?: number;
1120
+ scaleConfig?: EntryScaleConfig;
1121
+ startScale?: number;
1122
+ }
1123
+
1124
+ declare interface PerformanceRenderingConfig {
1125
+ lazyLoad?: boolean;
1126
+ preloadCount?: number;
1127
+ imageQuality?: 'auto' | 'high' | 'medium' | 'low';
1128
+ }
1129
+
1130
+ export declare interface PlacementLayout {
1131
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: Partial<LayoutConfig>): ImageLayout[];
1132
+ }
1133
+
1134
+ declare interface Point {
1135
+ x: number;
1136
+ y: number;
1137
+ }
1138
+
1139
+ declare interface RadialLayoutOptions extends Partial<LayoutConfig> {
1140
+ fixedHeight?: number;
1141
+ }
1142
+
1143
+ export declare class RadialPlacementLayout implements PlacementLayout {
1144
+ private config;
1145
+ private imageConfig;
1146
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1147
+ /**
1148
+ * Generate radial layout positions for images
1149
+ * @param imageCount - Number of images to layout
1150
+ * @param containerBounds - Container dimensions {width, height}
1151
+ * @param options - Optional overrides
1152
+ * @returns Array of layout objects with position, rotation, scale
1153
+ */
1154
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: RadialLayoutOptions): ImageLayout[];
1155
+ /**
1156
+ * Estimate image width based on height
1157
+ * Assumes landscape aspect ratio (approximately 1.4:1)
1158
+ * @param height - Image height
1159
+ * @returns Estimated width
1160
+ */
1161
+ private estimateWidth;
1162
+ /**
1163
+ * Utility: Generate random number between min and max
1164
+ * @param min - Minimum value
1165
+ * @param max - Maximum value
1166
+ * @returns Random number in range
1167
+ */
1168
+ private random;
1169
+ }
1170
+
1171
+ declare interface RandomLayoutOptions extends Partial<LayoutConfig> {
1172
+ fixedHeight?: number;
1173
+ }
1174
+
1175
+ export declare class RandomPlacementLayout implements PlacementLayout {
1176
+ private config;
1177
+ private imageConfig;
1178
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1179
+ /**
1180
+ * Generate random layout positions for images
1181
+ * @param imageCount - Number of images to layout
1182
+ * @param containerBounds - Container dimensions {width, height}
1183
+ * @param options - Optional overrides (includes fixedHeight)
1184
+ * @returns Array of layout objects with position, rotation, scale
1185
+ */
1186
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: RandomLayoutOptions): ImageLayout[];
1187
+ /**
1188
+ * Utility: Generate random number between min and max
1189
+ * @param min - Minimum value
1190
+ * @param max - Maximum value
1191
+ * @returns Random number in range
1192
+ */
1193
+ private random;
1194
+ }
1195
+
1196
+ declare interface RenderingConfig {
1197
+ responsive: ResponsiveRenderingConfig;
1198
+ ui: UIRenderingConfig;
1199
+ performance?: PerformanceRenderingConfig;
1200
+ }
1201
+
1202
+ /**
1203
+ * Check if a path type requires JavaScript animation (vs CSS transitions)
1204
+ */
1205
+ export declare function requiresJSAnimation(pathType: EntryPathType): boolean;
1206
+
1207
+ /**
1208
+ * Responsive breakpoints configuration for layout
1209
+ * Defines viewport width thresholds for mobile and tablet
1210
+ */
1211
+ declare interface ResponsiveBreakpoints {
1212
+ mobile: {
1213
+ maxWidth: number;
1214
+ };
1215
+ tablet: {
1216
+ maxWidth: number;
1217
+ };
1218
+ }
1219
+
1220
+ export declare interface ResponsiveHeight {
1221
+ minWidth: number;
1222
+ height: number;
1223
+ }
1224
+
1225
+ export declare interface ResponsiveRenderingConfig {
1226
+ breakpoints: {
1227
+ mobile: number;
1228
+ tablet?: number;
1229
+ desktop?: number;
1230
+ };
1231
+ mobileDetection: () => boolean;
1232
+ }
1233
+
1234
+ declare type ShadowPreset = 'none' | 'sm' | 'md' | 'lg' | 'glow';
1235
+
1236
+ export declare interface SharedLoaderConfig {
1237
+ validateUrls?: boolean;
1238
+ validationTimeout?: number;
1239
+ validationMethod?: 'head' | 'simple' | 'none';
1240
+ allowedExtensions?: string[];
1241
+ }
1242
+
1243
+ /**
1244
+ * Sizing mode:
1245
+ * - 'fixed': single explicit height for all breakpoints
1246
+ * - 'responsive': different heights per breakpoint (mobile/tablet/screen)
1247
+ * - 'adaptive': auto-calculates based on container size and image count
1248
+ */
1249
+ declare type SizingMode = 'fixed' | 'responsive' | 'adaptive';
1250
+
1251
+ export declare interface SpiralAlgorithmConfig {
1252
+ spiralType: 'golden' | 'archimedean' | 'logarithmic';
1253
+ direction: 'clockwise' | 'counterclockwise';
1254
+ tightness: number;
1255
+ scaleDecay: number;
1256
+ startAngle: number;
1257
+ }
1258
+
1259
+ declare interface SpiralLayoutOptions extends Partial<LayoutConfig> {
1260
+ fixedHeight?: number;
1261
+ }
1262
+
1263
+ export declare class SpiralPlacementLayout implements PlacementLayout {
1264
+ private config;
1265
+ private imageConfig;
1266
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1267
+ /**
1268
+ * Generate spiral layout positions for images
1269
+ * @param imageCount - Number of images to layout
1270
+ * @param containerBounds - Container dimensions {width, height}
1271
+ * @param options - Optional overrides (includes fixedHeight)
1272
+ * @returns Array of layout objects with position, rotation, scale
1273
+ */
1274
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: SpiralLayoutOptions): ImageLayout[];
1275
+ /**
1276
+ * Calculate tangent angle for spiral curve at given position
1277
+ * This aligns the image along the spiral's direction of travel
1278
+ */
1279
+ private calculateSpiralTangent;
1280
+ /**
1281
+ * Calculate radius for golden spiral (Vogel's model)
1282
+ * Creates even distribution like sunflower seeds
1283
+ */
1284
+ private calculateGoldenRadius;
1285
+ /**
1286
+ * Calculate radius for Archimedean spiral
1287
+ * r = a + b*θ (constant spacing between arms)
1288
+ */
1289
+ private calculateArchimedeanRadius;
1290
+ /**
1291
+ * Calculate radius for logarithmic (equiangular) spiral
1292
+ * r = a * e^(b*θ)
1293
+ */
1294
+ private calculateLogarithmicRadius;
1295
+ /**
1296
+ * Utility: Generate random number between min and max
1297
+ */
1298
+ private random;
1299
+ }
1300
+
1301
+ declare interface StartPosition {
1302
+ x: number;
1303
+ y: number;
1304
+ useScale?: boolean;
1305
+ }
1306
+
1307
+ export declare class StaticImageLoader implements ImageLoader {
1308
+ private validateUrls;
1309
+ private validationTimeout;
1310
+ private validationMethod;
1311
+ private sources;
1312
+ private debugLogging;
1313
+ private _prepared;
1314
+ private _discoveredUrls;
1315
+ constructor(config: StaticLoaderInnerConfig);
1316
+ /**
1317
+ * Prepare the loader by discovering all images from configured sources
1318
+ * @param filter - Filter to apply to discovered images
1319
+ */
1320
+ prepare(filter: IImageFilter): Promise<void>;
1321
+ /**
1322
+ * Get the number of discovered images
1323
+ * @throws Error if called before prepare()
1324
+ */
1325
+ imagesLength(): number;
1326
+ /**
1327
+ * Get the ordered list of image URLs
1328
+ * @throws Error if called before prepare()
1329
+ */
1330
+ imageURLs(): string[];
1331
+ /**
1332
+ * Check if the loader has been prepared
1333
+ */
1334
+ isPrepared(): boolean;
1335
+ /**
1336
+ * Process a single source object using shape-based detection
1337
+ * @param source - Source configuration detected by key presence
1338
+ * @param filter - Filter to apply to discovered images
1339
+ * @returns Promise resolving to array of valid URLs from this source
1340
+ */
1341
+ private processSource;
1342
+ /**
1343
+ * Process a list of direct URLs
1344
+ * @param urls - Array of image URLs
1345
+ * @param filter - Filter to apply to discovered images
1346
+ * @returns Promise resolving to array of validated URLs
1347
+ */
1348
+ private processUrls;
1349
+ /**
1350
+ * Process a path-based source
1351
+ * @param basePath - Base path (relative or absolute)
1352
+ * @param files - Array of filenames
1353
+ * @param filter - Filter to apply to discovered images
1354
+ * @returns Promise resolving to array of validated URLs
1355
+ */
1356
+ private processPath;
1357
+ /**
1358
+ * Process a JSON endpoint source
1359
+ * Fetches a JSON endpoint that returns { images: string[] }
1360
+ * @param url - JSON endpoint URL
1361
+ * @param filter - Filter to apply to discovered images
1362
+ * @returns Promise resolving to array of validated URLs
1363
+ */
1364
+ private processJson;
1365
+ /**
1366
+ * Validate a single URL using HEAD request
1367
+ * @param url - URL to validate
1368
+ * @returns Promise resolving to true if valid and accessible
1369
+ */
1370
+ private validateUrl;
1371
+ /**
1372
+ * Construct full URL from basePath and filename
1373
+ * @param basePath - Base path (relative or absolute)
1374
+ * @param filename - Filename to append
1375
+ * @returns Complete URL
1376
+ */
1377
+ private constructUrl;
1378
+ /**
1379
+ * Check if URL is absolute (contains protocol)
1380
+ * @param url - URL to check
1381
+ * @returns True if absolute URL
1382
+ */
1383
+ private isAbsoluteUrl;
1384
+ /**
1385
+ * Debug logging helper
1386
+ * @param args - Arguments to log
1387
+ */
1388
+ private log;
1389
+ }
1390
+
1391
+ export declare interface StaticJsonSource {
1392
+ json: string;
1393
+ }
1394
+
1395
+ export declare interface StaticLoaderEntry {
1396
+ static: StaticLoaderInnerConfig;
1397
+ }
1398
+
1399
+ export declare interface StaticLoaderInnerConfig {
1400
+ sources: StaticSource[];
1401
+ validateUrls?: boolean;
1402
+ validationTimeout?: number;
1403
+ validationMethod?: 'head' | 'simple' | 'none';
1404
+ allowedExtensions?: string[];
1405
+ debugLogging?: boolean;
1406
+ }
1407
+
1408
+ export declare interface StaticPathSource {
1409
+ path: string;
1410
+ files: string[];
1411
+ }
1412
+
1413
+ export declare type StaticSource = StaticUrlsSource | StaticPathSource | StaticJsonSource;
1414
+
1415
+ export declare interface StaticUrlsSource {
1416
+ urls: string[];
1417
+ }
1418
+
1419
+ export declare interface TransformParams {
1420
+ x?: number;
1421
+ y?: number;
1422
+ rotation?: number;
1423
+ scale?: number;
1424
+ }
1425
+
1426
+ export declare interface UIRenderingConfig {
1427
+ showLoadingSpinner: boolean;
1428
+ showImageCounter?: boolean;
1429
+ showThumbnails?: boolean;
1430
+ theme?: 'light' | 'dark' | 'auto';
1431
+ loadingElement?: string | HTMLElement;
1432
+ errorElement?: string | HTMLElement;
1433
+ counterElement?: string | HTMLElement;
1434
+ }
1435
+
1436
+ /**
1437
+ * Wave path presets - sinusoidal path animations
1438
+ */
1439
+ export declare const WAVE_PATH_PRESETS: Record<WavePathPreset, WavePathConfig>;
1440
+
1441
+ declare interface WaveAlgorithmConfig {
1442
+ rows: number;
1443
+ amplitude: number;
1444
+ frequency: number;
1445
+ phaseShift: number;
1446
+ synchronization: 'offset' | 'synchronized' | 'alternating';
1447
+ }
1448
+
1449
+ declare interface WaveLayoutOptions extends Partial<LayoutConfig> {
1450
+ fixedHeight?: number;
1451
+ }
1452
+
1453
+ export declare interface WavePathConfig {
1454
+ amplitude: number;
1455
+ frequency: number;
1456
+ decay: boolean;
1457
+ decayRate: number;
1458
+ phase: number;
1459
+ }
1460
+
1461
+ export declare type WavePathPreset = 'gentle' | 'playful' | 'serpentine' | 'flutter';
1462
+
1463
+ export declare class WavePlacementLayout implements PlacementLayout {
1464
+ private config;
1465
+ private imageConfig;
1466
+ constructor(config: LayoutConfig, imageConfig?: ImageConfig);
1467
+ /**
1468
+ * Generate wave layout positions for images
1469
+ * @param imageCount - Number of images to layout
1470
+ * @param containerBounds - Container dimensions {width, height}
1471
+ * @param options - Optional overrides
1472
+ * @returns Array of layout objects with position, rotation, scale
1473
+ */
1474
+ generate(imageCount: number, containerBounds: ContainerBounds, options?: WaveLayoutOptions): ImageLayout[];
1475
+ /**
1476
+ * Calculate Y position displacement on wave curve
1477
+ * @param x - Horizontal position
1478
+ * @param containerWidth - Container width
1479
+ * @param amplitude - Wave amplitude
1480
+ * @param frequency - Wave frequency
1481
+ * @param phase - Phase offset
1482
+ * @returns Y displacement from baseline
1483
+ */
1484
+ private calculateWaveY;
1485
+ /**
1486
+ * Calculate rotation based on wave tangent
1487
+ * @param x - Horizontal position
1488
+ * @param containerWidth - Container width
1489
+ * @param amplitude - Wave amplitude
1490
+ * @param frequency - Wave frequency
1491
+ * @param phase - Phase offset
1492
+ * @returns Rotation angle in degrees
1493
+ */
1494
+ private calculateRotation;
1495
+ /**
1496
+ * Estimate image width based on height
1497
+ /**
1498
+ * Utility: Generate random number between min and max
1499
+ * @param min - Minimum value
1500
+ * @param max - Maximum value
1501
+ * @returns Random number in range
1502
+ */
1503
+ private random;
1504
+ }
1505
+
1506
+ export declare class ZoomEngine {
1507
+ private config;
1508
+ private animationEngine;
1509
+ private state;
1510
+ private currentFocus;
1511
+ private focusData;
1512
+ private outgoing;
1513
+ private incoming;
1514
+ private focusGeneration;
1515
+ private defaultStyles;
1516
+ private focusedStyles;
1517
+ private defaultClassName;
1518
+ private focusedClassName;
1519
+ constructor(config: FocusInteractionConfig, animationEngine: AnimationEngine, styling?: ImageStylingConfig);
1520
+ /**
1521
+ * Get current state machine state
1522
+ */
1523
+ getState(): ZoomState;
1524
+ /**
1525
+ * Check if any animation is in progress
1526
+ */
1527
+ isAnimating(): boolean;
1528
+ /**
1529
+ * Normalize scalePercent value
1530
+ */
1531
+ private normalizeScalePercent;
1532
+ /**
1533
+ * Calculate target dimensions for focused image
1534
+ * Returns actual pixel dimensions instead of scale factor for sharper rendering
1535
+ */
1536
+ private calculateFocusDimensions;
1537
+ /**
1538
+ * Calculate the transform needed to center an image (position only, no scale)
1539
+ * Scale is handled by animating actual dimensions for sharper rendering
1540
+ */
1541
+ private calculateFocusTransform;
1542
+ /**
1543
+ * Build transform string for dimension-based zoom (no scale in transform)
1544
+ */
1545
+ private buildDimensionZoomTransform;
1546
+ /**
1547
+ * Create a Web Animation that animates both transform (position) and dimensions
1548
+ * This provides sharper zoom by re-rendering at target size instead of scaling pixels
1549
+ */
1550
+ private animateWithDimensions;
1551
+ /**
1552
+ * Apply focused styling to an element
1553
+ */
1554
+ private applyFocusedStyling;
1555
+ /**
1556
+ * Remove focused styling from an element
1557
+ */
1558
+ private removeFocusedStyling;
1559
+ /**
1560
+ * Start focus animation for an image using dimension-based zoom
1561
+ * Animates actual width/height for sharper rendering instead of transform scale
1562
+ * @param fromTransform - Optional starting transform (for mid-animation reversals)
1563
+ * @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
1564
+ */
1565
+ private startFocusAnimation;
1566
+ /**
1567
+ * Start unfocus animation for an image using dimension-based zoom
1568
+ * Animates back to original dimensions for consistent behavior
1569
+ * @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
1570
+ */
1571
+ private startUnfocusAnimation;
1572
+ /**
1573
+ * Capture the current visual state of an element mid-animation, BEFORE cancelling.
1574
+ *
1575
+ * The computed matrix.e/f include the -50%/-50% centering offset resolved to pixels.
1576
+ * buildDimensionZoomTransform prepends its own translate(-50%,-50%), so passing raw
1577
+ * matrix.e/f doubles the centering and produces the wrong starting position.
1578
+ *
1579
+ * This method extracts the PURE positional offset (pureX = matrix.e + 0.5*midWidth)
1580
+ * and commits width/height/transform to inline styles before the animation is cancelled,
1581
+ * preventing any visual snap.
1582
+ *
1583
+ * Must be called while the animation is still running (offsetWidth reflects animated size).
1584
+ * Caller is responsible for calling animationEngine.cancelAllAnimations() afterwards.
1585
+ */
1586
+ private captureMidAnimationState;
1587
+ /**
1588
+ * Handle animation completion
1589
+ */
1590
+ private waitForAnimation;
1591
+ /**
1592
+ * Reset an element instantly to its original position and dimensions (no animation)
1593
+ */
1594
+ private resetElementInstantly;
1595
+ /**
1596
+ * Focus (zoom) an image to center of container
1597
+ * Implements cross-animation when swapping focus
1598
+ */
1599
+ focusImage(imageElement: HTMLElement, containerBounds: ContainerBounds, originalState: ImageLayout): Promise<void>;
1600
+ /**
1601
+ * Unfocus current image, returning it to original position
1602
+ */
1603
+ unfocusImage(): Promise<void>;
1604
+ /**
1605
+ * Swap focus from current image to a new one (alias for focusImage with cross-animation)
1606
+ */
1607
+ swapFocus(newImageElement: HTMLElement, containerBounds: ContainerBounds, originalState: ImageLayout): Promise<void>;
1608
+ /**
1609
+ * Get currently focused image element
1610
+ */
1611
+ getCurrentFocus(): HTMLElement | null;
1612
+ /**
1613
+ * Check if an image is currently focused (stable state)
1614
+ */
1615
+ isFocused(imageElement: HTMLElement): boolean;
1616
+ /**
1617
+ * Check if an image is the target of current focus animation
1618
+ */
1619
+ isTargetingFocus(imageElement: HTMLElement): boolean;
1620
+ /**
1621
+ * Check if an image is involved in any focus/animation state
1622
+ * Returns true if the image is focused, animating in, or animating out
1623
+ * Useful for hover state management - don't apply hover to animating images
1624
+ */
1625
+ isInvolved(imageElement: HTMLElement): boolean;
1626
+ /**
1627
+ * Apply a temporary horizontal drag offset to the focused image
1628
+ * Used during swipe gestures for visual feedback
1629
+ */
1630
+ setDragOffset(offset: number): void;
1631
+ /**
1632
+ * Clear the drag offset, optionally animating back to center
1633
+ * @param animate - If true, animate back to center; if false, snap instantly
1634
+ * @param duration - Animation duration in ms (default 150)
1635
+ */
1636
+ clearDragOffset(animate: boolean, duration?: number): void;
1637
+ /**
1638
+ * Reset zoom state (cancels all animations)
1639
+ */
1640
+ reset(): void;
1641
+ }
1642
+
1643
+ /**
1644
+ * State machine states for zoom/focus animations
1645
+ */
1646
+ declare enum ZoomState {
1647
+ IDLE = "idle",// No focus, no animations
1648
+ FOCUSING = "focusing",// Single image animating in
1649
+ FOCUSED = "focused",// Stable focused state
1650
+ UNFOCUSING = "unfocusing",// Single image animating out
1651
+ CROSS_ANIMATING = "cross_animating"
1652
+ }
1653
+
1654
+ export { }