@frybynite/image-cloud 0.7.5 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-cloud-auto-init.js +566 -560
- package/dist/image-cloud-auto-init.js.map +1 -1
- package/dist/image-cloud.js +943 -937
- package/dist/image-cloud.js.map +1 -1
- package/dist/image-cloud.umd.js +3 -3
- package/dist/image-cloud.umd.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +928 -922
- package/dist/react.js.map +1 -1
- package/dist/vue.d.ts +2 -2
- package/dist/vue.js +942 -936
- package/dist/vue.js.map +1 -1
- package/dist/web-component.d.ts +2 -2
- package/dist/web-component.js +657 -651
- package/dist/web-component.js.map +1 -1
- package/package.json +1 -1
package/dist/web-component.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const ft = Object.freeze({
|
|
2
2
|
none: "none",
|
|
3
3
|
sm: "0 2px 4px rgba(0,0,0,0.1)",
|
|
4
4
|
md: "0 4px 16px rgba(0,0,0,0.4)",
|
|
@@ -8,23 +8,23 @@ const gt = Object.freeze({
|
|
|
8
8
|
energetic: Object.freeze({ overshoot: 0.25, bounces: 2, decayRatio: 0.5 }),
|
|
9
9
|
playful: Object.freeze({ overshoot: 0.15, bounces: 1, decayRatio: 0.5 }),
|
|
10
10
|
subtle: Object.freeze({ overshoot: 0.08, bounces: 1, decayRatio: 0.5 })
|
|
11
|
-
}),
|
|
11
|
+
}), Rt = Object.freeze({
|
|
12
12
|
gentle: Object.freeze({ stiffness: 150, damping: 30, mass: 1, oscillations: 2 }),
|
|
13
13
|
bouncy: Object.freeze({ stiffness: 300, damping: 15, mass: 1, oscillations: 4 }),
|
|
14
14
|
wobbly: Object.freeze({ stiffness: 180, damping: 12, mass: 1.5, oscillations: 5 }),
|
|
15
15
|
snappy: Object.freeze({ stiffness: 400, damping: 25, mass: 0.8, oscillations: 2 })
|
|
16
|
-
}),
|
|
16
|
+
}), It = Object.freeze({
|
|
17
17
|
gentle: Object.freeze({ amplitude: 30, frequency: 1.5, decay: !0, decayRate: 0.9, phase: 0 }),
|
|
18
18
|
playful: Object.freeze({ amplitude: 50, frequency: 2.5, decay: !0, decayRate: 0.7, phase: 0 }),
|
|
19
19
|
serpentine: Object.freeze({ amplitude: 60, frequency: 3, decay: !1, decayRate: 1, phase: 0 }),
|
|
20
20
|
flutter: Object.freeze({ amplitude: 20, frequency: 4, decay: !0, decayRate: 0.5, phase: 0 })
|
|
21
|
-
}), bt = Object.freeze({
|
|
22
|
-
type: "linear"
|
|
23
21
|
}), yt = Object.freeze({
|
|
24
|
-
|
|
22
|
+
type: "linear"
|
|
25
23
|
}), vt = Object.freeze({
|
|
26
24
|
mode: "none"
|
|
27
|
-
}),
|
|
25
|
+
}), wt = Object.freeze({
|
|
26
|
+
mode: "none"
|
|
27
|
+
}), Lt = Object.freeze({
|
|
28
28
|
default: Object.freeze({
|
|
29
29
|
border: Object.freeze({
|
|
30
30
|
width: 0,
|
|
@@ -78,15 +78,15 @@ const gt = Object.freeze({
|
|
|
78
78
|
min: -15,
|
|
79
79
|
max: 15
|
|
80
80
|
})
|
|
81
|
-
}),
|
|
81
|
+
}), Mt = Object.freeze({
|
|
82
82
|
sizing: Ut,
|
|
83
83
|
rotation: Ht
|
|
84
|
-
}),
|
|
84
|
+
}), Ft = Object.freeze({
|
|
85
85
|
validateUrls: !0,
|
|
86
86
|
validationTimeout: 5e3,
|
|
87
87
|
validationMethod: "head",
|
|
88
88
|
allowedExtensions: ["jpg", "jpeg", "png", "gif", "webp", "bmp"]
|
|
89
|
-
}),
|
|
89
|
+
}), zt = Object.freeze({
|
|
90
90
|
enabled: !1,
|
|
91
91
|
centers: !1,
|
|
92
92
|
loaders: !1
|
|
@@ -95,11 +95,11 @@ const gt = Object.freeze({
|
|
|
95
95
|
loaders: [],
|
|
96
96
|
// Shared loader settings and debug config
|
|
97
97
|
config: Object.freeze({
|
|
98
|
-
loaders:
|
|
99
|
-
debug:
|
|
98
|
+
loaders: Ft,
|
|
99
|
+
debug: zt
|
|
100
100
|
}),
|
|
101
101
|
// Image sizing and rotation configuration
|
|
102
|
-
image:
|
|
102
|
+
image: Mt,
|
|
103
103
|
// Pattern-based layout configuration
|
|
104
104
|
layout: Object.freeze({
|
|
105
105
|
algorithm: "radial",
|
|
@@ -161,9 +161,9 @@ const gt = Object.freeze({
|
|
|
161
161
|
}),
|
|
162
162
|
easing: "cubic-bezier(0.25, 1, 0.5, 1)",
|
|
163
163
|
// smooth deceleration
|
|
164
|
-
path:
|
|
165
|
-
rotation:
|
|
166
|
-
scale:
|
|
164
|
+
path: yt,
|
|
165
|
+
rotation: vt,
|
|
166
|
+
scale: wt
|
|
167
167
|
})
|
|
168
168
|
}),
|
|
169
169
|
// Pattern-based interaction configuration
|
|
@@ -216,47 +216,47 @@ const gt = Object.freeze({
|
|
|
216
216
|
})
|
|
217
217
|
}),
|
|
218
218
|
// Image styling
|
|
219
|
-
styling:
|
|
219
|
+
styling: Lt
|
|
220
220
|
});
|
|
221
221
|
function Z(n, t) {
|
|
222
222
|
if (!n) return t || {};
|
|
223
223
|
if (!t) return { ...n };
|
|
224
|
-
const
|
|
225
|
-
return t.border !== void 0 && (
|
|
224
|
+
const i = { ...n };
|
|
225
|
+
return t.border !== void 0 && (i.border = { ...n.border, ...t.border }), t.borderTop !== void 0 && (i.borderTop = { ...n.borderTop, ...t.borderTop }), t.borderRight !== void 0 && (i.borderRight = { ...n.borderRight, ...t.borderRight }), t.borderBottom !== void 0 && (i.borderBottom = { ...n.borderBottom, ...t.borderBottom }), t.borderLeft !== void 0 && (i.borderLeft = { ...n.borderLeft, ...t.borderLeft }), t.filter !== void 0 && (i.filter = { ...n.filter, ...t.filter }), t.outline !== void 0 && (i.outline = { ...n.outline, ...t.outline }), t.shadow !== void 0 && (i.shadow = t.shadow), t.clipPath !== void 0 && (i.clipPath = t.clipPath), t.opacity !== void 0 && (i.opacity = t.opacity), t.cursor !== void 0 && (i.cursor = t.cursor), t.className !== void 0 && (i.className = t.className), t.objectFit !== void 0 && (i.objectFit = t.objectFit), t.aspectRatio !== void 0 && (i.aspectRatio = t.aspectRatio), t.borderRadiusTopLeft !== void 0 && (i.borderRadiusTopLeft = t.borderRadiusTopLeft), t.borderRadiusTopRight !== void 0 && (i.borderRadiusTopRight = t.borderRadiusTopRight), t.borderRadiusBottomRight !== void 0 && (i.borderRadiusBottomRight = t.borderRadiusBottomRight), t.borderRadiusBottomLeft !== void 0 && (i.borderRadiusBottomLeft = t.borderRadiusBottomLeft), i;
|
|
226
226
|
}
|
|
227
227
|
function Nt(n, t) {
|
|
228
228
|
if (!t) return { ...n };
|
|
229
|
-
const
|
|
230
|
-
Z(
|
|
229
|
+
const i = Z(n.default, t.default), e = Z(
|
|
230
|
+
Z(i, n.hover),
|
|
231
231
|
t.hover
|
|
232
232
|
), o = Z(
|
|
233
|
-
Z(
|
|
233
|
+
Z(i, n.focused),
|
|
234
234
|
t.focused
|
|
235
235
|
);
|
|
236
236
|
return {
|
|
237
|
-
default:
|
|
238
|
-
hover:
|
|
237
|
+
default: i,
|
|
238
|
+
hover: e,
|
|
239
239
|
focused: o
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
242
|
function jt(n, t) {
|
|
243
243
|
if (!t) return { ...n };
|
|
244
|
-
const
|
|
245
|
-
if (t.sizing !== void 0 && (
|
|
244
|
+
const i = { ...n };
|
|
245
|
+
if (t.sizing !== void 0 && (i.sizing = {
|
|
246
246
|
...n.sizing,
|
|
247
247
|
...t.sizing
|
|
248
248
|
}, t.sizing.variance)) {
|
|
249
|
-
const
|
|
250
|
-
|
|
249
|
+
const e = t.sizing.variance, o = e.min !== void 0 && e.min >= 0.25 && e.min <= 1 ? e.min : n.sizing?.variance?.min ?? 1, a = e.max !== void 0 && e.max >= 1 && e.max <= 1.75 ? e.max : n.sizing?.variance?.max ?? 1;
|
|
250
|
+
i.sizing.variance = { min: o, max: a };
|
|
251
251
|
}
|
|
252
|
-
if (t.rotation !== void 0 && (
|
|
252
|
+
if (t.rotation !== void 0 && (i.rotation = {
|
|
253
253
|
...n.rotation,
|
|
254
254
|
...t.rotation
|
|
255
255
|
}, t.rotation.range)) {
|
|
256
|
-
const
|
|
257
|
-
|
|
256
|
+
const e = t.rotation.range, o = e.min !== void 0 && e.min >= -180 && e.min <= 0 ? e.min : n.rotation?.range?.min ?? -15, a = e.max !== void 0 && e.max >= 0 && e.max <= 180 ? e.max : n.rotation?.range?.max ?? 15;
|
|
257
|
+
i.rotation.range = { min: o, max: a };
|
|
258
258
|
}
|
|
259
|
-
return
|
|
259
|
+
return i;
|
|
260
260
|
}
|
|
261
261
|
function kt(n) {
|
|
262
262
|
const t = n.layout?.rotation;
|
|
@@ -280,13 +280,13 @@ function Wt(n) {
|
|
|
280
280
|
};
|
|
281
281
|
}
|
|
282
282
|
function Gt(n = {}) {
|
|
283
|
-
const t = kt(n),
|
|
284
|
-
let
|
|
285
|
-
(t ||
|
|
286
|
-
...
|
|
283
|
+
const t = kt(n), i = Wt(n);
|
|
284
|
+
let e = n.image;
|
|
285
|
+
(t || i) && (e = {
|
|
286
|
+
...i || {},
|
|
287
287
|
...t || {},
|
|
288
|
-
...
|
|
289
|
-
},
|
|
288
|
+
...e
|
|
289
|
+
}, e.rotation && t?.rotation && n.image?.rotation && (e.rotation = {
|
|
290
290
|
...t.rotation,
|
|
291
291
|
...n.image.rotation
|
|
292
292
|
}));
|
|
@@ -298,18 +298,18 @@ function Gt(n = {}) {
|
|
|
298
298
|
});
|
|
299
299
|
const r = {
|
|
300
300
|
loaders: {
|
|
301
|
-
...
|
|
301
|
+
...Ft,
|
|
302
302
|
...n.config?.loaders ?? {}
|
|
303
303
|
}
|
|
304
304
|
}, s = {
|
|
305
305
|
loaders: o,
|
|
306
306
|
config: r,
|
|
307
|
-
image: jt(
|
|
307
|
+
image: jt(Mt, e),
|
|
308
308
|
layout: { ...y.layout },
|
|
309
309
|
animation: { ...y.animation },
|
|
310
310
|
interaction: { ...y.interaction },
|
|
311
311
|
rendering: { ...y.rendering },
|
|
312
|
-
styling: Nt(
|
|
312
|
+
styling: Nt(Lt, n.styling)
|
|
313
313
|
};
|
|
314
314
|
return n.layout && (s.layout = {
|
|
315
315
|
...y.layout,
|
|
@@ -342,9 +342,9 @@ function Gt(n = {}) {
|
|
|
342
342
|
circular: n.animation.entry.start.circular ? { ...y.animation.entry.start.circular, ...n.animation.entry.start.circular } : y.animation.entry.start.circular
|
|
343
343
|
} : y.animation.entry.start,
|
|
344
344
|
timing: n.animation.entry.timing ? { ...y.animation.entry.timing, ...n.animation.entry.timing } : y.animation.entry.timing,
|
|
345
|
-
path: n.animation.entry.path ? { ...
|
|
346
|
-
rotation: n.animation.entry.rotation ? { ...
|
|
347
|
-
scale: n.animation.entry.scale ? { ...
|
|
345
|
+
path: n.animation.entry.path ? { ...yt, ...n.animation.entry.path } : y.animation.entry.path,
|
|
346
|
+
rotation: n.animation.entry.rotation ? { ...vt, ...n.animation.entry.rotation } : y.animation.entry.rotation,
|
|
347
|
+
scale: n.animation.entry.scale ? { ...wt, ...n.animation.entry.scale } : y.animation.entry.scale
|
|
348
348
|
})), n.interaction && (s.interaction = {
|
|
349
349
|
...y.interaction,
|
|
350
350
|
...n.interaction
|
|
@@ -372,20 +372,20 @@ function Gt(n = {}) {
|
|
|
372
372
|
...y.rendering.performance,
|
|
373
373
|
...n.rendering.performance
|
|
374
374
|
})), s.config.debug = {
|
|
375
|
-
...
|
|
375
|
+
...zt,
|
|
376
376
|
...n.config?.debug ?? {}
|
|
377
377
|
}, s;
|
|
378
378
|
}
|
|
379
379
|
function qt(n, t) {
|
|
380
380
|
return { ...n ? St[n] : St.playful, ...t };
|
|
381
381
|
}
|
|
382
|
+
function Bt(n, t) {
|
|
383
|
+
return { ...n ? Rt[n] : Rt.gentle, ...t };
|
|
384
|
+
}
|
|
382
385
|
function Yt(n, t) {
|
|
383
386
|
return { ...n ? It[n] : It.gentle, ...t };
|
|
384
387
|
}
|
|
385
|
-
|
|
386
|
-
return { ...n ? At[n] : At.gentle, ...t };
|
|
387
|
-
}
|
|
388
|
-
class Bt {
|
|
388
|
+
class Xt {
|
|
389
389
|
constructor(t) {
|
|
390
390
|
this.activeAnimations = /* @__PURE__ */ new Map(), this.animationIdCounter = 0, this.config = t;
|
|
391
391
|
}
|
|
@@ -394,12 +394,12 @@ class Bt {
|
|
|
394
394
|
* Always starts with centering transform to match image positioning system
|
|
395
395
|
*/
|
|
396
396
|
buildTransformString(t) {
|
|
397
|
-
const
|
|
397
|
+
const i = ["translate(-50%, -50%)"];
|
|
398
398
|
if (t.x !== void 0 || t.y !== void 0) {
|
|
399
|
-
const
|
|
400
|
-
|
|
399
|
+
const e = t.x ?? 0, o = t.y ?? 0;
|
|
400
|
+
i.push(`translate(${e}px, ${o}px)`);
|
|
401
401
|
}
|
|
402
|
-
return t.rotation !== void 0 &&
|
|
402
|
+
return t.rotation !== void 0 && i.push(`rotate(${t.rotation}deg)`), t.scale !== void 0 && i.push(`scale(${t.scale})`), i.join(" ");
|
|
403
403
|
}
|
|
404
404
|
/**
|
|
405
405
|
* Start a cancellable transform animation using Web Animations API
|
|
@@ -410,9 +410,9 @@ class Bt {
|
|
|
410
410
|
* @param easing - CSS easing function (optional)
|
|
411
411
|
* @returns AnimationHandle that can be used to cancel or query the animation
|
|
412
412
|
*/
|
|
413
|
-
animateTransformCancellable(t,
|
|
413
|
+
animateTransformCancellable(t, i, e, o = null, a = null) {
|
|
414
414
|
this.cancelAllAnimations(t);
|
|
415
|
-
const r = o ?? this.config.duration, s = a ?? this.config.easing.default, h = this.buildTransformString(
|
|
415
|
+
const r = o ?? this.config.duration, s = a ?? this.config.easing.default, h = this.buildTransformString(i), c = this.buildTransformString(e);
|
|
416
416
|
t.style.transition = "none";
|
|
417
417
|
const d = t.animate(
|
|
418
418
|
[
|
|
@@ -429,8 +429,8 @@ class Bt {
|
|
|
429
429
|
id: `anim-${++this.animationIdCounter}`,
|
|
430
430
|
element: t,
|
|
431
431
|
animation: d,
|
|
432
|
-
fromState:
|
|
433
|
-
toState:
|
|
432
|
+
fromState: i,
|
|
433
|
+
toState: e,
|
|
434
434
|
startTime: performance.now(),
|
|
435
435
|
duration: r
|
|
436
436
|
};
|
|
@@ -446,18 +446,18 @@ class Bt {
|
|
|
446
446
|
* @param commitStyle - If true, keeps current position; if false, no style change
|
|
447
447
|
* @returns Snapshot of where the animation was when cancelled
|
|
448
448
|
*/
|
|
449
|
-
cancelAnimation(t,
|
|
450
|
-
const
|
|
451
|
-
if (t.animation.cancel(),
|
|
449
|
+
cancelAnimation(t, i = !0) {
|
|
450
|
+
const e = this.getCurrentTransform(t.element);
|
|
451
|
+
if (t.animation.cancel(), i) {
|
|
452
452
|
const o = this.buildTransformString({
|
|
453
|
-
x:
|
|
454
|
-
y:
|
|
455
|
-
rotation:
|
|
456
|
-
scale:
|
|
453
|
+
x: e.x,
|
|
454
|
+
y: e.y,
|
|
455
|
+
rotation: e.rotation,
|
|
456
|
+
scale: e.scale
|
|
457
457
|
});
|
|
458
458
|
t.element.style.transform = o;
|
|
459
459
|
}
|
|
460
|
-
return this.activeAnimations.delete(t.element),
|
|
460
|
+
return this.activeAnimations.delete(t.element), e;
|
|
461
461
|
}
|
|
462
462
|
/**
|
|
463
463
|
* Cancel all animations on an element
|
|
@@ -465,10 +465,10 @@ class Bt {
|
|
|
465
465
|
* @param element - The element to cancel animations for
|
|
466
466
|
*/
|
|
467
467
|
cancelAllAnimations(t) {
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
const
|
|
471
|
-
for (const o of
|
|
468
|
+
const i = this.activeAnimations.get(t);
|
|
469
|
+
i && this.cancelAnimation(i, !1);
|
|
470
|
+
const e = t.getAnimations();
|
|
471
|
+
for (const o of e)
|
|
472
472
|
o.cancel();
|
|
473
473
|
}
|
|
474
474
|
/**
|
|
@@ -478,10 +478,10 @@ class Bt {
|
|
|
478
478
|
* @returns Current transform snapshot
|
|
479
479
|
*/
|
|
480
480
|
getCurrentTransform(t) {
|
|
481
|
-
const
|
|
482
|
-
if (
|
|
481
|
+
const e = getComputedStyle(t).transform;
|
|
482
|
+
if (e === "none" || !e)
|
|
483
483
|
return { x: 0, y: 0, rotation: 0, scale: 1 };
|
|
484
|
-
const o = new DOMMatrix(
|
|
484
|
+
const o = new DOMMatrix(e), a = Math.sqrt(o.a * o.a + o.b * o.b), r = Math.atan2(o.b, o.a) * (180 / Math.PI), s = o.e, h = o.f;
|
|
485
485
|
return { x: s, y: h, rotation: r, scale: a };
|
|
486
486
|
}
|
|
487
487
|
/**
|
|
@@ -508,10 +508,10 @@ class Bt {
|
|
|
508
508
|
* @param easing - CSS easing function (optional)
|
|
509
509
|
* @returns Promise that resolves when animation completes
|
|
510
510
|
*/
|
|
511
|
-
animateTransform(t,
|
|
511
|
+
animateTransform(t, i, e = null, o = null) {
|
|
512
512
|
return new Promise((a) => {
|
|
513
|
-
const r =
|
|
514
|
-
t.style.transition = `transform ${r}ms ${s}, box-shadow ${r}ms ${s}`, t.style.transform = this.buildTransformString(
|
|
513
|
+
const r = e ?? this.config.duration, s = o ?? this.config.easing.default;
|
|
514
|
+
t.style.transition = `transform ${r}ms ${s}, box-shadow ${r}ms ${s}`, t.style.transform = this.buildTransformString(i), setTimeout(() => {
|
|
515
515
|
a();
|
|
516
516
|
}, r);
|
|
517
517
|
});
|
|
@@ -522,8 +522,8 @@ class Bt {
|
|
|
522
522
|
* @param originalState - Original transform state {x, y, rotation, scale}
|
|
523
523
|
* @returns Promise that resolves when animation completes
|
|
524
524
|
*/
|
|
525
|
-
resetTransform(t,
|
|
526
|
-
return this.animateTransform(t,
|
|
525
|
+
resetTransform(t, i) {
|
|
526
|
+
return this.animateTransform(t, i);
|
|
527
527
|
}
|
|
528
528
|
/**
|
|
529
529
|
* Remove transition styles from element
|
|
@@ -538,14 +538,14 @@ class Bt {
|
|
|
538
538
|
* @returns Promise that resolves after the specified duration
|
|
539
539
|
*/
|
|
540
540
|
wait(t) {
|
|
541
|
-
return new Promise((
|
|
541
|
+
return new Promise((i) => setTimeout(i, t));
|
|
542
542
|
}
|
|
543
543
|
}
|
|
544
|
-
function V(n, t,
|
|
545
|
-
return n + (t - n) *
|
|
544
|
+
function V(n, t, i) {
|
|
545
|
+
return n + (t - n) * i;
|
|
546
546
|
}
|
|
547
|
-
function Jt(n, t,
|
|
548
|
-
const { overshoot: o, bounces: a, decayRatio: r } =
|
|
547
|
+
function Jt(n, t, i, e) {
|
|
548
|
+
const { overshoot: o, bounces: a, decayRatio: r } = e, s = i.x - t.x, h = i.y - t.y, c = Vt(a, r);
|
|
549
549
|
let d = 0, l = 0, u = 1, g = o, p = !1;
|
|
550
550
|
for (let f = 0; f < c.length; f++)
|
|
551
551
|
if (n <= c[f].time) {
|
|
@@ -554,14 +554,14 @@ function Jt(n, t, e, i) {
|
|
|
554
554
|
}
|
|
555
555
|
const b = (n - l) / (u - l);
|
|
556
556
|
if (p)
|
|
557
|
-
d = 1 + g *
|
|
557
|
+
d = 1 + g * nt(b);
|
|
558
558
|
else if (l === 0)
|
|
559
|
-
d =
|
|
559
|
+
d = nt(b);
|
|
560
560
|
else {
|
|
561
561
|
const m = 1 + (c.find(
|
|
562
562
|
(E, v) => E.time > l && v > 0 && c[v - 1].isOvershoot
|
|
563
563
|
)?.overshoot || g);
|
|
564
|
-
d = V(m, 1,
|
|
564
|
+
d = V(m, 1, nt(b));
|
|
565
565
|
}
|
|
566
566
|
return {
|
|
567
567
|
x: t.x + s * d,
|
|
@@ -569,17 +569,17 @@ function Jt(n, t, e, i) {
|
|
|
569
569
|
};
|
|
570
570
|
}
|
|
571
571
|
function Vt(n, t) {
|
|
572
|
-
const
|
|
573
|
-
let
|
|
574
|
-
|
|
572
|
+
const i = [];
|
|
573
|
+
let e = 0.6;
|
|
574
|
+
i.push({ time: e, overshoot: 0, isOvershoot: !1 });
|
|
575
575
|
let o = 0.15;
|
|
576
576
|
const r = 0.4 / (n * 2);
|
|
577
577
|
for (let s = 0; s < n; s++)
|
|
578
|
-
|
|
579
|
-
return
|
|
578
|
+
e += r, i.push({ time: e, overshoot: o, isOvershoot: !0 }), e += r, i.push({ time: e, overshoot: o * t, isOvershoot: !1 }), o *= t;
|
|
579
|
+
return i.push({ time: 1, overshoot: 0, isOvershoot: !1 }), i;
|
|
580
580
|
}
|
|
581
|
-
function Kt(n, t,
|
|
582
|
-
const { stiffness: o, damping: a, mass: r, oscillations: s } =
|
|
581
|
+
function Kt(n, t, i, e) {
|
|
582
|
+
const { stiffness: o, damping: a, mass: r, oscillations: s } = e, h = i.x - t.x, c = i.y - t.y, d = Math.sqrt(o / r), l = a / (2 * Math.sqrt(o * r));
|
|
583
583
|
let u;
|
|
584
584
|
if (l < 1) {
|
|
585
585
|
const g = d * Math.sqrt(1 - l * l), p = Math.exp(-l * d * n * 3), b = Math.cos(g * n * s * Math.PI);
|
|
@@ -591,27 +591,27 @@ function Kt(n, t, e, i) {
|
|
|
591
591
|
y: t.y + c * u
|
|
592
592
|
};
|
|
593
593
|
}
|
|
594
|
-
function Zt(n, t,
|
|
595
|
-
const { amplitude: o, frequency: a, decay: r, decayRate: s, phase: h } =
|
|
594
|
+
function Zt(n, t, i, e) {
|
|
595
|
+
const { amplitude: o, frequency: a, decay: r, decayRate: s, phase: h } = e, c = i.x - t.x, d = i.y - t.y, l = Math.sqrt(c * c + d * d), u = l > 0 ? -d / l : 0, g = l > 0 ? c / l : 1, p = a * Math.PI * 2 * n + h, b = r ? Math.pow(1 - n, s) : 1, f = o * Math.sin(p) * b, m = Qt(n);
|
|
596
596
|
return {
|
|
597
|
-
x: V(t.x,
|
|
598
|
-
y: V(t.y,
|
|
597
|
+
x: V(t.x, i.x, m) + f * u,
|
|
598
|
+
y: V(t.y, i.y, m) + f * g
|
|
599
599
|
};
|
|
600
600
|
}
|
|
601
|
-
function
|
|
601
|
+
function nt(n) {
|
|
602
602
|
return 1 - (1 - n) * (1 - n);
|
|
603
603
|
}
|
|
604
604
|
function Qt(n) {
|
|
605
605
|
return 1 - Math.pow(1 - n, 3);
|
|
606
606
|
}
|
|
607
|
-
function te(n, t,
|
|
608
|
-
const { amplitude:
|
|
607
|
+
function te(n, t, i) {
|
|
608
|
+
const { amplitude: e, frequency: o, decay: a } = i, r = Math.sin(n * o * Math.PI * 2), s = a ? Math.pow(1 - n, 2) : 1, h = e * r * s;
|
|
609
609
|
return t + h;
|
|
610
610
|
}
|
|
611
|
-
function ee(n, t,
|
|
612
|
-
const { overshoot:
|
|
613
|
-
a.push({ time: 0.5, scale:
|
|
614
|
-
let r =
|
|
611
|
+
function ee(n, t, i) {
|
|
612
|
+
const { overshoot: e, bounces: o } = i, a = [];
|
|
613
|
+
a.push({ time: 0.5, scale: e });
|
|
614
|
+
let r = e;
|
|
615
615
|
const s = 0.5, c = 0.5 / (o * 2);
|
|
616
616
|
let d = 0.5;
|
|
617
617
|
for (let u = 0; u < o; u++) {
|
|
@@ -622,7 +622,7 @@ function ee(n, t, e) {
|
|
|
622
622
|
let l = 1;
|
|
623
623
|
for (let u = 0; u < a.length; u++)
|
|
624
624
|
if (n <= a[u].time) {
|
|
625
|
-
const g = u === 0 ? 0 : a[u - 1].time, p = u === 0 ? 1 : a[u - 1].scale, b = (n - g) / (a[u].time - g), f =
|
|
625
|
+
const g = u === 0 ? 0 : a[u - 1].time, p = u === 0 ? 1 : a[u - 1].scale, b = (n - g) / (a[u].time - g), f = nt(b);
|
|
626
626
|
l = p + (a[u].scale - p) * f;
|
|
627
627
|
break;
|
|
628
628
|
}
|
|
@@ -631,8 +631,8 @@ function ee(n, t, e) {
|
|
|
631
631
|
function ie(n) {
|
|
632
632
|
const {
|
|
633
633
|
element: t,
|
|
634
|
-
startPosition:
|
|
635
|
-
endPosition:
|
|
634
|
+
startPosition: i,
|
|
635
|
+
endPosition: e,
|
|
636
636
|
pathConfig: o,
|
|
637
637
|
duration: a,
|
|
638
638
|
imageWidth: r,
|
|
@@ -649,9 +649,9 @@ function ie(n) {
|
|
|
649
649
|
d && d();
|
|
650
650
|
return;
|
|
651
651
|
}
|
|
652
|
-
const
|
|
653
|
-
function U(
|
|
654
|
-
const N =
|
|
652
|
+
const M = performance.now(), F = -r / 2, _ = -s / 2;
|
|
653
|
+
function U(B) {
|
|
654
|
+
const N = B - M, T = Math.min(N / a, 1);
|
|
655
655
|
let O;
|
|
656
656
|
switch (b) {
|
|
657
657
|
case "bounce": {
|
|
@@ -659,36 +659,36 @@ function ie(n) {
|
|
|
659
659
|
o.bouncePreset,
|
|
660
660
|
o.bounce
|
|
661
661
|
);
|
|
662
|
-
O = Jt(
|
|
662
|
+
O = Jt(T, i, e, $);
|
|
663
663
|
break;
|
|
664
664
|
}
|
|
665
665
|
case "elastic": {
|
|
666
|
-
const $ =
|
|
666
|
+
const $ = Bt(
|
|
667
667
|
o.elasticPreset,
|
|
668
668
|
o.elastic
|
|
669
669
|
);
|
|
670
|
-
O = Kt(
|
|
670
|
+
O = Kt(T, i, e, $);
|
|
671
671
|
break;
|
|
672
672
|
}
|
|
673
673
|
case "wave": {
|
|
674
|
-
const $ =
|
|
674
|
+
const $ = Yt(
|
|
675
675
|
o.wavePreset,
|
|
676
676
|
o.wave
|
|
677
677
|
);
|
|
678
|
-
O = Zt(
|
|
678
|
+
O = Zt(T, i, e, $);
|
|
679
679
|
break;
|
|
680
680
|
}
|
|
681
681
|
default:
|
|
682
682
|
O = {
|
|
683
|
-
x: V(
|
|
684
|
-
y: V(
|
|
683
|
+
x: V(i.x, e.x, T),
|
|
684
|
+
y: V(i.y, e.y, T)
|
|
685
685
|
};
|
|
686
686
|
}
|
|
687
|
-
const k = O.x -
|
|
688
|
-
let
|
|
689
|
-
m ?
|
|
690
|
-
let
|
|
691
|
-
S ?
|
|
687
|
+
const k = O.x - e.x, H = O.y - e.y;
|
|
688
|
+
let C;
|
|
689
|
+
m ? C = te(T, h, E) : f ? C = V(u, h, T) : C = h;
|
|
690
|
+
let A;
|
|
691
|
+
S ? A = ee(T, c, x) : w ? A = V(p, c, T) : A = c, t.style.transform = `translate(${F}px, ${_}px) translate(${k}px, ${H}px) rotate(${C}deg) scale(${A})`, T < 1 ? requestAnimationFrame(U) : (t.style.transform = `translate(${F}px, ${_}px) rotate(${h}deg) scale(${c})`, d && d());
|
|
692
692
|
}
|
|
693
693
|
requestAnimationFrame(U);
|
|
694
694
|
}
|
|
@@ -704,8 +704,8 @@ const oe = {
|
|
|
704
704
|
wave: "left"
|
|
705
705
|
};
|
|
706
706
|
class se {
|
|
707
|
-
constructor(t,
|
|
708
|
-
this.config = t, this.layoutAlgorithm =
|
|
707
|
+
constructor(t, i) {
|
|
708
|
+
this.config = t, this.layoutAlgorithm = i, this.resolvedStartPosition = this.resolveStartPosition(), this.pathConfig = t.path || yt, this.rotationConfig = t.rotation || vt, this.scaleConfig = t.scale || wt;
|
|
709
709
|
}
|
|
710
710
|
/**
|
|
711
711
|
* Get the effective start position, considering layout-aware defaults
|
|
@@ -716,57 +716,57 @@ class se {
|
|
|
716
716
|
/**
|
|
717
717
|
* Calculate the starting position for an image's entry animation
|
|
718
718
|
*/
|
|
719
|
-
calculateStartPosition(t,
|
|
719
|
+
calculateStartPosition(t, i, e, o, a) {
|
|
720
720
|
const r = this.resolvedStartPosition, s = this.config.start.offset ?? 100;
|
|
721
721
|
switch (r) {
|
|
722
722
|
case "nearest-edge":
|
|
723
|
-
return this.calculateNearestEdge(t,
|
|
723
|
+
return this.calculateNearestEdge(t, i, e, s);
|
|
724
724
|
case "top":
|
|
725
|
-
return this.calculateEdgePosition("top", t,
|
|
725
|
+
return this.calculateEdgePosition("top", t, i, e, s);
|
|
726
726
|
case "bottom":
|
|
727
|
-
return this.calculateEdgePosition("bottom", t,
|
|
727
|
+
return this.calculateEdgePosition("bottom", t, i, e, s);
|
|
728
728
|
case "left":
|
|
729
|
-
return this.calculateEdgePosition("left", t,
|
|
729
|
+
return this.calculateEdgePosition("left", t, i, e, s);
|
|
730
730
|
case "right":
|
|
731
|
-
return this.calculateEdgePosition("right", t,
|
|
731
|
+
return this.calculateEdgePosition("right", t, i, e, s);
|
|
732
732
|
case "center":
|
|
733
|
-
return this.calculateCenterPosition(
|
|
733
|
+
return this.calculateCenterPosition(e, t, i);
|
|
734
734
|
case "random-edge":
|
|
735
|
-
return this.calculateRandomEdge(t,
|
|
735
|
+
return this.calculateRandomEdge(t, i, e, s);
|
|
736
736
|
case "circular":
|
|
737
737
|
return this.calculateCircularPosition(
|
|
738
738
|
t,
|
|
739
|
-
e,
|
|
740
739
|
i,
|
|
740
|
+
e,
|
|
741
741
|
o,
|
|
742
742
|
a
|
|
743
743
|
);
|
|
744
744
|
default:
|
|
745
|
-
return this.calculateNearestEdge(t,
|
|
745
|
+
return this.calculateNearestEdge(t, i, e, s);
|
|
746
746
|
}
|
|
747
747
|
}
|
|
748
748
|
/**
|
|
749
749
|
* Calculate start position from the nearest edge (current default behavior)
|
|
750
750
|
*/
|
|
751
|
-
calculateNearestEdge(t,
|
|
752
|
-
const a = t.x, r = t.y, s = a, h =
|
|
751
|
+
calculateNearestEdge(t, i, e, o) {
|
|
752
|
+
const a = t.x, r = t.y, s = a, h = e.width - a, c = r, d = e.height - r, l = Math.min(s, h, c, d);
|
|
753
753
|
let u = t.x, g = t.y;
|
|
754
|
-
return l === s ? u = -(
|
|
754
|
+
return l === s ? u = -(i.width + o) : l === h ? u = e.width + o : l === c ? g = -(i.height + o) : g = e.height + o, { x: u, y: g };
|
|
755
755
|
}
|
|
756
756
|
/**
|
|
757
757
|
* Calculate start position from a specific edge
|
|
758
758
|
*/
|
|
759
|
-
calculateEdgePosition(t,
|
|
760
|
-
let r =
|
|
759
|
+
calculateEdgePosition(t, i, e, o, a) {
|
|
760
|
+
let r = i.x, s = i.y;
|
|
761
761
|
switch (t) {
|
|
762
762
|
case "top":
|
|
763
|
-
s = -(
|
|
763
|
+
s = -(e.height + a);
|
|
764
764
|
break;
|
|
765
765
|
case "bottom":
|
|
766
766
|
s = o.height + a;
|
|
767
767
|
break;
|
|
768
768
|
case "left":
|
|
769
|
-
r = -(
|
|
769
|
+
r = -(e.width + a);
|
|
770
770
|
break;
|
|
771
771
|
case "right":
|
|
772
772
|
r = o.width + a;
|
|
@@ -777,7 +777,7 @@ class se {
|
|
|
777
777
|
/**
|
|
778
778
|
* Calculate start position from center with scale animation
|
|
779
779
|
*/
|
|
780
|
-
calculateCenterPosition(t,
|
|
780
|
+
calculateCenterPosition(t, i, e) {
|
|
781
781
|
const o = t.width / 2, a = t.height / 2;
|
|
782
782
|
return {
|
|
783
783
|
x: o,
|
|
@@ -789,68 +789,68 @@ class se {
|
|
|
789
789
|
/**
|
|
790
790
|
* Calculate start position from a random edge
|
|
791
791
|
*/
|
|
792
|
-
calculateRandomEdge(t,
|
|
792
|
+
calculateRandomEdge(t, i, e, o) {
|
|
793
793
|
const a = ["top", "bottom", "left", "right"], r = a[Math.floor(Math.random() * a.length)];
|
|
794
|
-
return this.calculateEdgePosition(r, t,
|
|
794
|
+
return this.calculateEdgePosition(r, t, i, e, o);
|
|
795
795
|
}
|
|
796
796
|
/**
|
|
797
797
|
* Calculate start position on a circle around the container
|
|
798
798
|
*/
|
|
799
|
-
calculateCircularPosition(t,
|
|
799
|
+
calculateCircularPosition(t, i, e, o, a) {
|
|
800
800
|
const r = this.config.start.circular || {}, s = r.distribution || "even";
|
|
801
801
|
let h;
|
|
802
802
|
const c = r.radius || "120%";
|
|
803
803
|
if (typeof c == "string" && c.endsWith("%")) {
|
|
804
804
|
const b = parseFloat(c) / 100;
|
|
805
805
|
h = Math.sqrt(
|
|
806
|
-
|
|
806
|
+
e.width ** 2 + e.height ** 2
|
|
807
807
|
) * b / 2;
|
|
808
808
|
} else
|
|
809
809
|
h = typeof c == "number" ? c : 500;
|
|
810
810
|
let d;
|
|
811
811
|
s === "even" ? d = o / a * 2 * Math.PI : d = Math.random() * 2 * Math.PI;
|
|
812
|
-
const l =
|
|
812
|
+
const l = e.width / 2, u = e.height / 2, g = l + Math.cos(d) * h, p = u + Math.sin(d) * h;
|
|
813
813
|
return { x: g, y: p };
|
|
814
814
|
}
|
|
815
815
|
/**
|
|
816
816
|
* Get animation parameters for an image
|
|
817
817
|
*/
|
|
818
818
|
getAnimationParams(t) {
|
|
819
|
-
const
|
|
819
|
+
const i = this.config.timing.duration, e = this.config.easing;
|
|
820
820
|
return {
|
|
821
821
|
startTransform: "",
|
|
822
822
|
// Will be computed by caller based on start position
|
|
823
|
-
duration:
|
|
823
|
+
duration: i,
|
|
824
824
|
delay: 0,
|
|
825
|
-
easing:
|
|
825
|
+
easing: e
|
|
826
826
|
};
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* Build a CSS transform string for the start position
|
|
830
830
|
* Uses pixel-based centering offset for reliable cross-browser behavior
|
|
831
831
|
*/
|
|
832
|
-
buildStartTransform(t,
|
|
833
|
-
const c = t.x -
|
|
832
|
+
buildStartTransform(t, i, e, o, a, r, s, h) {
|
|
833
|
+
const c = t.x - i.x, d = t.y - i.y, l = s !== void 0 ? s : e, u = h !== void 0 ? h : o, g = a !== void 0 ? -a / 2 : 0, p = r !== void 0 ? -r / 2 : 0, b = a !== void 0 ? `translate(${g}px, ${p}px)` : "translate(-50%, -50%)";
|
|
834
834
|
return t.useScale ? `${b} translate(${c}px, ${d}px) rotate(${l}deg) scale(0)` : `${b} translate(${c}px, ${d}px) rotate(${l}deg) scale(${u})`;
|
|
835
835
|
}
|
|
836
836
|
/**
|
|
837
837
|
* Build the final CSS transform string
|
|
838
838
|
* Uses pixel-based centering offset for reliable cross-browser behavior
|
|
839
839
|
*/
|
|
840
|
-
buildFinalTransform(t,
|
|
841
|
-
if (
|
|
842
|
-
const a = -
|
|
843
|
-
return `translate(${a}px, ${r}px) rotate(${t}deg) scale(${
|
|
840
|
+
buildFinalTransform(t, i, e, o) {
|
|
841
|
+
if (e !== void 0 && o !== void 0) {
|
|
842
|
+
const a = -e / 2, r = -o / 2;
|
|
843
|
+
return `translate(${a}px, ${r}px) rotate(${t}deg) scale(${i})`;
|
|
844
844
|
}
|
|
845
|
-
return `translate(-50%, -50%) rotate(${t}deg) scale(${
|
|
845
|
+
return `translate(-50%, -50%) rotate(${t}deg) scale(${i})`;
|
|
846
846
|
}
|
|
847
847
|
/**
|
|
848
848
|
* Get the transition CSS for entry animation
|
|
849
849
|
* For JS-animated paths, only animate opacity (transform handled by JS)
|
|
850
850
|
*/
|
|
851
851
|
getTransitionCSS() {
|
|
852
|
-
const t = this.config.timing.duration,
|
|
853
|
-
return this.requiresJSAnimation() ? `opacity ${t}ms ease-out` : `opacity ${t}ms ease-out, transform ${t}ms ${
|
|
852
|
+
const t = this.config.timing.duration, i = this.config.easing;
|
|
853
|
+
return this.requiresJSAnimation() ? `opacity ${t}ms ease-out` : `opacity ${t}ms ease-out, transform ${t}ms ${i}`;
|
|
854
854
|
}
|
|
855
855
|
/**
|
|
856
856
|
* Check if the current path type requires JavaScript animation
|
|
@@ -900,17 +900,17 @@ class se {
|
|
|
900
900
|
case "none":
|
|
901
901
|
return t;
|
|
902
902
|
case "settle": {
|
|
903
|
-
const
|
|
904
|
-
if (
|
|
903
|
+
const e = this.rotationConfig.startRotation;
|
|
904
|
+
if (e === void 0)
|
|
905
905
|
return t + (Math.random() - 0.5) * 60;
|
|
906
|
-
if (typeof
|
|
907
|
-
return
|
|
908
|
-
const o =
|
|
909
|
-
return
|
|
906
|
+
if (typeof e == "number")
|
|
907
|
+
return e;
|
|
908
|
+
const o = e.max - e.min;
|
|
909
|
+
return e.min + Math.random() * o;
|
|
910
910
|
}
|
|
911
911
|
case "spin": {
|
|
912
|
-
const
|
|
913
|
-
return t +
|
|
912
|
+
const e = this.rotationConfig.spinCount ?? 1, o = this.resolveSpinDirection(t);
|
|
913
|
+
return t + e * 360 * o;
|
|
914
914
|
}
|
|
915
915
|
case "random":
|
|
916
916
|
return t + (Math.random() - 0.5) * 60;
|
|
@@ -951,15 +951,15 @@ class se {
|
|
|
951
951
|
* @param finalRotation - The final rotation in degrees
|
|
952
952
|
* @returns The current rotation in degrees
|
|
953
953
|
*/
|
|
954
|
-
calculateWobbleRotation(t,
|
|
954
|
+
calculateWobbleRotation(t, i) {
|
|
955
955
|
if (this.rotationConfig.mode !== "wobble")
|
|
956
|
-
return
|
|
957
|
-
const
|
|
956
|
+
return i;
|
|
957
|
+
const e = this.rotationConfig.wobble || {
|
|
958
958
|
amplitude: 15,
|
|
959
959
|
frequency: 3,
|
|
960
960
|
decay: !0
|
|
961
|
-
}, { amplitude: o, frequency: a, decay: r } =
|
|
962
|
-
return
|
|
961
|
+
}, { amplitude: o, frequency: a, decay: r } = e, s = Math.sin(t * a * Math.PI * 2), h = r ? Math.pow(1 - t, 2) : 1, c = o * s * h;
|
|
962
|
+
return i + c;
|
|
963
963
|
}
|
|
964
964
|
/**
|
|
965
965
|
* Get the scale configuration
|
|
@@ -989,8 +989,8 @@ class se {
|
|
|
989
989
|
case "pop":
|
|
990
990
|
return t;
|
|
991
991
|
case "random": {
|
|
992
|
-
const
|
|
993
|
-
return (
|
|
992
|
+
const e = this.scaleConfig.range ?? { min: 0.5, max: 1 };
|
|
993
|
+
return (e.min + Math.random() * (e.max - e.min)) * t;
|
|
994
994
|
}
|
|
995
995
|
default:
|
|
996
996
|
return t;
|
|
@@ -1009,36 +1009,36 @@ class se {
|
|
|
1009
1009
|
* @param finalScale - The final scale value
|
|
1010
1010
|
* @returns The current scale value with bounce effect
|
|
1011
1011
|
*/
|
|
1012
|
-
calculatePopScale(t,
|
|
1012
|
+
calculatePopScale(t, i) {
|
|
1013
1013
|
if (this.scaleConfig.mode !== "pop")
|
|
1014
|
-
return
|
|
1015
|
-
const
|
|
1014
|
+
return i;
|
|
1015
|
+
const e = this.scaleConfig.pop || {
|
|
1016
1016
|
overshoot: 1.2,
|
|
1017
1017
|
bounces: 1
|
|
1018
|
-
}, { overshoot: o, bounces: a } =
|
|
1019
|
-
let s =
|
|
1018
|
+
}, { overshoot: o, bounces: a } = e, r = this.generateScaleBounceKeyframes(a, o);
|
|
1019
|
+
let s = i;
|
|
1020
1020
|
for (let h = 0; h < r.length; h++)
|
|
1021
1021
|
if (t <= r[h].time) {
|
|
1022
|
-
const c = h === 0 ? 0 : r[h - 1].time, d = h === 0 ?
|
|
1022
|
+
const c = h === 0 ? 0 : r[h - 1].time, d = h === 0 ? i : r[h - 1].scale, l = (t - c) / (r[h].time - c), u = this.easeOutQuad(l);
|
|
1023
1023
|
s = d + (r[h].scale - d) * u;
|
|
1024
1024
|
break;
|
|
1025
1025
|
}
|
|
1026
|
-
return s *
|
|
1026
|
+
return s * i;
|
|
1027
1027
|
}
|
|
1028
1028
|
/**
|
|
1029
1029
|
* Generate keyframes for scale bounce animation
|
|
1030
1030
|
*/
|
|
1031
|
-
generateScaleBounceKeyframes(t,
|
|
1032
|
-
const
|
|
1033
|
-
|
|
1034
|
-
let o =
|
|
1031
|
+
generateScaleBounceKeyframes(t, i) {
|
|
1032
|
+
const e = [];
|
|
1033
|
+
e.push({ time: 0.5, scale: i });
|
|
1034
|
+
let o = i;
|
|
1035
1035
|
const a = 0.5, s = 0.5 / (t * 2);
|
|
1036
1036
|
let h = 0.5;
|
|
1037
1037
|
for (let c = 0; c < t; c++) {
|
|
1038
1038
|
const d = 1 - (o - 1) * a;
|
|
1039
|
-
h += s,
|
|
1039
|
+
h += s, e.push({ time: h, scale: d }), o = 1 + (o - 1) * a * a, h += s, c < t - 1 && e.push({ time: h, scale: o });
|
|
1040
1040
|
}
|
|
1041
|
-
return
|
|
1041
|
+
return e.push({ time: 1, scale: 1 }), e;
|
|
1042
1042
|
}
|
|
1043
1043
|
/**
|
|
1044
1044
|
* Easing function for smooth transitions
|
|
@@ -1048,8 +1048,8 @@ class se {
|
|
|
1048
1048
|
}
|
|
1049
1049
|
}
|
|
1050
1050
|
class ae {
|
|
1051
|
-
constructor(t,
|
|
1052
|
-
this.config = t, this.imageConfig =
|
|
1051
|
+
constructor(t, i = {}) {
|
|
1052
|
+
this.config = t, this.imageConfig = i;
|
|
1053
1053
|
}
|
|
1054
1054
|
/**
|
|
1055
1055
|
* Generate random layout positions for images
|
|
@@ -1058,18 +1058,18 @@ class ae {
|
|
|
1058
1058
|
* @param options - Optional overrides (includes fixedHeight)
|
|
1059
1059
|
* @returns Array of layout objects with position, rotation, scale
|
|
1060
1060
|
*/
|
|
1061
|
-
generate(t,
|
|
1062
|
-
const o = [], { width: a, height: r } =
|
|
1061
|
+
generate(t, i, e = {}) {
|
|
1062
|
+
const o = [], { width: a, height: r } = i, s = this.config.spacing.padding, h = e.fixedHeight ?? 200, c = this.imageConfig.rotation?.mode ?? "none", d = this.imageConfig.rotation?.range?.min ?? -15, l = this.imageConfig.rotation?.range?.max ?? 15, u = this.imageConfig.sizing?.variance?.min ?? 1, g = this.imageConfig.sizing?.variance?.max ?? 1, p = u !== 1 || g !== 1, f = h * 1.5 / 2, m = h / 2, E = a - s - f, v = r - s - m, w = s + f, S = s + m;
|
|
1063
1063
|
for (let x = 0; x < t; x++) {
|
|
1064
|
-
const
|
|
1064
|
+
const I = this.random(w, E), M = this.random(S, v), F = c === "random" ? this.random(d, l) : 0, _ = p ? this.random(u, g) : 1, U = h * _, B = {
|
|
1065
1065
|
id: x,
|
|
1066
|
-
x:
|
|
1067
|
-
y:
|
|
1068
|
-
rotation:
|
|
1066
|
+
x: I,
|
|
1067
|
+
y: M,
|
|
1068
|
+
rotation: F,
|
|
1069
1069
|
scale: _,
|
|
1070
1070
|
baseSize: U
|
|
1071
1071
|
};
|
|
1072
|
-
o.push(
|
|
1072
|
+
o.push(B);
|
|
1073
1073
|
}
|
|
1074
1074
|
return o;
|
|
1075
1075
|
}
|
|
@@ -1079,13 +1079,13 @@ class ae {
|
|
|
1079
1079
|
* @param max - Maximum value
|
|
1080
1080
|
* @returns Random number in range
|
|
1081
1081
|
*/
|
|
1082
|
-
random(t,
|
|
1083
|
-
return Math.random() * (
|
|
1082
|
+
random(t, i) {
|
|
1083
|
+
return Math.random() * (i - t) + t;
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|
|
1086
1086
|
class re {
|
|
1087
|
-
constructor(t,
|
|
1088
|
-
this.config = t, this.imageConfig =
|
|
1087
|
+
constructor(t, i = {}) {
|
|
1088
|
+
this.config = t, this.imageConfig = i;
|
|
1089
1089
|
}
|
|
1090
1090
|
/**
|
|
1091
1091
|
* Generate radial layout positions for images
|
|
@@ -1094,8 +1094,8 @@ class re {
|
|
|
1094
1094
|
* @param options - Optional overrides
|
|
1095
1095
|
* @returns Array of layout objects with position, rotation, scale
|
|
1096
1096
|
*/
|
|
1097
|
-
generate(t,
|
|
1098
|
-
const o = [], { width: a, height: r } =
|
|
1097
|
+
generate(t, i, e = {}) {
|
|
1098
|
+
const o = [], { width: a, height: r } = i, s = e.fixedHeight ?? 200, h = this.imageConfig.rotation?.mode ?? "none", c = this.imageConfig.rotation?.range?.min ?? -15, d = this.imageConfig.rotation?.range?.max ?? 15, l = this.imageConfig.sizing?.variance?.min ?? 1, u = this.imageConfig.sizing?.variance?.max ?? 1, g = l !== 1 || u !== 1, p = this.config.scaleDecay ?? 0, b = e.fixedHeight ?? s, f = a / 2, m = r / 2, E = Math.ceil(Math.sqrt(t));
|
|
1099
1099
|
if (t > 0) {
|
|
1100
1100
|
const S = g ? this.random(l, u) : 1, x = b * S;
|
|
1101
1101
|
o.push({
|
|
@@ -1112,25 +1112,25 @@ class re {
|
|
|
1112
1112
|
}
|
|
1113
1113
|
let v = 1, w = 1;
|
|
1114
1114
|
for (; v < t; ) {
|
|
1115
|
-
const S = w / E, x = p > 0 ? 1 - S * p * 0.5 : 1,
|
|
1115
|
+
const S = w / E, x = p > 0 ? 1 - S * p * 0.5 : 1, I = w * (b * 0.8), M = I * 1.5, F = Math.PI * (3 * (M + I) - Math.sqrt((3 * M + I) * (M + 3 * I))), _ = this.estimateWidth(b), U = Math.floor(F / (_ * 0.7));
|
|
1116
1116
|
if (U === 0) {
|
|
1117
1117
|
w++;
|
|
1118
1118
|
continue;
|
|
1119
1119
|
}
|
|
1120
|
-
const
|
|
1121
|
-
for (let
|
|
1122
|
-
const O =
|
|
1123
|
-
let
|
|
1124
|
-
const D = this.config.spacing.padding ?? 50, P =
|
|
1125
|
-
|
|
1120
|
+
const B = 2 * Math.PI / U, N = w * (20 * Math.PI / 180);
|
|
1121
|
+
for (let T = 0; T < U && v < t; T++) {
|
|
1122
|
+
const O = T * B + N, k = g ? this.random(l, u) : 1, H = x * k, C = b * H;
|
|
1123
|
+
let A = f + Math.cos(O) * M, $ = m + Math.sin(O) * I;
|
|
1124
|
+
const D = this.config.spacing.padding ?? 50, P = C * 1.5 / 2, L = C / 2;
|
|
1125
|
+
A - P < D ? A = D + P : A + P > a - D && (A = a - D - P), $ - L < D ? $ = D + L : $ + L > r - D && ($ = r - D - L);
|
|
1126
1126
|
const W = h === "random" ? this.random(c, d) : 0;
|
|
1127
1127
|
o.push({
|
|
1128
1128
|
id: v,
|
|
1129
|
-
x:
|
|
1129
|
+
x: A,
|
|
1130
1130
|
y: $,
|
|
1131
1131
|
rotation: W,
|
|
1132
1132
|
scale: H,
|
|
1133
|
-
baseSize:
|
|
1133
|
+
baseSize: C,
|
|
1134
1134
|
zIndex: Math.max(1, 100 - w)
|
|
1135
1135
|
// Outer rings have lower z-index
|
|
1136
1136
|
}), v++;
|
|
@@ -1154,8 +1154,8 @@ class re {
|
|
|
1154
1154
|
* @param max - Maximum value
|
|
1155
1155
|
* @returns Random number in range
|
|
1156
1156
|
*/
|
|
1157
|
-
random(t,
|
|
1158
|
-
return Math.random() * (
|
|
1157
|
+
random(t, i) {
|
|
1158
|
+
return Math.random() * (i - t) + t;
|
|
1159
1159
|
}
|
|
1160
1160
|
}
|
|
1161
1161
|
const ce = {
|
|
@@ -1168,7 +1168,7 @@ const ce = {
|
|
|
1168
1168
|
alignment: "center",
|
|
1169
1169
|
gap: 10,
|
|
1170
1170
|
overflowOffset: 0.25
|
|
1171
|
-
},
|
|
1171
|
+
}, Tt = [
|
|
1172
1172
|
{ x: 1, y: 1 },
|
|
1173
1173
|
// bottom-right
|
|
1174
1174
|
{ x: -1, y: -1 },
|
|
@@ -1187,8 +1187,8 @@ const ce = {
|
|
|
1187
1187
|
// down
|
|
1188
1188
|
];
|
|
1189
1189
|
class le {
|
|
1190
|
-
constructor(t,
|
|
1191
|
-
this.config = t, this.imageConfig =
|
|
1190
|
+
constructor(t, i = {}) {
|
|
1191
|
+
this.config = t, this.imageConfig = i;
|
|
1192
1192
|
}
|
|
1193
1193
|
/**
|
|
1194
1194
|
* Generate grid layout positions for images
|
|
@@ -1197,66 +1197,66 @@ class le {
|
|
|
1197
1197
|
* @param options - Optional overrides (includes fixedHeight)
|
|
1198
1198
|
* @returns Array of layout objects with position, rotation, scale
|
|
1199
1199
|
*/
|
|
1200
|
-
generate(t,
|
|
1201
|
-
const o = [], { width: a, height: r } =
|
|
1200
|
+
generate(t, i, e = {}) {
|
|
1201
|
+
const o = [], { width: a, height: r } = i, s = { ...ce, ...this.config.grid }, h = this.config.spacing.padding, c = e.fixedHeight ?? 200, d = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.sizing?.variance?.min ?? 1, u = this.imageConfig.sizing?.variance?.max ?? 1, g = l !== 1 || u !== 1, p = a - 2 * h, b = r - 2 * h, { columns: f, rows: m } = this.calculateGridDimensions(
|
|
1202
1202
|
t,
|
|
1203
1203
|
p,
|
|
1204
1204
|
b,
|
|
1205
1205
|
c,
|
|
1206
1206
|
s
|
|
1207
|
-
), E = s.stagger === "row", v = s.stagger === "column", w = E ? f + 0.5 : f, S = v ? m + 0.5 : m, x = (p - s.gap * (f - 1)) / w,
|
|
1207
|
+
), E = s.stagger === "row", v = s.stagger === "column", w = E ? f + 0.5 : f, S = v ? m + 0.5 : m, x = (p - s.gap * (f - 1)) / w, I = (b - s.gap * (m - 1)) / S, M = E ? x / 2 : 0, F = v ? I / 2 : 0, _ = 1 + s.overlap, U = Math.min(x, I) * _, B = e.fixedHeight ? Math.min(e.fixedHeight, U) : U, N = f * x + (f - 1) * s.gap + M, T = m * I + (m - 1) * s.gap + F, O = h + (p - N) / 2, k = h + (b - T) / 2, H = f * m, C = s.columns !== "auto" && s.rows !== "auto", A = C && t > H;
|
|
1208
1208
|
typeof window < "u" && (window.__gridOverflowDebug = {
|
|
1209
1209
|
gridConfigColumns: s.columns,
|
|
1210
1210
|
gridConfigRows: s.rows,
|
|
1211
1211
|
columns: f,
|
|
1212
1212
|
rows: m,
|
|
1213
1213
|
cellCount: H,
|
|
1214
|
-
hasFixedGrid:
|
|
1214
|
+
hasFixedGrid: C,
|
|
1215
1215
|
imageCount: t,
|
|
1216
|
-
isOverflowMode:
|
|
1216
|
+
isOverflowMode: A
|
|
1217
1217
|
});
|
|
1218
|
-
const $ =
|
|
1219
|
-
for (let
|
|
1220
|
-
let P,
|
|
1221
|
-
if (
|
|
1222
|
-
const q =
|
|
1223
|
-
W = Math.floor(q / H) + 1, $[j]++, s.fillDirection === "row" ? (P = j % f,
|
|
1218
|
+
const $ = A ? new Array(H).fill(0) : [], D = Math.min(x, I) * s.overflowOffset;
|
|
1219
|
+
for (let z = 0; z < t; z++) {
|
|
1220
|
+
let P, L, W = 0;
|
|
1221
|
+
if (A && z >= H) {
|
|
1222
|
+
const q = z - H, j = q % H;
|
|
1223
|
+
W = Math.floor(q / H) + 1, $[j]++, s.fillDirection === "row" ? (P = j % f, L = Math.floor(j / f)) : (L = j % m, P = Math.floor(j / m));
|
|
1224
1224
|
} else
|
|
1225
|
-
s.fillDirection === "row" ? (P =
|
|
1226
|
-
let G = O + P * (x + s.gap) + x / 2,
|
|
1227
|
-
if (s.stagger === "row" &&
|
|
1228
|
-
const q = (W - 1) %
|
|
1229
|
-
G += j.x * D,
|
|
1225
|
+
s.fillDirection === "row" ? (P = z % f, L = Math.floor(z / f)) : (L = z % m, P = Math.floor(z / m));
|
|
1226
|
+
let G = O + P * (x + s.gap) + x / 2, Y = k + L * (I + s.gap) + I / 2;
|
|
1227
|
+
if (s.stagger === "row" && L % 2 === 1 ? G += x / 2 : s.stagger === "column" && P % 2 === 1 && (Y += I / 2), W > 0) {
|
|
1228
|
+
const q = (W - 1) % Tt.length, j = Tt[q];
|
|
1229
|
+
G += j.x * D, Y += j.y * D;
|
|
1230
1230
|
}
|
|
1231
1231
|
if (s.jitter > 0) {
|
|
1232
|
-
const q = x / 2 * s.jitter, j =
|
|
1233
|
-
G += this.random(-q, q),
|
|
1232
|
+
const q = x / 2 * s.jitter, j = I / 2 * s.jitter;
|
|
1233
|
+
G += this.random(-q, q), Y += this.random(-j, j);
|
|
1234
1234
|
}
|
|
1235
|
-
let
|
|
1236
|
-
if (!
|
|
1235
|
+
let X = G, J = Y;
|
|
1236
|
+
if (!A && s.fillDirection === "row") {
|
|
1237
1237
|
const q = t % f || f;
|
|
1238
|
-
if (
|
|
1238
|
+
if (L === Math.floor((t - 1) / f) && q < f) {
|
|
1239
1239
|
const Et = q * x + (q - 1) * s.gap;
|
|
1240
|
-
let
|
|
1241
|
-
s.alignment === "center" ?
|
|
1240
|
+
let ut = 0;
|
|
1241
|
+
s.alignment === "center" ? ut = (N - Et) / 2 : s.alignment === "end" && (ut = N - Et), X += ut;
|
|
1242
1242
|
}
|
|
1243
1243
|
}
|
|
1244
|
-
const
|
|
1245
|
-
|
|
1246
|
-
let
|
|
1244
|
+
const at = g ? this.random(l, u) : 1, K = B * at, et = K * 1.5 / 2, it = K / 2, ct = h + et, lt = a - h - et, $t = h + it, Dt = r - h - it;
|
|
1245
|
+
X = Math.max(ct, Math.min(X, lt)), J = Math.max($t, Math.min(J, Dt));
|
|
1246
|
+
let ht = 0;
|
|
1247
1247
|
if (d === "random") {
|
|
1248
1248
|
const q = this.imageConfig.rotation?.range?.min ?? -15, j = this.imageConfig.rotation?.range?.max ?? 15;
|
|
1249
|
-
s.jitter > 0 ?
|
|
1249
|
+
s.jitter > 0 ? ht = this.random(q * s.jitter, j * s.jitter) : ht = this.random(q, j);
|
|
1250
1250
|
}
|
|
1251
|
-
let
|
|
1252
|
-
|
|
1253
|
-
id:
|
|
1254
|
-
x:
|
|
1251
|
+
let dt;
|
|
1252
|
+
A && W > 0 ? dt = 50 - W : dt = A ? 100 + z : z + 1, o.push({
|
|
1253
|
+
id: z,
|
|
1254
|
+
x: X,
|
|
1255
1255
|
y: J,
|
|
1256
|
-
rotation:
|
|
1257
|
-
scale:
|
|
1256
|
+
rotation: ht,
|
|
1257
|
+
scale: at,
|
|
1258
1258
|
baseSize: K,
|
|
1259
|
-
zIndex:
|
|
1259
|
+
zIndex: dt
|
|
1260
1260
|
});
|
|
1261
1261
|
}
|
|
1262
1262
|
return o;
|
|
@@ -1264,7 +1264,7 @@ class le {
|
|
|
1264
1264
|
/**
|
|
1265
1265
|
* Calculate optimal grid dimensions based on image count and container
|
|
1266
1266
|
*/
|
|
1267
|
-
calculateGridDimensions(t,
|
|
1267
|
+
calculateGridDimensions(t, i, e, o, a) {
|
|
1268
1268
|
let r, s;
|
|
1269
1269
|
if (a.columns !== "auto" && a.rows !== "auto")
|
|
1270
1270
|
r = a.columns, s = a.rows;
|
|
@@ -1273,7 +1273,7 @@ class le {
|
|
|
1273
1273
|
else if (a.rows !== "auto")
|
|
1274
1274
|
s = a.rows, r = Math.ceil(t / s);
|
|
1275
1275
|
else {
|
|
1276
|
-
const h =
|
|
1276
|
+
const h = i / e;
|
|
1277
1277
|
for (r = Math.max(1, Math.round(Math.sqrt(t * h / 1.4))), s = Math.ceil(t / r); r > 1 && (r - 1) * s >= t; )
|
|
1278
1278
|
r--;
|
|
1279
1279
|
}
|
|
@@ -1282,8 +1282,8 @@ class le {
|
|
|
1282
1282
|
/**
|
|
1283
1283
|
* Utility: Generate random number between min and max
|
|
1284
1284
|
*/
|
|
1285
|
-
random(t,
|
|
1286
|
-
return Math.random() * (
|
|
1285
|
+
random(t, i) {
|
|
1286
|
+
return Math.random() * (i - t) + t;
|
|
1287
1287
|
}
|
|
1288
1288
|
}
|
|
1289
1289
|
const he = Math.PI * (3 - Math.sqrt(5)), de = {
|
|
@@ -1294,8 +1294,8 @@ const he = Math.PI * (3 - Math.sqrt(5)), de = {
|
|
|
1294
1294
|
startAngle: 0
|
|
1295
1295
|
};
|
|
1296
1296
|
class ue {
|
|
1297
|
-
constructor(t,
|
|
1298
|
-
this.config = t, this.imageConfig =
|
|
1297
|
+
constructor(t, i = {}) {
|
|
1298
|
+
this.config = t, this.imageConfig = i;
|
|
1299
1299
|
}
|
|
1300
1300
|
/**
|
|
1301
1301
|
* Generate spiral layout positions for images
|
|
@@ -1304,36 +1304,36 @@ class ue {
|
|
|
1304
1304
|
* @param options - Optional overrides (includes fixedHeight)
|
|
1305
1305
|
* @returns Array of layout objects with position, rotation, scale
|
|
1306
1306
|
*/
|
|
1307
|
-
generate(t,
|
|
1308
|
-
const o = [], { width: a, height: r } =
|
|
1307
|
+
generate(t, i, e = {}) {
|
|
1308
|
+
const o = [], { width: a, height: r } = i, s = { ...de, ...this.config.spiral }, h = this.config.spacing.padding, c = e.fixedHeight ?? 200, d = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.rotation?.range?.min ?? -15, u = this.imageConfig.rotation?.range?.max ?? 15, g = this.imageConfig.sizing?.variance?.min ?? 1, p = this.imageConfig.sizing?.variance?.max ?? 1, b = g !== 1 || p !== 1, f = this.config.scaleDecay ?? s.scaleDecay, m = a / 2, E = r / 2, v = Math.min(
|
|
1309
1309
|
m - h - c / 2,
|
|
1310
1310
|
E - h - c / 2
|
|
1311
1311
|
), w = s.direction === "clockwise" ? -1 : 1;
|
|
1312
1312
|
for (let S = 0; S < t; S++) {
|
|
1313
|
-
let x,
|
|
1313
|
+
let x, I;
|
|
1314
1314
|
if (s.spiralType === "golden")
|
|
1315
|
-
x = S * he * w + s.startAngle,
|
|
1315
|
+
x = S * he * w + s.startAngle, I = this.calculateGoldenRadius(S, t, v, s.tightness);
|
|
1316
1316
|
else if (s.spiralType === "archimedean") {
|
|
1317
1317
|
const G = S * 0.5 * s.tightness;
|
|
1318
|
-
x = G * w + s.startAngle,
|
|
1318
|
+
x = G * w + s.startAngle, I = this.calculateArchimedeanRadius(G, t, v, s.tightness);
|
|
1319
1319
|
} else {
|
|
1320
1320
|
const G = S * 0.3 * s.tightness;
|
|
1321
|
-
x = G * w + s.startAngle,
|
|
1321
|
+
x = G * w + s.startAngle, I = this.calculateLogarithmicRadius(G, t, v, s.tightness);
|
|
1322
1322
|
}
|
|
1323
|
-
const
|
|
1324
|
-
let
|
|
1323
|
+
const M = m + Math.cos(x) * I, F = E + Math.sin(x) * I, _ = I / v, U = f > 0 ? 1 - _ * f * 0.5 : 1, B = b ? this.random(g, p) : 1, N = U * B, T = c * N, k = T * 1.5 / 2, H = T / 2, C = h + k, A = a - h - k, $ = h + H, D = r - h - H, z = Math.max(C, Math.min(M, A)), P = Math.max($, Math.min(F, D));
|
|
1324
|
+
let L = 0;
|
|
1325
1325
|
if (d === "random") {
|
|
1326
|
-
const G = x * 180 / Math.PI % 360,
|
|
1327
|
-
|
|
1328
|
-
} else d === "tangent" && (
|
|
1326
|
+
const G = x * 180 / Math.PI % 360, Y = this.random(l, u);
|
|
1327
|
+
L = s.spiralType === "golden" ? Y : G * 0.1 + Y * 0.9;
|
|
1328
|
+
} else d === "tangent" && (L = this.calculateSpiralTangent(x, I, s));
|
|
1329
1329
|
const W = t - S;
|
|
1330
1330
|
o.push({
|
|
1331
1331
|
id: S,
|
|
1332
|
-
x:
|
|
1332
|
+
x: z,
|
|
1333
1333
|
y: P,
|
|
1334
|
-
rotation:
|
|
1334
|
+
rotation: L,
|
|
1335
1335
|
scale: N,
|
|
1336
|
-
baseSize:
|
|
1336
|
+
baseSize: T,
|
|
1337
1337
|
zIndex: W
|
|
1338
1338
|
});
|
|
1339
1339
|
}
|
|
@@ -1343,15 +1343,15 @@ class ue {
|
|
|
1343
1343
|
* Calculate tangent angle for spiral curve at given position
|
|
1344
1344
|
* This aligns the image along the spiral's direction of travel
|
|
1345
1345
|
*/
|
|
1346
|
-
calculateSpiralTangent(t,
|
|
1346
|
+
calculateSpiralTangent(t, i, e) {
|
|
1347
1347
|
let o;
|
|
1348
|
-
if (
|
|
1348
|
+
if (e.spiralType === "golden")
|
|
1349
1349
|
o = t + Math.PI / 2;
|
|
1350
|
-
else if (
|
|
1351
|
-
const r = 1 /
|
|
1350
|
+
else if (e.spiralType === "archimedean") {
|
|
1351
|
+
const r = 1 / e.tightness, s = Math.atan(i / r);
|
|
1352
1352
|
o = t + s;
|
|
1353
1353
|
} else {
|
|
1354
|
-
const r = 0.15 /
|
|
1354
|
+
const r = 0.15 / e.tightness, s = Math.atan(1 / r);
|
|
1355
1355
|
o = t + s;
|
|
1356
1356
|
}
|
|
1357
1357
|
return o * 180 / Math.PI % 360 - 90;
|
|
@@ -1360,31 +1360,31 @@ class ue {
|
|
|
1360
1360
|
* Calculate radius for golden spiral (Vogel's model)
|
|
1361
1361
|
* Creates even distribution like sunflower seeds
|
|
1362
1362
|
*/
|
|
1363
|
-
calculateGoldenRadius(t,
|
|
1364
|
-
const r =
|
|
1365
|
-
return Math.min(r,
|
|
1363
|
+
calculateGoldenRadius(t, i, e, o) {
|
|
1364
|
+
const r = e / Math.sqrt(i) * Math.sqrt(t) / o;
|
|
1365
|
+
return Math.min(r, e);
|
|
1366
1366
|
}
|
|
1367
1367
|
/**
|
|
1368
1368
|
* Calculate radius for Archimedean spiral
|
|
1369
1369
|
* r = a + b*θ (constant spacing between arms)
|
|
1370
1370
|
*/
|
|
1371
|
-
calculateArchimedeanRadius(t,
|
|
1372
|
-
const a =
|
|
1373
|
-
return t / a *
|
|
1371
|
+
calculateArchimedeanRadius(t, i, e, o) {
|
|
1372
|
+
const a = i * 0.5 * o;
|
|
1373
|
+
return t / a * e;
|
|
1374
1374
|
}
|
|
1375
1375
|
/**
|
|
1376
1376
|
* Calculate radius for logarithmic (equiangular) spiral
|
|
1377
1377
|
* r = a * e^(b*θ)
|
|
1378
1378
|
*/
|
|
1379
|
-
calculateLogarithmicRadius(t,
|
|
1380
|
-
const a =
|
|
1381
|
-
return s / c *
|
|
1379
|
+
calculateLogarithmicRadius(t, i, e, o) {
|
|
1380
|
+
const a = e * 0.05, r = 0.15 / o, s = a * Math.exp(r * t), h = i * 0.3 * o, c = a * Math.exp(r * h);
|
|
1381
|
+
return s / c * e;
|
|
1382
1382
|
}
|
|
1383
1383
|
/**
|
|
1384
1384
|
* Utility: Generate random number between min and max
|
|
1385
1385
|
*/
|
|
1386
|
-
random(t,
|
|
1387
|
-
return Math.random() * (
|
|
1386
|
+
random(t, i) {
|
|
1387
|
+
return Math.random() * (i - t) + t;
|
|
1388
1388
|
}
|
|
1389
1389
|
}
|
|
1390
1390
|
const ge = {
|
|
@@ -1396,8 +1396,8 @@ const ge = {
|
|
|
1396
1396
|
distribution: "gaussian"
|
|
1397
1397
|
};
|
|
1398
1398
|
class fe {
|
|
1399
|
-
constructor(t,
|
|
1400
|
-
this.config = t, this.imageConfig =
|
|
1399
|
+
constructor(t, i = {}) {
|
|
1400
|
+
this.config = t, this.imageConfig = i;
|
|
1401
1401
|
}
|
|
1402
1402
|
/**
|
|
1403
1403
|
* Generate cluster layout positions for images
|
|
@@ -1406,8 +1406,8 @@ class fe {
|
|
|
1406
1406
|
* @param options - Optional overrides (includes fixedHeight)
|
|
1407
1407
|
* @returns Array of layout objects with position, rotation, scale
|
|
1408
1408
|
*/
|
|
1409
|
-
generate(t,
|
|
1410
|
-
const o = [], { width: a, height: r } =
|
|
1409
|
+
generate(t, i, e = {}) {
|
|
1410
|
+
const o = [], { width: a, height: r } = i, s = { ...ge, ...this.config.cluster }, h = this.config.spacing.padding, c = e.fixedHeight ?? 200, d = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.rotation?.range?.min ?? -15, u = this.imageConfig.rotation?.range?.max ?? 15, g = this.imageConfig.sizing?.variance?.min ?? 1, p = this.imageConfig.sizing?.variance?.max ?? 1, b = g !== 1 || p !== 1, f = this.calculateClusterCount(
|
|
1411
1411
|
t,
|
|
1412
1412
|
s.clusterCount,
|
|
1413
1413
|
a,
|
|
@@ -1425,28 +1425,28 @@ class fe {
|
|
|
1425
1425
|
let v = 0;
|
|
1426
1426
|
for (let w = 0; w < f; w++) {
|
|
1427
1427
|
const S = m[w], x = E[w];
|
|
1428
|
-
for (let
|
|
1429
|
-
let
|
|
1428
|
+
for (let I = 0; I < x; I++) {
|
|
1429
|
+
let M, F;
|
|
1430
1430
|
if (s.distribution === "gaussian")
|
|
1431
|
-
|
|
1431
|
+
M = this.gaussianRandom() * S.spread, F = this.gaussianRandom() * S.spread;
|
|
1432
1432
|
else {
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1433
|
+
const L = this.random(0, Math.PI * 2), W = this.random(0, S.spread);
|
|
1434
|
+
M = Math.cos(L) * W, F = Math.sin(L) * W;
|
|
1435
1435
|
}
|
|
1436
1436
|
const _ = 1 + s.overlap * 0.5, U = 1 + s.overlap * 0.3;
|
|
1437
|
-
|
|
1438
|
-
const
|
|
1439
|
-
let O = S.x +
|
|
1440
|
-
const
|
|
1441
|
-
O = Math.max(h +
|
|
1442
|
-
const $ = d === "random" ? this.random(l, u) : 0,
|
|
1437
|
+
M /= _, F /= _;
|
|
1438
|
+
const B = b ? this.random(g, p) : 1, N = U * B, T = c * N;
|
|
1439
|
+
let O = S.x + M, k = S.y + F;
|
|
1440
|
+
const C = T * 1.5 / 2, A = T / 2;
|
|
1441
|
+
O = Math.max(h + C, Math.min(O, a - h - C)), k = Math.max(h + A, Math.min(k, r - h - A));
|
|
1442
|
+
const $ = d === "random" ? this.random(l, u) : 0, z = Math.sqrt(M * M + F * F) / S.spread, P = Math.round((1 - z) * 50) + 1;
|
|
1443
1443
|
o.push({
|
|
1444
1444
|
id: v,
|
|
1445
1445
|
x: O,
|
|
1446
1446
|
y: k,
|
|
1447
1447
|
rotation: $,
|
|
1448
1448
|
scale: N,
|
|
1449
|
-
baseSize:
|
|
1449
|
+
baseSize: T,
|
|
1450
1450
|
zIndex: P
|
|
1451
1451
|
}), v++;
|
|
1452
1452
|
}
|
|
@@ -1456,19 +1456,19 @@ class fe {
|
|
|
1456
1456
|
/**
|
|
1457
1457
|
* Calculate optimal number of clusters based on image count and container
|
|
1458
1458
|
*/
|
|
1459
|
-
calculateClusterCount(t,
|
|
1460
|
-
if (
|
|
1461
|
-
return Math.max(1, Math.min(
|
|
1459
|
+
calculateClusterCount(t, i, e, o, a) {
|
|
1460
|
+
if (i !== "auto")
|
|
1461
|
+
return Math.max(1, Math.min(i, t));
|
|
1462
1462
|
const s = Math.max(1, Math.ceil(t / 8)), h = Math.floor(
|
|
1463
|
-
|
|
1463
|
+
e / a * (o / a) * 0.6
|
|
1464
1464
|
);
|
|
1465
1465
|
return Math.max(1, Math.min(s, h, 10));
|
|
1466
1466
|
}
|
|
1467
1467
|
/**
|
|
1468
1468
|
* Generate cluster center positions with spacing constraints
|
|
1469
1469
|
*/
|
|
1470
|
-
generateClusterCenters(t,
|
|
1471
|
-
const r = [], h = o + a.clusterSpread, c =
|
|
1470
|
+
generateClusterCenters(t, i, e, o, a) {
|
|
1471
|
+
const r = [], h = o + a.clusterSpread, c = i - o - a.clusterSpread, d = o + a.clusterSpread, l = e - o - a.clusterSpread;
|
|
1472
1472
|
for (let u = 0; u < t; u++) {
|
|
1473
1473
|
let g = null, p = -1;
|
|
1474
1474
|
for (let b = 0; b < 100; b++) {
|
|
@@ -1500,22 +1500,22 @@ class fe {
|
|
|
1500
1500
|
* Using Box-Muller transform
|
|
1501
1501
|
*/
|
|
1502
1502
|
gaussianRandom() {
|
|
1503
|
-
let t = 0,
|
|
1503
|
+
let t = 0, i = 0;
|
|
1504
1504
|
for (; t === 0; ) t = Math.random();
|
|
1505
|
-
for (;
|
|
1506
|
-
const
|
|
1507
|
-
return Math.max(-3, Math.min(3,
|
|
1505
|
+
for (; i === 0; ) i = Math.random();
|
|
1506
|
+
const e = Math.sqrt(-2 * Math.log(t)) * Math.cos(2 * Math.PI * i);
|
|
1507
|
+
return Math.max(-3, Math.min(3, e)) / 3;
|
|
1508
1508
|
}
|
|
1509
1509
|
/**
|
|
1510
1510
|
* Utility: Generate random number between min and max
|
|
1511
1511
|
*/
|
|
1512
|
-
random(t,
|
|
1513
|
-
return Math.random() * (
|
|
1512
|
+
random(t, i) {
|
|
1513
|
+
return Math.random() * (i - t) + t;
|
|
1514
1514
|
}
|
|
1515
1515
|
}
|
|
1516
1516
|
class me {
|
|
1517
|
-
constructor(t,
|
|
1518
|
-
this.config = t, this.imageConfig =
|
|
1517
|
+
constructor(t, i = {}) {
|
|
1518
|
+
this.config = t, this.imageConfig = i;
|
|
1519
1519
|
}
|
|
1520
1520
|
/**
|
|
1521
1521
|
* Generate wave layout positions for images
|
|
@@ -1524,30 +1524,30 @@ class me {
|
|
|
1524
1524
|
* @param options - Optional overrides
|
|
1525
1525
|
* @returns Array of layout objects with position, rotation, scale
|
|
1526
1526
|
*/
|
|
1527
|
-
generate(t,
|
|
1528
|
-
const o = [], { width: a, height: r } =
|
|
1527
|
+
generate(t, i, e = {}) {
|
|
1528
|
+
const o = [], { width: a, height: r } = i, s = e.fixedHeight ?? 200, h = this.config.spacing.padding ?? 50, c = this.imageConfig.rotation?.mode ?? "none", d = this.imageConfig.rotation?.range?.min ?? -15, l = this.imageConfig.rotation?.range?.max ?? 15, u = this.imageConfig.sizing?.variance?.min ?? 1, g = this.imageConfig.sizing?.variance?.max ?? 1, p = u !== 1 || g !== 1, b = e.fixedHeight ?? s, f = {
|
|
1529
1529
|
...Pt,
|
|
1530
1530
|
...this.config.wave
|
|
1531
|
-
}, { rows: m, amplitude: E, frequency: v, phaseShift: w, synchronization: S } = f, x = Math.ceil(t / m),
|
|
1532
|
-
let
|
|
1533
|
-
for (let
|
|
1534
|
-
const $ = m === 1 ? (
|
|
1531
|
+
}, { rows: m, amplitude: E, frequency: v, phaseShift: w, synchronization: S } = f, x = Math.ceil(t / m), F = b * 1.5 / 2, _ = h + F, U = a - h - F, B = U - _, N = x > 1 ? B / (x - 1) : 0, T = h + E + b / 2, O = r - h - E - b / 2, k = O - T, H = m > 1 ? k / (m - 1) : 0;
|
|
1532
|
+
let C = 0;
|
|
1533
|
+
for (let A = 0; A < m && C < t; A++) {
|
|
1534
|
+
const $ = m === 1 ? (T + O) / 2 : T + A * H;
|
|
1535
1535
|
let D = 0;
|
|
1536
|
-
S === "offset" ? D =
|
|
1537
|
-
for (let
|
|
1538
|
-
const P = x === 1 ? (_ + U) / 2 : _ +
|
|
1536
|
+
S === "offset" ? D = A * w : S === "alternating" && (D = A * Math.PI);
|
|
1537
|
+
for (let z = 0; z < x && C < t; z++) {
|
|
1538
|
+
const P = x === 1 ? (_ + U) / 2 : _ + z * N, L = this.calculateWaveY(P, a, E, v, D), W = P, G = $ + L, Y = p ? this.random(u, g) : 1, X = b * Y;
|
|
1539
1539
|
let J = 0;
|
|
1540
1540
|
c === "tangent" ? J = this.calculateRotation(P, a, E, v, D) : c === "random" && (J = this.random(d, l));
|
|
1541
|
-
const K =
|
|
1541
|
+
const K = X * 1.5 / 2, rt = X / 2, et = h + K, it = a - h - K, ct = h + rt, lt = r - h - rt;
|
|
1542
1542
|
o.push({
|
|
1543
|
-
id:
|
|
1544
|
-
x: Math.max(
|
|
1545
|
-
y: Math.max(
|
|
1543
|
+
id: C,
|
|
1544
|
+
x: Math.max(et, Math.min(W, it)),
|
|
1545
|
+
y: Math.max(ct, Math.min(G, lt)),
|
|
1546
1546
|
rotation: J,
|
|
1547
|
-
scale:
|
|
1548
|
-
baseSize:
|
|
1549
|
-
zIndex:
|
|
1550
|
-
}),
|
|
1547
|
+
scale: Y,
|
|
1548
|
+
baseSize: X,
|
|
1549
|
+
zIndex: C + 1
|
|
1550
|
+
}), C++;
|
|
1551
1551
|
}
|
|
1552
1552
|
}
|
|
1553
1553
|
return o;
|
|
@@ -1561,9 +1561,9 @@ class me {
|
|
|
1561
1561
|
* @param phase - Phase offset
|
|
1562
1562
|
* @returns Y displacement from baseline
|
|
1563
1563
|
*/
|
|
1564
|
-
calculateWaveY(t,
|
|
1565
|
-
const r = t /
|
|
1566
|
-
return
|
|
1564
|
+
calculateWaveY(t, i, e, o, a) {
|
|
1565
|
+
const r = t / i;
|
|
1566
|
+
return e * Math.sin(o * r * 2 * Math.PI + a);
|
|
1567
1567
|
}
|
|
1568
1568
|
/**
|
|
1569
1569
|
* Calculate rotation based on wave tangent
|
|
@@ -1574,8 +1574,8 @@ class me {
|
|
|
1574
1574
|
* @param phase - Phase offset
|
|
1575
1575
|
* @returns Rotation angle in degrees
|
|
1576
1576
|
*/
|
|
1577
|
-
calculateRotation(t,
|
|
1578
|
-
const r = t /
|
|
1577
|
+
calculateRotation(t, i, e, o, a) {
|
|
1578
|
+
const r = t / i, s = e * o * 2 * Math.PI * Math.cos(o * r * 2 * Math.PI + a) / i;
|
|
1579
1579
|
return Math.atan(s) * (180 / Math.PI);
|
|
1580
1580
|
}
|
|
1581
1581
|
/**
|
|
@@ -1586,8 +1586,8 @@ class me {
|
|
|
1586
1586
|
* @param max - Maximum value
|
|
1587
1587
|
* @returns Random number in range
|
|
1588
1588
|
*/
|
|
1589
|
-
random(t,
|
|
1590
|
-
return Math.random() * (
|
|
1589
|
+
random(t, i) {
|
|
1590
|
+
return Math.random() * (i - t) + t;
|
|
1591
1591
|
}
|
|
1592
1592
|
}
|
|
1593
1593
|
class pe {
|
|
@@ -1621,8 +1621,8 @@ class pe {
|
|
|
1621
1621
|
* @param options - Optional overrides for configuration (e.g. fixedHeight)
|
|
1622
1622
|
* @returns Array of layout objects with position, rotation, scale
|
|
1623
1623
|
*/
|
|
1624
|
-
generateLayout(t,
|
|
1625
|
-
const o = this.placementLayout.generate(t,
|
|
1624
|
+
generateLayout(t, i, e = {}) {
|
|
1625
|
+
const o = this.placementLayout.generate(t, i, e);
|
|
1626
1626
|
return o.forEach((a) => {
|
|
1627
1627
|
this.layouts.set(a.id, a);
|
|
1628
1628
|
}), o;
|
|
@@ -1661,8 +1661,8 @@ class pe {
|
|
|
1661
1661
|
* Resolve breakpoint name based on viewport width
|
|
1662
1662
|
*/
|
|
1663
1663
|
resolveBreakpoint(t) {
|
|
1664
|
-
const
|
|
1665
|
-
return t <=
|
|
1664
|
+
const i = this.getBreakpoints();
|
|
1665
|
+
return t <= i.mobile.maxWidth ? "mobile" : t <= i.tablet.maxWidth ? "tablet" : "screen";
|
|
1666
1666
|
}
|
|
1667
1667
|
/**
|
|
1668
1668
|
* Resolve the effective base height based on image config and current viewport
|
|
@@ -1670,15 +1670,15 @@ class pe {
|
|
|
1670
1670
|
* @returns Resolved base height or undefined if should auto-calculate (adaptive mode)
|
|
1671
1671
|
*/
|
|
1672
1672
|
resolveBaseHeight(t) {
|
|
1673
|
-
const
|
|
1674
|
-
if (!
|
|
1673
|
+
const i = this.imageConfig.sizing;
|
|
1674
|
+
if (!i || i.mode === "adaptive")
|
|
1675
1675
|
return;
|
|
1676
|
-
const
|
|
1677
|
-
if (
|
|
1676
|
+
const e = i.height;
|
|
1677
|
+
if (e === void 0)
|
|
1678
1678
|
return;
|
|
1679
|
-
if (typeof
|
|
1680
|
-
return
|
|
1681
|
-
const o =
|
|
1679
|
+
if (typeof e == "number")
|
|
1680
|
+
return e;
|
|
1681
|
+
const o = e, a = this.resolveBreakpoint(t);
|
|
1682
1682
|
return a === "mobile" ? o.mobile ?? o.tablet ?? o.screen : a === "tablet" ? o.tablet ?? o.screen ?? o.mobile : o.screen ?? o.tablet ?? o.mobile;
|
|
1683
1683
|
}
|
|
1684
1684
|
/**
|
|
@@ -1689,13 +1689,13 @@ class pe {
|
|
|
1689
1689
|
* @param viewportWidth - Current viewport width for baseHeight resolution
|
|
1690
1690
|
* @returns Calculated sizing result with height
|
|
1691
1691
|
*/
|
|
1692
|
-
calculateAdaptiveSize(t,
|
|
1692
|
+
calculateAdaptiveSize(t, i, e, o) {
|
|
1693
1693
|
const a = this.imageConfig.sizing, r = this.resolveBaseHeight(o);
|
|
1694
1694
|
if (r !== void 0)
|
|
1695
1695
|
return { height: r };
|
|
1696
|
-
const s = a?.minSize ?? 50, h = a?.maxSize ?? 400, c = this.config.targetCoverage ?? 0.6, d = this.config.densityFactor ?? 1, { width: l, height: u } = t, b = l * u * c /
|
|
1696
|
+
const s = a?.minSize ?? 50, h = a?.maxSize ?? 400, c = this.config.targetCoverage ?? 0.6, d = this.config.densityFactor ?? 1, { width: l, height: u } = t, b = l * u * c / i;
|
|
1697
1697
|
let m = Math.sqrt(b / 1.4);
|
|
1698
|
-
m *= d, m = Math.min(m,
|
|
1698
|
+
m *= d, m = Math.min(m, e);
|
|
1699
1699
|
let E = this.clamp(m, s, h);
|
|
1700
1700
|
if (E === s && m < s) {
|
|
1701
1701
|
const v = Math.max(s * 0.05, 20);
|
|
@@ -1706,12 +1706,12 @@ class pe {
|
|
|
1706
1706
|
/**
|
|
1707
1707
|
* Utility: Clamp a value between min and max
|
|
1708
1708
|
*/
|
|
1709
|
-
clamp(t,
|
|
1710
|
-
return Math.max(
|
|
1709
|
+
clamp(t, i, e) {
|
|
1710
|
+
return Math.max(i, Math.min(e, t));
|
|
1711
1711
|
}
|
|
1712
1712
|
}
|
|
1713
|
-
var
|
|
1714
|
-
const
|
|
1713
|
+
var R = /* @__PURE__ */ ((n) => (n.IDLE = "idle", n.FOCUSING = "focusing", n.FOCUSED = "focused", n.UNFOCUSING = "unfocusing", n.CROSS_ANIMATING = "cross_animating", n))(R || {});
|
|
1714
|
+
const At = {
|
|
1715
1715
|
// Geometric shapes - uses percentages for responsive sizing
|
|
1716
1716
|
circle: "circle(50%)",
|
|
1717
1717
|
square: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)",
|
|
@@ -1760,25 +1760,25 @@ const Tt = {
|
|
|
1760
1760
|
};
|
|
1761
1761
|
function ye(n) {
|
|
1762
1762
|
if (n)
|
|
1763
|
-
return n in
|
|
1763
|
+
return n in At ? At[n] : n;
|
|
1764
1764
|
}
|
|
1765
|
-
function ve(n, t,
|
|
1766
|
-
const
|
|
1767
|
-
if (!
|
|
1768
|
-
const o = t /
|
|
1765
|
+
function ve(n, t, i) {
|
|
1766
|
+
const e = be[n];
|
|
1767
|
+
if (!e) return "";
|
|
1768
|
+
const o = t / e.refHeight;
|
|
1769
1769
|
if (n === "circle")
|
|
1770
1770
|
return `circle(${Math.round(50 * o * 100) / 100}px)`;
|
|
1771
|
-
const a =
|
|
1772
|
-
return `polygon(${
|
|
1771
|
+
const a = e.refHeight * o, r = a / 2, s = a / 2, h = (i ?? a) / 2, c = t / 2, d = h - r, l = c - s;
|
|
1772
|
+
return `polygon(${e.points.map(([g, p]) => {
|
|
1773
1773
|
const b = Math.round((g * o + d) * 100) / 100, f = Math.round((p * o + l) * 100) / 100;
|
|
1774
1774
|
return `${b}px ${f}px`;
|
|
1775
1775
|
}).join(", ")})`;
|
|
1776
1776
|
}
|
|
1777
1777
|
function we(n) {
|
|
1778
|
-
return n in
|
|
1778
|
+
return n in ft;
|
|
1779
1779
|
}
|
|
1780
1780
|
function xe(n) {
|
|
1781
|
-
return n ? we(n) ?
|
|
1781
|
+
return n ? we(n) ? ft[n] : n : ft.md;
|
|
1782
1782
|
}
|
|
1783
1783
|
function Ee(n) {
|
|
1784
1784
|
if (!n) return "";
|
|
@@ -1787,76 +1787,76 @@ function Ee(n) {
|
|
|
1787
1787
|
if (typeof n.dropShadow == "string")
|
|
1788
1788
|
t.push(`drop-shadow(${n.dropShadow})`);
|
|
1789
1789
|
else {
|
|
1790
|
-
const
|
|
1791
|
-
t.push(`drop-shadow(${
|
|
1790
|
+
const i = n.dropShadow;
|
|
1791
|
+
t.push(`drop-shadow(${i.x}px ${i.y}px ${i.blur}px ${i.color})`);
|
|
1792
1792
|
}
|
|
1793
1793
|
return t.join(" ");
|
|
1794
1794
|
}
|
|
1795
1795
|
function Q(n) {
|
|
1796
1796
|
if (!n || n.style === "none" || n.width === 0)
|
|
1797
1797
|
return "none";
|
|
1798
|
-
const t = n.width ?? 0,
|
|
1799
|
-
return `${t}px ${
|
|
1798
|
+
const t = n.width ?? 0, i = n.style ?? "solid", e = n.color ?? "#000000";
|
|
1799
|
+
return `${t}px ${i} ${e}`;
|
|
1800
1800
|
}
|
|
1801
|
-
function
|
|
1801
|
+
function tt(n, t, i) {
|
|
1802
1802
|
if (!n) return {};
|
|
1803
|
-
const
|
|
1803
|
+
const e = {};
|
|
1804
1804
|
if (n.borderRadiusTopLeft !== void 0 || n.borderRadiusTopRight !== void 0 || n.borderRadiusBottomRight !== void 0 || n.borderRadiusBottomLeft !== void 0) {
|
|
1805
1805
|
const s = n.border?.radius ?? 0;
|
|
1806
|
-
n.borderRadiusTopLeft !== void 0 ?
|
|
1807
|
-
} else n.border?.radius !== void 0 && (
|
|
1806
|
+
n.borderRadiusTopLeft !== void 0 ? e.borderTopLeftRadius = `${n.borderRadiusTopLeft}px` : s && (e.borderTopLeftRadius = `${s}px`), n.borderRadiusTopRight !== void 0 ? e.borderTopRightRadius = `${n.borderRadiusTopRight}px` : s && (e.borderTopRightRadius = `${s}px`), n.borderRadiusBottomRight !== void 0 ? e.borderBottomRightRadius = `${n.borderRadiusBottomRight}px` : s && (e.borderBottomRightRadius = `${s}px`), n.borderRadiusBottomLeft !== void 0 ? e.borderBottomLeftRadius = `${n.borderRadiusBottomLeft}px` : s && (e.borderBottomLeftRadius = `${s}px`);
|
|
1807
|
+
} else n.border?.radius !== void 0 && (e.borderRadius = `${n.border.radius}px`);
|
|
1808
1808
|
if (n.borderTop || n.borderRight || n.borderBottom || n.borderLeft) {
|
|
1809
1809
|
const s = n.border || {}, h = { ...s, ...n.borderTop }, c = { ...s, ...n.borderRight }, d = { ...s, ...n.borderBottom }, l = { ...s, ...n.borderLeft };
|
|
1810
|
-
|
|
1811
|
-
} else n.border && (
|
|
1812
|
-
n.shadow !== void 0 && (
|
|
1810
|
+
e.borderTop = Q(h), e.borderRight = Q(c), e.borderBottom = Q(d), e.borderLeft = Q(l);
|
|
1811
|
+
} else n.border && (e.border = Q(n.border));
|
|
1812
|
+
n.shadow !== void 0 && (e.boxShadow = xe(n.shadow));
|
|
1813
1813
|
const r = Ee(n.filter);
|
|
1814
|
-
if (
|
|
1814
|
+
if (e.filter = r || "none", n.opacity !== void 0 && (e.opacity = String(n.opacity)), n.cursor !== void 0 && (e.cursor = n.cursor), n.outline && n.outline.style !== "none" && (n.outline.width ?? 0) > 0) {
|
|
1815
1815
|
const s = n.outline.width ?? 0, h = n.outline.style ?? "solid", c = n.outline.color ?? "#000000";
|
|
1816
|
-
|
|
1816
|
+
e.outline = `${s}px ${h} ${c}`, n.outline.offset !== void 0 && (e.outlineOffset = `${n.outline.offset}px`);
|
|
1817
1817
|
}
|
|
1818
|
-
if (n.objectFit !== void 0 && (
|
|
1818
|
+
if (n.objectFit !== void 0 && (e.objectFit = n.objectFit), n.aspectRatio !== void 0 && (e.aspectRatio = n.aspectRatio), n.clipPath !== void 0) {
|
|
1819
1819
|
let s;
|
|
1820
1820
|
const h = typeof n.clipPath == "object" && n.clipPath !== null && "shape" in n.clipPath, c = h ? n.clipPath : void 0;
|
|
1821
1821
|
if (c?.mode === "height-relative" && t)
|
|
1822
|
-
s = ve(c.shape, t,
|
|
1822
|
+
s = ve(c.shape, t, i);
|
|
1823
1823
|
else {
|
|
1824
1824
|
const d = h && c ? c.shape : n.clipPath;
|
|
1825
1825
|
s = ye(d);
|
|
1826
1826
|
}
|
|
1827
|
-
s && (s === "none" ?
|
|
1827
|
+
s && (s === "none" ? e.clipPath = "unset" : (e.clipPath = s, e.overflow = "hidden"));
|
|
1828
1828
|
}
|
|
1829
|
-
return
|
|
1829
|
+
return e;
|
|
1830
1830
|
}
|
|
1831
1831
|
function Se(n, t) {
|
|
1832
1832
|
t.borderRadius !== void 0 && (n.style.borderRadius = t.borderRadius), t.borderTopLeftRadius !== void 0 && (n.style.borderTopLeftRadius = t.borderTopLeftRadius), t.borderTopRightRadius !== void 0 && (n.style.borderTopRightRadius = t.borderTopRightRadius), t.borderBottomRightRadius !== void 0 && (n.style.borderBottomRightRadius = t.borderBottomRightRadius), t.borderBottomLeftRadius !== void 0 && (n.style.borderBottomLeftRadius = t.borderBottomLeftRadius), t.border !== void 0 && (n.style.border = t.border), t.borderTop !== void 0 && (n.style.borderTop = t.borderTop), t.borderRight !== void 0 && (n.style.borderRight = t.borderRight), t.borderBottom !== void 0 && (n.style.borderBottom = t.borderBottom), t.borderLeft !== void 0 && (n.style.borderLeft = t.borderLeft), t.boxShadow !== void 0 && (n.style.boxShadow = t.boxShadow), t.filter !== void 0 && (n.style.filter = t.filter), t.opacity !== void 0 && (n.style.opacity = t.opacity), t.cursor !== void 0 && (n.style.cursor = t.cursor), t.outline !== void 0 && (n.style.outline = t.outline), t.outlineOffset !== void 0 && (n.style.outlineOffset = t.outlineOffset), t.objectFit !== void 0 && (n.style.objectFit = t.objectFit), t.aspectRatio !== void 0 && (n.style.aspectRatio = t.aspectRatio), t.clipPath !== void 0 && (n.style.clipPath = t.clipPath), t.overflow !== void 0 && (n.style.overflow = t.overflow);
|
|
1833
1833
|
}
|
|
1834
|
-
function
|
|
1835
|
-
const o =
|
|
1834
|
+
function gt(n, t, i, e) {
|
|
1835
|
+
const o = tt(t, i, e);
|
|
1836
1836
|
Se(n, o);
|
|
1837
1837
|
}
|
|
1838
1838
|
function Ot(n) {
|
|
1839
1839
|
return n ? Array.isArray(n) ? n.join(" ") : n : "";
|
|
1840
1840
|
}
|
|
1841
|
-
function
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1841
|
+
function ot(n, t) {
|
|
1842
|
+
const i = Ot(t);
|
|
1843
|
+
i && i.split(" ").forEach((e) => {
|
|
1844
|
+
e.trim() && n.classList.add(e.trim());
|
|
1845
1845
|
});
|
|
1846
1846
|
}
|
|
1847
|
-
function
|
|
1848
|
-
const
|
|
1849
|
-
|
|
1850
|
-
|
|
1847
|
+
function mt(n, t) {
|
|
1848
|
+
const i = Ot(t);
|
|
1849
|
+
i && i.split(" ").forEach((e) => {
|
|
1850
|
+
e.trim() && n.classList.remove(e.trim());
|
|
1851
1851
|
});
|
|
1852
1852
|
}
|
|
1853
|
-
const
|
|
1853
|
+
const Ct = {
|
|
1854
1854
|
UNFOCUSING: 999,
|
|
1855
1855
|
FOCUSING: 1e3
|
|
1856
1856
|
};
|
|
1857
|
-
class
|
|
1858
|
-
constructor(t,
|
|
1859
|
-
this.state =
|
|
1857
|
+
class Re {
|
|
1858
|
+
constructor(t, i, e) {
|
|
1859
|
+
this.state = R.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null, this.focusGeneration = 0, this.config = t, this.animationEngine = i, this.styling = e, this.focusedClassName = e?.focused?.className;
|
|
1860
1860
|
}
|
|
1861
1861
|
/**
|
|
1862
1862
|
* Get current state machine state
|
|
@@ -1868,7 +1868,7 @@ class Ie {
|
|
|
1868
1868
|
* Check if any animation is in progress
|
|
1869
1869
|
*/
|
|
1870
1870
|
isAnimating() {
|
|
1871
|
-
return this.state !==
|
|
1871
|
+
return this.state !== R.IDLE && this.state !== R.FOCUSED;
|
|
1872
1872
|
}
|
|
1873
1873
|
/**
|
|
1874
1874
|
* Normalize scalePercent value
|
|
@@ -1880,18 +1880,18 @@ class Ie {
|
|
|
1880
1880
|
* Calculate target dimensions for focused image
|
|
1881
1881
|
* Returns actual pixel dimensions instead of scale factor for sharper rendering
|
|
1882
1882
|
*/
|
|
1883
|
-
calculateFocusDimensions(t,
|
|
1884
|
-
const o = this.normalizeScalePercent(this.config.scalePercent), a =
|
|
1883
|
+
calculateFocusDimensions(t, i, e) {
|
|
1884
|
+
const o = this.normalizeScalePercent(this.config.scalePercent), a = e.height * o, r = t / i;
|
|
1885
1885
|
let s = a, h = s * r;
|
|
1886
|
-
const c =
|
|
1886
|
+
const c = e.width * o;
|
|
1887
1887
|
return h > c && (h = c, s = h / r), { width: h, height: s };
|
|
1888
1888
|
}
|
|
1889
1889
|
/**
|
|
1890
1890
|
* Calculate the transform needed to center an image (position only, no scale)
|
|
1891
1891
|
* Scale is handled by animating actual dimensions for sharper rendering
|
|
1892
1892
|
*/
|
|
1893
|
-
calculateFocusTransform(t,
|
|
1894
|
-
const
|
|
1893
|
+
calculateFocusTransform(t, i) {
|
|
1894
|
+
const e = t.width / 2, o = t.height / 2, a = e - i.x, r = o - i.y;
|
|
1895
1895
|
return {
|
|
1896
1896
|
x: a,
|
|
1897
1897
|
y: r,
|
|
@@ -1904,19 +1904,19 @@ class Ie {
|
|
|
1904
1904
|
* Build transform string for dimension-based zoom (no scale in transform)
|
|
1905
1905
|
*/
|
|
1906
1906
|
buildDimensionZoomTransform(t) {
|
|
1907
|
-
const
|
|
1907
|
+
const i = ["translate(-50%, -50%)"];
|
|
1908
1908
|
if (t.x !== void 0 || t.y !== void 0) {
|
|
1909
|
-
const
|
|
1910
|
-
|
|
1909
|
+
const e = t.x ?? 0, o = t.y ?? 0;
|
|
1910
|
+
i.push(`translate(${e}px, ${o}px)`);
|
|
1911
1911
|
}
|
|
1912
|
-
return t.rotation !== void 0 &&
|
|
1912
|
+
return t.rotation !== void 0 && i.push(`rotate(${t.rotation}deg)`), i.join(" ");
|
|
1913
1913
|
}
|
|
1914
1914
|
/**
|
|
1915
1915
|
* Create a Web Animation that animates both transform (position) and dimensions
|
|
1916
1916
|
* This provides sharper zoom by re-rendering at target size instead of scaling pixels
|
|
1917
1917
|
*/
|
|
1918
|
-
animateWithDimensions(t,
|
|
1919
|
-
const c = this.buildDimensionZoomTransform(
|
|
1918
|
+
animateWithDimensions(t, i, e, o, a, r, s, h) {
|
|
1919
|
+
const c = this.buildDimensionZoomTransform(i), d = this.buildDimensionZoomTransform(e);
|
|
1920
1920
|
return t.style.transition = "none", t.animate(
|
|
1921
1921
|
[
|
|
1922
1922
|
{
|
|
@@ -1939,28 +1939,34 @@ class Ie {
|
|
|
1939
1939
|
}
|
|
1940
1940
|
/**
|
|
1941
1941
|
* Apply focused styling to an element
|
|
1942
|
-
* Applies
|
|
1942
|
+
* Applies all focused styling properties, classes, and z-index
|
|
1943
1943
|
*/
|
|
1944
|
-
applyFocusedStyling(t,
|
|
1945
|
-
t.style.zIndex = String(
|
|
1944
|
+
applyFocusedStyling(t, i) {
|
|
1945
|
+
if (t.style.zIndex = String(i), t.classList.add("fbn-ic-focused"), ot(t, this.focusedClassName), this.styling?.focused) {
|
|
1946
|
+
const e = tt(this.styling.focused, t.offsetHeight, t.offsetWidth);
|
|
1947
|
+
e.borderRadius !== void 0 && (t.style.borderRadius = e.borderRadius), e.borderTopLeftRadius !== void 0 && (t.style.borderTopLeftRadius = e.borderTopLeftRadius), e.borderTopRightRadius !== void 0 && (t.style.borderTopRightRadius = e.borderTopRightRadius), e.borderBottomRightRadius !== void 0 && (t.style.borderBottomRightRadius = e.borderBottomRightRadius), e.borderBottomLeftRadius !== void 0 && (t.style.borderBottomLeftRadius = e.borderBottomLeftRadius), e.border !== void 0 && (t.style.border = e.border), e.borderTop !== void 0 && (t.style.borderTop = e.borderTop), e.borderRight !== void 0 && (t.style.borderRight = e.borderRight), e.borderBottom !== void 0 && (t.style.borderBottom = e.borderBottom), e.borderLeft !== void 0 && (t.style.borderLeft = e.borderLeft), e.boxShadow !== void 0 && (t.style.boxShadow = e.boxShadow), e.filter !== void 0 && (t.style.filter = e.filter), e.opacity !== void 0 && (t.style.opacity = e.opacity), e.cursor !== void 0 && (t.style.cursor = e.cursor), e.outline !== void 0 && (t.style.outline = e.outline), e.outlineOffset !== void 0 && (t.style.outlineOffset = e.outlineOffset), e.objectFit !== void 0 && (t.style.objectFit = e.objectFit), e.aspectRatio !== void 0 && (t.style.aspectRatio = e.aspectRatio);
|
|
1948
|
+
}
|
|
1946
1949
|
}
|
|
1947
1950
|
/**
|
|
1948
1951
|
* Remove focused styling from an element
|
|
1949
|
-
*
|
|
1952
|
+
* Restores default styling properties, removes classes, and resets z-index
|
|
1950
1953
|
*/
|
|
1951
|
-
removeFocusedStyling(t,
|
|
1952
|
-
t.style.zIndex =
|
|
1954
|
+
removeFocusedStyling(t, i) {
|
|
1955
|
+
if (t.style.zIndex = i, t.classList.remove("fbn-ic-focused"), mt(t, this.focusedClassName), this.styling?.default) {
|
|
1956
|
+
const e = tt(this.styling.default, t.offsetHeight, t.offsetWidth);
|
|
1957
|
+
e.borderRadius !== void 0 && (t.style.borderRadius = e.borderRadius), e.borderTopLeftRadius !== void 0 && (t.style.borderTopLeftRadius = e.borderTopLeftRadius), e.borderTopRightRadius !== void 0 && (t.style.borderTopRightRadius = e.borderTopRightRadius), e.borderBottomRightRadius !== void 0 && (t.style.borderBottomRightRadius = e.borderBottomRightRadius), e.borderBottomLeftRadius !== void 0 && (t.style.borderBottomLeftRadius = e.borderBottomLeftRadius), e.border !== void 0 && (t.style.border = e.border), e.borderTop !== void 0 && (t.style.borderTop = e.borderTop), e.borderRight !== void 0 && (t.style.borderRight = e.borderRight), e.borderBottom !== void 0 && (t.style.borderBottom = e.borderBottom), e.borderLeft !== void 0 && (t.style.borderLeft = e.borderLeft), e.boxShadow !== void 0 && (t.style.boxShadow = e.boxShadow), e.filter !== void 0 && (t.style.filter = e.filter), e.opacity !== void 0 && (t.style.opacity = e.opacity), e.cursor !== void 0 && (t.style.cursor = e.cursor), e.outline !== void 0 && (t.style.outline = e.outline), e.outlineOffset !== void 0 && (t.style.outlineOffset = e.outlineOffset), e.objectFit !== void 0 && (t.style.objectFit = e.objectFit), e.aspectRatio !== void 0 && (t.style.aspectRatio = e.aspectRatio);
|
|
1958
|
+
}
|
|
1953
1959
|
}
|
|
1954
1960
|
/**
|
|
1955
1961
|
* Continuously update clip-path during animation based on current element dimensions
|
|
1956
1962
|
* This ensures clip-path changes smoothly as width/height animate
|
|
1957
1963
|
*/
|
|
1958
|
-
startClipPathAnimation(t,
|
|
1959
|
-
let o =
|
|
1960
|
-
|
|
1964
|
+
startClipPathAnimation(t, i, e) {
|
|
1965
|
+
let o = e ? this.styling?.focused ?? this.styling?.default : this.styling?.default;
|
|
1966
|
+
e && this.styling?.focused && this.styling.focused.clipPath === void 0 && (o = { ...o, clipPath: void 0 });
|
|
1961
1967
|
const a = () => {
|
|
1962
|
-
const r = t.offsetHeight, s = t.offsetWidth, h =
|
|
1963
|
-
h.clipPath !== void 0 ? t.style.clipPath = h.clipPath : t.style.clipPath = "unset", h.overflow !== void 0 && (t.style.overflow = h.overflow),
|
|
1968
|
+
const r = t.offsetHeight, s = t.offsetWidth, h = tt(o, r, s);
|
|
1969
|
+
h.clipPath !== void 0 ? t.style.clipPath = h.clipPath : t.style.clipPath = "unset", h.overflow !== void 0 && (t.style.overflow = h.overflow), i.animation.playState === "running" && requestAnimationFrame(a);
|
|
1964
1970
|
};
|
|
1965
1971
|
requestAnimationFrame(a);
|
|
1966
1972
|
}
|
|
@@ -1970,15 +1976,15 @@ class Ie {
|
|
|
1970
1976
|
* @param fromTransform - Optional starting transform (for mid-animation reversals)
|
|
1971
1977
|
* @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
|
|
1972
1978
|
*/
|
|
1973
|
-
startFocusAnimation(t,
|
|
1974
|
-
const r = t.style.zIndex || "", s = t.offsetWidth, h = t.offsetHeight, c = this.calculateFocusDimensions(s, h,
|
|
1979
|
+
startFocusAnimation(t, i, e, o, a) {
|
|
1980
|
+
const r = t.style.zIndex || "", s = t.offsetWidth, h = t.offsetHeight, c = this.calculateFocusDimensions(s, h, i), d = this.calculateFocusTransform(i, e);
|
|
1975
1981
|
this.animationEngine.cancelAllAnimations(t);
|
|
1976
1982
|
const l = this.config.animationDuration ?? 600;
|
|
1977
|
-
this.applyFocusedStyling(t,
|
|
1983
|
+
this.applyFocusedStyling(t, Ct.FOCUSING);
|
|
1978
1984
|
const u = o ?? {
|
|
1979
1985
|
x: 0,
|
|
1980
1986
|
y: 0,
|
|
1981
|
-
rotation:
|
|
1987
|
+
rotation: e.rotation,
|
|
1982
1988
|
scale: 1
|
|
1983
1989
|
// No scale - using dimensions
|
|
1984
1990
|
}, g = a?.width ?? s, p = a?.height ?? h, b = this.animateWithDimensions(
|
|
@@ -2001,7 +2007,7 @@ class Ie {
|
|
|
2001
2007
|
};
|
|
2002
2008
|
return this.focusData = {
|
|
2003
2009
|
element: t,
|
|
2004
|
-
originalState:
|
|
2010
|
+
originalState: e,
|
|
2005
2011
|
focusTransform: d,
|
|
2006
2012
|
originalZIndex: r,
|
|
2007
2013
|
originalWidth: s,
|
|
@@ -2010,7 +2016,7 @@ class Ie {
|
|
|
2010
2016
|
focusHeight: c.height
|
|
2011
2017
|
}, this.startClipPathAnimation(t, f, !0), {
|
|
2012
2018
|
element: t,
|
|
2013
|
-
originalState:
|
|
2019
|
+
originalState: e,
|
|
2014
2020
|
animationHandle: f,
|
|
2015
2021
|
direction: "in",
|
|
2016
2022
|
originalWidth: s,
|
|
@@ -2022,14 +2028,14 @@ class Ie {
|
|
|
2022
2028
|
* Animates back to original dimensions for consistent behavior
|
|
2023
2029
|
* @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
|
|
2024
2030
|
*/
|
|
2025
|
-
startUnfocusAnimation(t,
|
|
2026
|
-
t.style.zIndex = String(
|
|
2031
|
+
startUnfocusAnimation(t, i, e, o) {
|
|
2032
|
+
t.style.zIndex = String(Ct.UNFOCUSING), this.animationEngine.cancelAllAnimations(t);
|
|
2027
2033
|
const a = this.config.animationDuration ?? 600;
|
|
2028
|
-
t.classList.remove("fbn-ic-focused"),
|
|
2029
|
-
const r =
|
|
2034
|
+
t.classList.remove("fbn-ic-focused"), mt(t, this.focusedClassName);
|
|
2035
|
+
const r = e ?? this.focusData?.focusTransform ?? { x: 0, y: 0, rotation: 0, scale: 1 }, s = o?.width ?? this.focusData?.focusWidth ?? t.offsetWidth, h = o?.height ?? this.focusData?.focusHeight ?? t.offsetHeight, c = {
|
|
2030
2036
|
x: 0,
|
|
2031
2037
|
y: 0,
|
|
2032
|
-
rotation:
|
|
2038
|
+
rotation: i.rotation,
|
|
2033
2039
|
scale: 1
|
|
2034
2040
|
// No scale - using dimensions
|
|
2035
2041
|
}, d = this.focusData?.originalWidth ?? t.offsetWidth, l = this.focusData?.originalHeight ?? t.offsetHeight, u = this.animateWithDimensions(
|
|
@@ -2052,7 +2058,7 @@ class Ie {
|
|
|
2052
2058
|
};
|
|
2053
2059
|
return this.startClipPathAnimation(t, g, !1), {
|
|
2054
2060
|
element: t,
|
|
2055
|
-
originalState:
|
|
2061
|
+
originalState: i,
|
|
2056
2062
|
animationHandle: g,
|
|
2057
2063
|
direction: "out",
|
|
2058
2064
|
originalWidth: d,
|
|
@@ -2074,7 +2080,7 @@ class Ie {
|
|
|
2074
2080
|
* Caller is responsible for calling animationEngine.cancelAllAnimations() afterwards.
|
|
2075
2081
|
*/
|
|
2076
2082
|
captureMidAnimationState(t) {
|
|
2077
|
-
const
|
|
2083
|
+
const i = getComputedStyle(t), e = new DOMMatrix(i.transform), o = t.offsetWidth, a = t.offsetHeight, r = e.e + o * 0.5, s = e.f + a * 0.5, h = Math.atan2(e.b, e.a) * (180 / Math.PI);
|
|
2078
2084
|
return t.style.width = `${o}px`, t.style.height = `${a}px`, t.style.transform = `translate(-50%, -50%) translate(${r}px, ${s}px) rotate(${h}deg)`, t.style.transition = "none", {
|
|
2079
2085
|
transform: { x: r, y: s, rotation: h, scale: 1 },
|
|
2080
2086
|
dimensions: { width: o, height: a }
|
|
@@ -2092,63 +2098,63 @@ class Ie {
|
|
|
2092
2098
|
/**
|
|
2093
2099
|
* Reset an element instantly to its original position and dimensions (no animation)
|
|
2094
2100
|
*/
|
|
2095
|
-
resetElementInstantly(t,
|
|
2101
|
+
resetElementInstantly(t, i, e, o, a) {
|
|
2096
2102
|
this.animationEngine.cancelAllAnimations(t);
|
|
2097
2103
|
const r = ["translate(-50%, -50%)"];
|
|
2098
|
-
r.push("translate(0px, 0px)"), r.push(`rotate(${
|
|
2104
|
+
r.push("translate(0px, 0px)"), r.push(`rotate(${i.rotation}deg)`), t.style.transition = "none", t.style.transform = r.join(" "), o !== void 0 && a !== void 0 && (t.style.width = `${o}px`, t.style.height = `${a}px`), this.removeFocusedStyling(t, e);
|
|
2099
2105
|
}
|
|
2100
2106
|
/**
|
|
2101
2107
|
* Focus (zoom) an image to center of container
|
|
2102
2108
|
* Implements cross-animation when swapping focus
|
|
2103
2109
|
*/
|
|
2104
|
-
async focusImage(t,
|
|
2105
|
-
if (this.currentFocus === t && this.state ===
|
|
2110
|
+
async focusImage(t, i, e) {
|
|
2111
|
+
if (this.currentFocus === t && this.state === R.FOCUSED)
|
|
2106
2112
|
return this.unfocusImage();
|
|
2107
|
-
if (this.incoming?.element === t && this.state ===
|
|
2113
|
+
if (this.incoming?.element === t && this.state === R.FOCUSING) {
|
|
2108
2114
|
const { transform: a, dimensions: r } = this.captureMidAnimationState(t);
|
|
2109
2115
|
this.animationEngine.cancelAllAnimations(t), this.outgoing = this.startUnfocusAnimation(
|
|
2110
2116
|
t,
|
|
2111
2117
|
this.incoming.originalState,
|
|
2112
2118
|
a,
|
|
2113
2119
|
r
|
|
2114
|
-
), this.incoming = null, this.state =
|
|
2120
|
+
), this.incoming = null, this.state = R.UNFOCUSING, await this.waitForAnimation(this.outgoing.animationHandle), this.removeFocusedStyling(this.outgoing.element, this.focusData?.originalZIndex || ""), this.outgoing = null, this.currentFocus = null, this.focusData = null, this.state = R.IDLE;
|
|
2115
2121
|
return;
|
|
2116
2122
|
}
|
|
2117
2123
|
const o = ++this.focusGeneration;
|
|
2118
2124
|
switch (this.state) {
|
|
2119
|
-
case
|
|
2120
|
-
if (this.state =
|
|
2121
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2125
|
+
case R.IDLE:
|
|
2126
|
+
if (this.state = R.FOCUSING, this.incoming = this.startFocusAnimation(t, i, e), await this.waitForAnimation(this.incoming.animationHandle), this.focusGeneration !== o) return;
|
|
2127
|
+
this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2122
2128
|
break;
|
|
2123
|
-
case
|
|
2124
|
-
if (this.state =
|
|
2129
|
+
case R.FOCUSED:
|
|
2130
|
+
if (this.state = R.CROSS_ANIMATING, this.currentFocus && this.focusData && (this.outgoing = this.startUnfocusAnimation(
|
|
2125
2131
|
this.currentFocus,
|
|
2126
2132
|
this.focusData.originalState
|
|
2127
|
-
)), this.incoming = this.startFocusAnimation(t,
|
|
2133
|
+
)), this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2128
2134
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2129
2135
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2130
2136
|
]), this.focusGeneration !== o)
|
|
2131
2137
|
return;
|
|
2132
|
-
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state =
|
|
2138
|
+
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2133
2139
|
break;
|
|
2134
|
-
case
|
|
2140
|
+
case R.FOCUSING:
|
|
2135
2141
|
if (this.incoming && (this.animationEngine.cancelAnimation(this.incoming.animationHandle, !1), this.resetElementInstantly(
|
|
2136
2142
|
this.incoming.element,
|
|
2137
2143
|
this.incoming.originalState,
|
|
2138
2144
|
this.focusData?.originalZIndex || "",
|
|
2139
2145
|
this.focusData?.originalWidth,
|
|
2140
2146
|
this.focusData?.originalHeight
|
|
2141
|
-
), this.incoming = null), this.incoming = this.startFocusAnimation(t,
|
|
2142
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2147
|
+
), this.incoming = null), this.incoming = this.startFocusAnimation(t, i, e), await this.waitForAnimation(this.incoming.animationHandle), this.focusGeneration !== o) return;
|
|
2148
|
+
this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2143
2149
|
break;
|
|
2144
|
-
case
|
|
2145
|
-
if (this.state =
|
|
2150
|
+
case R.UNFOCUSING:
|
|
2151
|
+
if (this.state = R.CROSS_ANIMATING, this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2146
2152
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2147
2153
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2148
2154
|
]), this.focusGeneration !== o) return;
|
|
2149
|
-
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state =
|
|
2155
|
+
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2150
2156
|
break;
|
|
2151
|
-
case
|
|
2157
|
+
case R.CROSS_ANIMATING:
|
|
2152
2158
|
if (this.incoming?.element === t)
|
|
2153
2159
|
return;
|
|
2154
2160
|
if (this.outgoing?.element === t) {
|
|
@@ -2163,11 +2169,11 @@ class Ie {
|
|
|
2163
2169
|
);
|
|
2164
2170
|
} else
|
|
2165
2171
|
this.outgoing = null;
|
|
2166
|
-
if (this.incoming = this.startFocusAnimation(t,
|
|
2172
|
+
if (this.incoming = this.startFocusAnimation(t, i, e, a, r), await Promise.all([
|
|
2167
2173
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2168
2174
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2169
2175
|
]), this.focusGeneration !== o) return;
|
|
2170
|
-
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state =
|
|
2176
|
+
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2171
2177
|
return;
|
|
2172
2178
|
}
|
|
2173
2179
|
if (this.outgoing && (this.animationEngine.cancelAnimation(this.outgoing.animationHandle, !1), this.resetElementInstantly(
|
|
@@ -2185,11 +2191,11 @@ class Ie {
|
|
|
2185
2191
|
r
|
|
2186
2192
|
);
|
|
2187
2193
|
}
|
|
2188
|
-
if (this.incoming = this.startFocusAnimation(t,
|
|
2194
|
+
if (this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2189
2195
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2190
2196
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2191
2197
|
]), this.focusGeneration !== o) return;
|
|
2192
|
-
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state =
|
|
2198
|
+
this.outgoing && (this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null), this.currentFocus = t, this.incoming = null, this.state = R.FOCUSED;
|
|
2193
2199
|
break;
|
|
2194
2200
|
}
|
|
2195
2201
|
}
|
|
@@ -2197,23 +2203,23 @@ class Ie {
|
|
|
2197
2203
|
* Unfocus current image, returning it to original position
|
|
2198
2204
|
*/
|
|
2199
2205
|
async unfocusImage() {
|
|
2200
|
-
if (this.state ===
|
|
2206
|
+
if (this.state === R.UNFOCUSING)
|
|
2201
2207
|
return;
|
|
2202
2208
|
const t = ++this.focusGeneration;
|
|
2203
2209
|
if (!this.currentFocus || !this.focusData) {
|
|
2204
|
-
if (this.incoming && this.state ===
|
|
2210
|
+
if (this.incoming && this.state === R.FOCUSING) {
|
|
2205
2211
|
const { transform: a, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2206
2212
|
if (this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2207
2213
|
this.incoming.element,
|
|
2208
2214
|
this.incoming.originalState,
|
|
2209
2215
|
a,
|
|
2210
2216
|
r
|
|
2211
|
-
), this.incoming = null, this.state =
|
|
2212
|
-
this.removeFocusedStyling(this.outgoing.element, this.focusData?.originalZIndex || ""), this.outgoing = null, this.focusData = null, this.state =
|
|
2217
|
+
), this.incoming = null, this.state = R.UNFOCUSING, await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration !== t) return;
|
|
2218
|
+
this.removeFocusedStyling(this.outgoing.element, this.focusData?.originalZIndex || ""), this.outgoing = null, this.focusData = null, this.state = R.IDLE;
|
|
2213
2219
|
}
|
|
2214
2220
|
return;
|
|
2215
2221
|
}
|
|
2216
|
-
if (this.state ===
|
|
2222
|
+
if (this.state === R.CROSS_ANIMATING && this.incoming) {
|
|
2217
2223
|
const { transform: a, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2218
2224
|
this.animationEngine.cancelAllAnimations(this.incoming.element);
|
|
2219
2225
|
const s = this.startUnfocusAnimation(
|
|
@@ -2226,18 +2232,18 @@ class Ie {
|
|
|
2226
2232
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2227
2233
|
this.waitForAnimation(s.animationHandle)
|
|
2228
2234
|
]), this.focusGeneration !== t) return;
|
|
2229
|
-
this.outgoing && this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.removeFocusedStyling(s.element, this.incoming.originalState.zIndex?.toString() || ""), this.outgoing = null, this.incoming = null, this.currentFocus = null, this.focusData = null, this.state =
|
|
2235
|
+
this.outgoing && this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.removeFocusedStyling(s.element, this.incoming.originalState.zIndex?.toString() || ""), this.outgoing = null, this.incoming = null, this.currentFocus = null, this.focusData = null, this.state = R.IDLE;
|
|
2230
2236
|
return;
|
|
2231
2237
|
}
|
|
2232
|
-
this.state =
|
|
2233
|
-
const
|
|
2234
|
-
this.outgoing = this.startUnfocusAnimation(
|
|
2238
|
+
this.state = R.UNFOCUSING;
|
|
2239
|
+
const i = this.currentFocus, e = this.focusData.originalState, o = this.focusData.originalZIndex;
|
|
2240
|
+
this.outgoing = this.startUnfocusAnimation(i, e), await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration === t && (this.removeFocusedStyling(i, o), this.outgoing = null, this.currentFocus = null, this.focusData = null, this.state = R.IDLE);
|
|
2235
2241
|
}
|
|
2236
2242
|
/**
|
|
2237
2243
|
* Swap focus from current image to a new one (alias for focusImage with cross-animation)
|
|
2238
2244
|
*/
|
|
2239
|
-
async swapFocus(t,
|
|
2240
|
-
return this.focusImage(t,
|
|
2245
|
+
async swapFocus(t, i, e) {
|
|
2246
|
+
return this.focusImage(t, i, e);
|
|
2241
2247
|
}
|
|
2242
2248
|
/**
|
|
2243
2249
|
* Get currently focused image element
|
|
@@ -2249,7 +2255,7 @@ class Ie {
|
|
|
2249
2255
|
* Check if an image is currently focused (stable state)
|
|
2250
2256
|
*/
|
|
2251
2257
|
isFocused(t) {
|
|
2252
|
-
return this.currentFocus === t && this.state ===
|
|
2258
|
+
return this.currentFocus === t && this.state === R.FOCUSED;
|
|
2253
2259
|
}
|
|
2254
2260
|
/**
|
|
2255
2261
|
* Check if an image is the target of current focus animation
|
|
@@ -2270,23 +2276,23 @@ class Ie {
|
|
|
2270
2276
|
* Used during swipe gestures for visual feedback
|
|
2271
2277
|
*/
|
|
2272
2278
|
setDragOffset(t) {
|
|
2273
|
-
if (!this.currentFocus || !this.focusData || this.state !==
|
|
2274
|
-
const
|
|
2275
|
-
o.push(`translate(${a}px, ${r}px)`),
|
|
2279
|
+
if (!this.currentFocus || !this.focusData || this.state !== R.FOCUSED) return;
|
|
2280
|
+
const i = this.currentFocus, e = this.focusData.focusTransform, o = ["translate(-50%, -50%)"], a = (e.x ?? 0) + t, r = e.y ?? 0;
|
|
2281
|
+
o.push(`translate(${a}px, ${r}px)`), e.rotation !== void 0 && o.push(`rotate(${e.rotation}deg)`), i.style.transition = "none", i.style.transform = o.join(" ");
|
|
2276
2282
|
}
|
|
2277
2283
|
/**
|
|
2278
2284
|
* Clear the drag offset, optionally animating back to center
|
|
2279
2285
|
* @param animate - If true, animate back to center; if false, snap instantly
|
|
2280
2286
|
* @param duration - Animation duration in ms (default 150)
|
|
2281
2287
|
*/
|
|
2282
|
-
clearDragOffset(t,
|
|
2283
|
-
if (!this.currentFocus || !this.focusData || this.state !==
|
|
2284
|
-
const
|
|
2288
|
+
clearDragOffset(t, i = 150) {
|
|
2289
|
+
if (!this.currentFocus || !this.focusData || this.state !== R.FOCUSED) return;
|
|
2290
|
+
const e = this.currentFocus, o = this.focusData.focusTransform, a = ["translate(-50%, -50%)"], r = o.x ?? 0, s = o.y ?? 0;
|
|
2285
2291
|
a.push(`translate(${r}px, ${s}px)`), o.rotation !== void 0 && a.push(`rotate(${o.rotation}deg)`);
|
|
2286
2292
|
const h = a.join(" ");
|
|
2287
|
-
t ? (
|
|
2288
|
-
this.currentFocus ===
|
|
2289
|
-
},
|
|
2293
|
+
t ? (e.style.transition = `transform ${i}ms ease-out`, e.style.transform = h, setTimeout(() => {
|
|
2294
|
+
this.currentFocus === e && (e.style.transition = "none");
|
|
2295
|
+
}, i)) : (e.style.transition = "none", e.style.transform = h);
|
|
2290
2296
|
}
|
|
2291
2297
|
/**
|
|
2292
2298
|
* Reset zoom state (cancels all animations)
|
|
@@ -2310,12 +2316,12 @@ class Ie {
|
|
|
2310
2316
|
this.focusData.originalZIndex,
|
|
2311
2317
|
this.focusData.originalWidth,
|
|
2312
2318
|
this.focusData.originalHeight
|
|
2313
|
-
), this.state =
|
|
2319
|
+
), this.state = R.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null;
|
|
2314
2320
|
}
|
|
2315
2321
|
}
|
|
2316
|
-
const
|
|
2317
|
-
constructor(t,
|
|
2318
|
-
this.enabled = !1, this.touchState = null, this.recentTouchTimestamp = 0, this.container = t, this.callbacks =
|
|
2322
|
+
const Ie = 50, Te = 0.5, Ae = 20, Ce = 0.3, Le = 150, Me = 30, st = class st {
|
|
2323
|
+
constructor(t, i) {
|
|
2324
|
+
this.enabled = !1, this.touchState = null, this.recentTouchTimestamp = 0, this.container = t, this.callbacks = i, this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchMove = this.handleTouchMove.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundTouchCancel = this.handleTouchCancel.bind(this);
|
|
2319
2325
|
}
|
|
2320
2326
|
/**
|
|
2321
2327
|
* Start listening for touch events
|
|
@@ -2340,48 +2346,48 @@ const Ae = 50, Ce = 0.5, Te = 20, Re = 0.3, Me = 150, Le = 30, ot = class ot {
|
|
|
2340
2346
|
* Used to prevent click-outside from unfocusing immediately after touch
|
|
2341
2347
|
*/
|
|
2342
2348
|
hadRecentTouch() {
|
|
2343
|
-
return Date.now() - this.recentTouchTimestamp <
|
|
2349
|
+
return Date.now() - this.recentTouchTimestamp < st.TOUCH_CLICK_DELAY;
|
|
2344
2350
|
}
|
|
2345
2351
|
handleTouchStart(t) {
|
|
2346
2352
|
if (t.touches.length !== 1) return;
|
|
2347
2353
|
this.recentTouchTimestamp = Date.now();
|
|
2348
|
-
const
|
|
2354
|
+
const i = t.touches[0];
|
|
2349
2355
|
this.touchState = {
|
|
2350
|
-
startX:
|
|
2351
|
-
startY:
|
|
2356
|
+
startX: i.clientX,
|
|
2357
|
+
startY: i.clientY,
|
|
2352
2358
|
startTime: performance.now(),
|
|
2353
|
-
currentX:
|
|
2359
|
+
currentX: i.clientX,
|
|
2354
2360
|
isDragging: !1,
|
|
2355
2361
|
isHorizontalSwipe: null
|
|
2356
2362
|
};
|
|
2357
2363
|
}
|
|
2358
2364
|
handleTouchMove(t) {
|
|
2359
2365
|
if (!this.touchState || t.touches.length !== 1) return;
|
|
2360
|
-
const
|
|
2361
|
-
if (this.touchState.isHorizontalSwipe === null && Math.sqrt(
|
|
2362
|
-
const s = Math.atan2(Math.abs(o), Math.abs(
|
|
2363
|
-
this.touchState.isHorizontalSwipe = s <=
|
|
2366
|
+
const i = t.touches[0], e = i.clientX - this.touchState.startX, o = i.clientY - this.touchState.startY;
|
|
2367
|
+
if (this.touchState.isHorizontalSwipe === null && Math.sqrt(e * e + o * o) > 10) {
|
|
2368
|
+
const s = Math.atan2(Math.abs(o), Math.abs(e)) * (180 / Math.PI);
|
|
2369
|
+
this.touchState.isHorizontalSwipe = s <= Me;
|
|
2364
2370
|
}
|
|
2365
2371
|
if (this.touchState.isHorizontalSwipe !== !1 && this.touchState.isHorizontalSwipe === !0) {
|
|
2366
|
-
t.preventDefault(), this.touchState.isDragging = !0, this.touchState.currentX =
|
|
2367
|
-
const a =
|
|
2372
|
+
t.preventDefault(), this.touchState.isDragging = !0, this.touchState.currentX = i.clientX;
|
|
2373
|
+
const a = e * Ce;
|
|
2368
2374
|
this.callbacks.onDragOffset(a);
|
|
2369
2375
|
}
|
|
2370
2376
|
}
|
|
2371
2377
|
handleTouchEnd(t) {
|
|
2372
2378
|
if (!this.touchState) return;
|
|
2373
2379
|
this.recentTouchTimestamp = Date.now();
|
|
2374
|
-
const
|
|
2380
|
+
const i = this.touchState.currentX - this.touchState.startX, e = performance.now() - this.touchState.startTime, o = Math.abs(i) / e, a = Math.abs(i);
|
|
2375
2381
|
let r = !1;
|
|
2376
|
-
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (a >=
|
|
2382
|
+
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (a >= Ie || o >= Te && a >= Ae) && (r = !0, i < 0 ? this.callbacks.onNext() : this.callbacks.onPrev()), this.touchState.isDragging && this.callbacks.onDragEnd(r), this.touchState = null;
|
|
2377
2383
|
}
|
|
2378
2384
|
handleTouchCancel(t) {
|
|
2379
2385
|
this.touchState?.isDragging && this.callbacks.onDragEnd(!1), this.touchState = null;
|
|
2380
2386
|
}
|
|
2381
2387
|
};
|
|
2382
|
-
|
|
2383
|
-
let
|
|
2384
|
-
class
|
|
2388
|
+
st.TOUCH_CLICK_DELAY = 300;
|
|
2389
|
+
let pt = st;
|
|
2390
|
+
class Fe {
|
|
2385
2391
|
constructor(t) {
|
|
2386
2392
|
if (this._prepared = !1, this._discoveredUrls = [], this.apiKey = t.apiKey ?? "", this.apiEndpoint = t.apiEndpoint ?? "https://www.googleapis.com/drive/v3/files", this.debugLogging = t.debugLogging ?? !1, this.sources = t.sources ?? [], !this.sources || this.sources.length === 0)
|
|
2387
2393
|
throw new Error("GoogleDriveLoader requires at least one source to be configured");
|
|
@@ -2392,15 +2398,15 @@ class ze {
|
|
|
2392
2398
|
*/
|
|
2393
2399
|
async prepare(t) {
|
|
2394
2400
|
this._discoveredUrls = [];
|
|
2395
|
-
for (const
|
|
2396
|
-
if ("folders" in
|
|
2397
|
-
for (const
|
|
2398
|
-
const o =
|
|
2401
|
+
for (const i of this.sources)
|
|
2402
|
+
if ("folders" in i)
|
|
2403
|
+
for (const e of i.folders) {
|
|
2404
|
+
const o = i.recursive !== void 0 ? i.recursive : !0, a = await this.loadFromFolder(e, t, o);
|
|
2399
2405
|
this._discoveredUrls.push(...a);
|
|
2400
2406
|
}
|
|
2401
|
-
else if ("files" in
|
|
2402
|
-
const
|
|
2403
|
-
this._discoveredUrls.push(...
|
|
2407
|
+
else if ("files" in i) {
|
|
2408
|
+
const e = await this.loadFiles(i.files, t);
|
|
2409
|
+
this._discoveredUrls.push(...e);
|
|
2404
2410
|
}
|
|
2405
2411
|
this._prepared = !0;
|
|
2406
2412
|
}
|
|
@@ -2434,14 +2440,14 @@ class ze {
|
|
|
2434
2440
|
* @returns Folder ID or null if invalid
|
|
2435
2441
|
*/
|
|
2436
2442
|
extractFolderId(t) {
|
|
2437
|
-
const
|
|
2443
|
+
const i = [
|
|
2438
2444
|
/\/folders\/([a-zA-Z0-9_-]+)/,
|
|
2439
2445
|
// Standard format
|
|
2440
2446
|
/id=([a-zA-Z0-9_-]+)/
|
|
2441
2447
|
// Alternative format
|
|
2442
2448
|
];
|
|
2443
|
-
for (const
|
|
2444
|
-
const o = t.match(
|
|
2449
|
+
for (const e of i) {
|
|
2450
|
+
const o = t.match(e);
|
|
2445
2451
|
if (o && o[1])
|
|
2446
2452
|
return o[1];
|
|
2447
2453
|
}
|
|
@@ -2454,16 +2460,16 @@ class ze {
|
|
|
2454
2460
|
* @param recursive - Whether to include images from subfolders
|
|
2455
2461
|
* @returns Promise resolving to array of image URLs
|
|
2456
2462
|
*/
|
|
2457
|
-
async loadFromFolder(t,
|
|
2463
|
+
async loadFromFolder(t, i, e = !0) {
|
|
2458
2464
|
const o = this.extractFolderId(t);
|
|
2459
2465
|
if (!o)
|
|
2460
2466
|
throw new Error("Invalid Google Drive folder URL. Please check the URL format.");
|
|
2461
2467
|
if (!this.apiKey || this.apiKey === "YOUR_API_KEY_HERE")
|
|
2462
|
-
return this.loadImagesDirectly(o,
|
|
2468
|
+
return this.loadImagesDirectly(o, i);
|
|
2463
2469
|
try {
|
|
2464
|
-
return
|
|
2470
|
+
return e ? await this.loadImagesRecursively(o, i) : await this.loadImagesFromSingleFolder(o, i);
|
|
2465
2471
|
} catch (a) {
|
|
2466
|
-
return console.error("Error loading from Google Drive API:", a), this.loadImagesDirectly(o,
|
|
2472
|
+
return console.error("Error loading from Google Drive API:", a), this.loadImagesDirectly(o, i);
|
|
2467
2473
|
}
|
|
2468
2474
|
}
|
|
2469
2475
|
/**
|
|
@@ -2472,16 +2478,16 @@ class ze {
|
|
|
2472
2478
|
* @param filter - Filter to apply to discovered images
|
|
2473
2479
|
* @returns Promise resolving to array of image URLs
|
|
2474
2480
|
*/
|
|
2475
|
-
async loadImagesFromSingleFolder(t,
|
|
2476
|
-
const
|
|
2481
|
+
async loadImagesFromSingleFolder(t, i) {
|
|
2482
|
+
const e = [], o = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(o)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, s = await fetch(r);
|
|
2477
2483
|
if (!s.ok)
|
|
2478
2484
|
throw new Error(`API request failed: ${s.status} ${s.statusText}`);
|
|
2479
2485
|
const c = (await s.json()).files.filter(
|
|
2480
|
-
(d) => d.mimeType.startsWith("image/") &&
|
|
2486
|
+
(d) => d.mimeType.startsWith("image/") && i.isAllowed(d.name)
|
|
2481
2487
|
);
|
|
2482
2488
|
return this.log(`Found ${c.length} images in folder ${t} (non-recursive)`), c.forEach((d) => {
|
|
2483
|
-
|
|
2484
|
-
}),
|
|
2489
|
+
e.push(`https://lh3.googleusercontent.com/d/${d.id}=s1600`), this.log(`Added file: ${d.name}`);
|
|
2490
|
+
}), e;
|
|
2485
2491
|
}
|
|
2486
2492
|
/**
|
|
2487
2493
|
* Load specific files by their URLs or IDs
|
|
@@ -2489,8 +2495,8 @@ class ze {
|
|
|
2489
2495
|
* @param filter - Filter to apply to discovered images
|
|
2490
2496
|
* @returns Promise resolving to array of image URLs
|
|
2491
2497
|
*/
|
|
2492
|
-
async loadFiles(t,
|
|
2493
|
-
const
|
|
2498
|
+
async loadFiles(t, i) {
|
|
2499
|
+
const e = [];
|
|
2494
2500
|
for (const o of t) {
|
|
2495
2501
|
const a = this.extractFileId(o);
|
|
2496
2502
|
if (!a) {
|
|
@@ -2502,16 +2508,16 @@ class ze {
|
|
|
2502
2508
|
const r = `${this.apiEndpoint}/${a}?fields=name,mimeType&key=${this.apiKey}`, s = await fetch(r);
|
|
2503
2509
|
if (s.ok) {
|
|
2504
2510
|
const h = await s.json();
|
|
2505
|
-
h.mimeType.startsWith("image/") &&
|
|
2511
|
+
h.mimeType.startsWith("image/") && i.isAllowed(h.name) ? (e.push(`https://lh3.googleusercontent.com/d/${a}=s1600`), this.log(`Added file: ${h.name}`)) : this.log(`Skipping non-image file: ${h.name} (${h.mimeType})`);
|
|
2506
2512
|
} else
|
|
2507
2513
|
this.log(`Failed to fetch metadata for file ${a}: ${s.status}`);
|
|
2508
2514
|
} catch (r) {
|
|
2509
2515
|
this.log(`Error fetching metadata for file ${a}:`, r);
|
|
2510
2516
|
}
|
|
2511
2517
|
else
|
|
2512
|
-
|
|
2518
|
+
e.push(`https://lh3.googleusercontent.com/d/${a}=s1600`);
|
|
2513
2519
|
}
|
|
2514
|
-
return
|
|
2520
|
+
return e;
|
|
2515
2521
|
}
|
|
2516
2522
|
/**
|
|
2517
2523
|
* Extract file ID from Google Drive file URL
|
|
@@ -2521,7 +2527,7 @@ class ze {
|
|
|
2521
2527
|
extractFileId(t) {
|
|
2522
2528
|
if (!/[/:.]/.test(t))
|
|
2523
2529
|
return t;
|
|
2524
|
-
const
|
|
2530
|
+
const i = [
|
|
2525
2531
|
/\/file\/d\/([a-zA-Z0-9_-]+)/,
|
|
2526
2532
|
// Standard file format
|
|
2527
2533
|
/\/open\?id=([a-zA-Z0-9_-]+)/,
|
|
@@ -2529,8 +2535,8 @@ class ze {
|
|
|
2529
2535
|
/id=([a-zA-Z0-9_-]+)/
|
|
2530
2536
|
// Generic id parameter
|
|
2531
2537
|
];
|
|
2532
|
-
for (const
|
|
2533
|
-
const o = t.match(
|
|
2538
|
+
for (const e of i) {
|
|
2539
|
+
const o = t.match(e);
|
|
2534
2540
|
if (o && o[1])
|
|
2535
2541
|
return o[1];
|
|
2536
2542
|
}
|
|
@@ -2542,24 +2548,24 @@ class ze {
|
|
|
2542
2548
|
* @param filter - Filter to apply to discovered images
|
|
2543
2549
|
* @returns Promise resolving to array of image URLs
|
|
2544
2550
|
*/
|
|
2545
|
-
async loadImagesRecursively(t,
|
|
2546
|
-
const
|
|
2551
|
+
async loadImagesRecursively(t, i) {
|
|
2552
|
+
const e = [], o = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(o)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, s = await fetch(r);
|
|
2547
2553
|
if (!s.ok)
|
|
2548
2554
|
throw new Error(`API request failed: ${s.status} ${s.statusText}`);
|
|
2549
2555
|
const h = await s.json(), c = h.files.filter(
|
|
2550
|
-
(l) => l.mimeType.startsWith("image/") &&
|
|
2556
|
+
(l) => l.mimeType.startsWith("image/") && i.isAllowed(l.name)
|
|
2551
2557
|
), d = h.files.filter(
|
|
2552
2558
|
(l) => l.mimeType === "application/vnd.google-apps.folder"
|
|
2553
2559
|
);
|
|
2554
2560
|
this.log(`Found ${h.files.length} total items in folder ${t}`), h.files.forEach((l) => this.log(` - File: ${l.name} (${l.mimeType})`)), this.log(`- ${c.length} valid files (images only)`), this.log(`- ${d.length} subfolders`), c.forEach((l) => {
|
|
2555
|
-
|
|
2561
|
+
e.push(`https://lh3.googleusercontent.com/d/${l.id}=s1600`), this.log(`Added file: ${l.name}`);
|
|
2556
2562
|
});
|
|
2557
2563
|
for (const l of d) {
|
|
2558
2564
|
this.log(`Loading images from subfolder: ${l.name}`);
|
|
2559
|
-
const u = await this.loadImagesRecursively(l.id,
|
|
2560
|
-
|
|
2565
|
+
const u = await this.loadImagesRecursively(l.id, i);
|
|
2566
|
+
e.push(...u);
|
|
2561
2567
|
}
|
|
2562
|
-
return
|
|
2568
|
+
return e;
|
|
2563
2569
|
}
|
|
2564
2570
|
/**
|
|
2565
2571
|
* Direct loading method (no API key required, but less reliable)
|
|
@@ -2568,17 +2574,17 @@ class ze {
|
|
|
2568
2574
|
* @param filter - Filter to apply (not used in fallback mode)
|
|
2569
2575
|
* @returns Promise resolving to array of image URLs
|
|
2570
2576
|
*/
|
|
2571
|
-
async loadImagesDirectly(t,
|
|
2577
|
+
async loadImagesDirectly(t, i) {
|
|
2572
2578
|
try {
|
|
2573
|
-
const
|
|
2579
|
+
const e = `https://drive.google.com/embeddedfolderview?id=${t}`, o = await fetch(e, { mode: "cors" });
|
|
2574
2580
|
if (!o.ok)
|
|
2575
2581
|
throw new Error("Cannot access folder directly (CORS or permissions issue)");
|
|
2576
2582
|
const a = await o.text(), r = /\/file\/d\/([a-zA-Z0-9_-]+)/g, s = [...a.matchAll(r)];
|
|
2577
2583
|
return [...new Set(s.map((d) => d[1]))].map(
|
|
2578
2584
|
(d) => `https://drive.google.com/uc?export=view&id=${d}`
|
|
2579
2585
|
);
|
|
2580
|
-
} catch (
|
|
2581
|
-
throw console.error("Direct loading failed:",
|
|
2586
|
+
} catch (e) {
|
|
2587
|
+
throw console.error("Direct loading failed:", e), new Error(
|
|
2582
2588
|
`Unable to load images. Please ensure:
|
|
2583
2589
|
1. The folder is shared publicly (Anyone with the link can view)
|
|
2584
2590
|
2. The folder contains image files
|
|
@@ -2592,7 +2598,7 @@ class ze {
|
|
|
2592
2598
|
* @returns Array of direct image URLs
|
|
2593
2599
|
*/
|
|
2594
2600
|
manualImageUrls(t) {
|
|
2595
|
-
return t.map((
|
|
2601
|
+
return t.map((i) => `https://drive.google.com/uc?export=view&id=${i}`);
|
|
2596
2602
|
}
|
|
2597
2603
|
/**
|
|
2598
2604
|
* Debug logging helper
|
|
@@ -2602,7 +2608,7 @@ class ze {
|
|
|
2602
2608
|
this.debugLogging && typeof console < "u" && console.log(...t);
|
|
2603
2609
|
}
|
|
2604
2610
|
}
|
|
2605
|
-
class
|
|
2611
|
+
class ze {
|
|
2606
2612
|
constructor(t) {
|
|
2607
2613
|
if (this._prepared = !1, this._discoveredUrls = [], this.validateUrls = t.validateUrls !== !1, this.validationTimeout = t.validationTimeout ?? 5e3, this.validationMethod = t.validationMethod ?? "head", this.debugLogging = t.debugLogging ?? !1, this.sources = t.sources ?? [], !this.sources || this.sources.length === 0)
|
|
2608
2614
|
throw new Error("StaticImageLoader requires at least one source to be configured");
|
|
@@ -2614,12 +2620,12 @@ class Fe {
|
|
|
2614
2620
|
*/
|
|
2615
2621
|
async prepare(t) {
|
|
2616
2622
|
this._discoveredUrls = [], this.log(`Processing ${this.sources.length} source(s)`);
|
|
2617
|
-
for (const
|
|
2623
|
+
for (const i of this.sources)
|
|
2618
2624
|
try {
|
|
2619
|
-
const
|
|
2620
|
-
this._discoveredUrls.push(...
|
|
2621
|
-
} catch (
|
|
2622
|
-
console.warn("Failed to process source:",
|
|
2625
|
+
const e = await this.processSource(i, t);
|
|
2626
|
+
this._discoveredUrls.push(...e);
|
|
2627
|
+
} catch (e) {
|
|
2628
|
+
console.warn("Failed to process source:", i, e);
|
|
2623
2629
|
}
|
|
2624
2630
|
this._prepared = !0, this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);
|
|
2625
2631
|
}
|
|
@@ -2653,8 +2659,8 @@ class Fe {
|
|
|
2653
2659
|
* @param filter - Filter to apply to discovered images
|
|
2654
2660
|
* @returns Promise resolving to array of valid URLs from this source
|
|
2655
2661
|
*/
|
|
2656
|
-
async processSource(t,
|
|
2657
|
-
return t ? "urls" in t ? await this.processUrls(t.urls,
|
|
2662
|
+
async processSource(t, i) {
|
|
2663
|
+
return t ? "urls" in t ? await this.processUrls(t.urls, i) : "path" in t ? await this.processPath(t.path, t.files, i) : "json" in t ? await this.processJson(t.json, i) : (console.warn("Unknown source shape:", t), []) : (console.warn("Invalid source object:", t), []);
|
|
2658
2664
|
}
|
|
2659
2665
|
/**
|
|
2660
2666
|
* Process a list of direct URLs
|
|
@@ -2662,19 +2668,19 @@ class Fe {
|
|
|
2662
2668
|
* @param filter - Filter to apply to discovered images
|
|
2663
2669
|
* @returns Promise resolving to array of validated URLs
|
|
2664
2670
|
*/
|
|
2665
|
-
async processUrls(t,
|
|
2671
|
+
async processUrls(t, i) {
|
|
2666
2672
|
if (!Array.isArray(t))
|
|
2667
2673
|
return console.warn("URLs must be an array:", t), [];
|
|
2668
|
-
const
|
|
2674
|
+
const e = [];
|
|
2669
2675
|
for (const o of t) {
|
|
2670
2676
|
const a = o.split("/").pop() || o;
|
|
2671
|
-
if (!
|
|
2677
|
+
if (!i.isAllowed(a)) {
|
|
2672
2678
|
this.log(`Skipping filtered URL: ${o}`);
|
|
2673
2679
|
continue;
|
|
2674
2680
|
}
|
|
2675
|
-
this.validateUrls ? await this.validateUrl(o) ?
|
|
2681
|
+
this.validateUrls ? await this.validateUrl(o) ? e.push(o) : console.warn(`Skipping invalid/missing URL: ${o}`) : e.push(o);
|
|
2676
2682
|
}
|
|
2677
|
-
return
|
|
2683
|
+
return e;
|
|
2678
2684
|
}
|
|
2679
2685
|
/**
|
|
2680
2686
|
* Process a path-based source
|
|
@@ -2683,12 +2689,12 @@ class Fe {
|
|
|
2683
2689
|
* @param filter - Filter to apply to discovered images
|
|
2684
2690
|
* @returns Promise resolving to array of validated URLs
|
|
2685
2691
|
*/
|
|
2686
|
-
async processPath(t,
|
|
2687
|
-
if (!Array.isArray(
|
|
2688
|
-
return console.warn("files must be an array:",
|
|
2692
|
+
async processPath(t, i, e) {
|
|
2693
|
+
if (!Array.isArray(i))
|
|
2694
|
+
return console.warn("files must be an array:", i), [];
|
|
2689
2695
|
const o = [];
|
|
2690
|
-
for (const a of
|
|
2691
|
-
if (!
|
|
2696
|
+
for (const a of i) {
|
|
2697
|
+
if (!e.isAllowed(a)) {
|
|
2692
2698
|
this.log(`Skipping filtered file: ${a}`);
|
|
2693
2699
|
continue;
|
|
2694
2700
|
}
|
|
@@ -2704,17 +2710,17 @@ class Fe {
|
|
|
2704
2710
|
* @param filter - Filter to apply to discovered images
|
|
2705
2711
|
* @returns Promise resolving to array of validated URLs
|
|
2706
2712
|
*/
|
|
2707
|
-
async processJson(t,
|
|
2713
|
+
async processJson(t, i) {
|
|
2708
2714
|
this.log(`Fetching JSON endpoint: ${t}`);
|
|
2709
|
-
const
|
|
2715
|
+
const e = new AbortController(), o = setTimeout(() => e.abort(), 1e4);
|
|
2710
2716
|
try {
|
|
2711
|
-
const a = await fetch(t, { signal:
|
|
2717
|
+
const a = await fetch(t, { signal: e.signal });
|
|
2712
2718
|
if (clearTimeout(o), !a.ok)
|
|
2713
2719
|
throw new Error(`HTTP ${a.status} fetching ${t}`);
|
|
2714
2720
|
const r = await a.json();
|
|
2715
2721
|
if (!r || !Array.isArray(r.images))
|
|
2716
2722
|
throw new Error('JSON source must return JSON with shape { "images": ["url1", "url2", ...] }');
|
|
2717
|
-
return this.log(`JSON endpoint returned ${r.images.length} image(s)`), await this.processUrls(r.images,
|
|
2723
|
+
return this.log(`JSON endpoint returned ${r.images.length} image(s)`), await this.processUrls(r.images, i);
|
|
2718
2724
|
} catch (a) {
|
|
2719
2725
|
throw clearTimeout(o), a instanceof Error && a.name === "AbortError" ? new Error(`Timeout fetching JSON endpoint: ${t}`) : a;
|
|
2720
2726
|
}
|
|
@@ -2738,13 +2744,13 @@ class Fe {
|
|
|
2738
2744
|
if (!(t.startsWith(window.location.origin) || t.startsWith("/")))
|
|
2739
2745
|
return this.log(`Skipping validation for cross-origin URL: ${t}`), !0;
|
|
2740
2746
|
try {
|
|
2741
|
-
const
|
|
2747
|
+
const e = new AbortController(), o = setTimeout(() => e.abort(), this.validationTimeout), a = await fetch(t, {
|
|
2742
2748
|
method: "HEAD",
|
|
2743
|
-
signal:
|
|
2749
|
+
signal: e.signal
|
|
2744
2750
|
});
|
|
2745
2751
|
return clearTimeout(o), a.ok ? !0 : (this.log(`Validation failed for ${t}: HTTP ${a.status}`), !1);
|
|
2746
|
-
} catch (
|
|
2747
|
-
return
|
|
2752
|
+
} catch (e) {
|
|
2753
|
+
return e instanceof Error && (e.name === "AbortError" ? this.log(`Validation timeout for ${t}`) : this.log(`Validation failed for ${t}:`, e.message)), !1;
|
|
2748
2754
|
}
|
|
2749
2755
|
}
|
|
2750
2756
|
/**
|
|
@@ -2753,14 +2759,14 @@ class Fe {
|
|
|
2753
2759
|
* @param filename - Filename to append
|
|
2754
2760
|
* @returns Complete URL
|
|
2755
2761
|
*/
|
|
2756
|
-
constructUrl(t,
|
|
2757
|
-
const
|
|
2762
|
+
constructUrl(t, i) {
|
|
2763
|
+
const e = t.replace(/\/$/, "");
|
|
2758
2764
|
if (this.isAbsoluteUrl(t))
|
|
2759
|
-
return `${
|
|
2765
|
+
return `${e}/${i}`;
|
|
2760
2766
|
if (typeof window > "u")
|
|
2761
|
-
return `${
|
|
2767
|
+
return `${e}/${i}`;
|
|
2762
2768
|
const o = window.location.origin, r = (t.startsWith("/") ? t : "/" + t).replace(/\/$/, "");
|
|
2763
|
-
return `${o}${r}/${
|
|
2769
|
+
return `${o}${r}/${i}`;
|
|
2764
2770
|
}
|
|
2765
2771
|
/**
|
|
2766
2772
|
* Check if URL is absolute (contains protocol)
|
|
@@ -2794,15 +2800,15 @@ class Oe {
|
|
|
2794
2800
|
*/
|
|
2795
2801
|
async prepare(t) {
|
|
2796
2802
|
this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);
|
|
2797
|
-
const
|
|
2798
|
-
this.log(`Loader ${o} prepared with ${
|
|
2803
|
+
const i = this.loaders.map((e, o) => e.prepare(t).then(() => {
|
|
2804
|
+
this.log(`Loader ${o} prepared with ${e.imagesLength()} images`);
|
|
2799
2805
|
}).catch((a) => {
|
|
2800
2806
|
console.warn(`Loader ${o} failed to prepare:`, a);
|
|
2801
2807
|
}));
|
|
2802
|
-
await Promise.all(
|
|
2803
|
-
for (const
|
|
2804
|
-
if (
|
|
2805
|
-
const o =
|
|
2808
|
+
await Promise.all(i);
|
|
2809
|
+
for (const e of this.loaders)
|
|
2810
|
+
if (e.isPrepared()) {
|
|
2811
|
+
const o = e.imageURLs();
|
|
2806
2812
|
this._discoveredUrls.push(...o);
|
|
2807
2813
|
}
|
|
2808
2814
|
this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);
|
|
@@ -2861,8 +2867,8 @@ class $e {
|
|
|
2861
2867
|
* @returns True if the file extension is allowed
|
|
2862
2868
|
*/
|
|
2863
2869
|
isAllowed(t) {
|
|
2864
|
-
const
|
|
2865
|
-
return
|
|
2870
|
+
const e = t.split("?")[0].split(".").pop()?.toLowerCase();
|
|
2871
|
+
return e ? this.allowedExtensions.includes(e) : !1;
|
|
2866
2872
|
}
|
|
2867
2873
|
/**
|
|
2868
2874
|
* Get the list of allowed extensions
|
|
@@ -2935,13 +2941,13 @@ function Pe() {
|
|
|
2935
2941
|
}
|
|
2936
2942
|
class _e {
|
|
2937
2943
|
constructor(t = {}) {
|
|
2938
|
-
this.fullConfig = Gt(t), t.container instanceof HTMLElement ? (this.containerRef = t.container, this.containerId = null) : (this.containerRef = null, this.containerId = t.container || "imageCloud"), this.imagesLoaded = !1, this.imageElements = [], this.imageLayouts = [], this.currentImageHeight = 225, this.currentFocusIndex = null, this.hoveredImage = null, this.resizeTimeout = null, this.displayQueue = [], this.queueInterval = null, this.loadGeneration = 0, this.loadingElAutoCreated = !1, this.errorElAutoCreated = !1, this.counterEl = null, this.counterElAutoCreated = !1, this.animationEngine = new
|
|
2944
|
+
this.fullConfig = Gt(t), t.container instanceof HTMLElement ? (this.containerRef = t.container, this.containerId = null) : (this.containerRef = null, this.containerId = t.container || "imageCloud"), this.imagesLoaded = !1, this.imageElements = [], this.imageLayouts = [], this.currentImageHeight = 225, this.currentFocusIndex = null, this.hoveredImage = null, this.resizeTimeout = null, this.displayQueue = [], this.queueInterval = null, this.loadGeneration = 0, this.loadingElAutoCreated = !1, this.errorElAutoCreated = !1, this.counterEl = null, this.counterElAutoCreated = !1, this.animationEngine = new Xt(this.fullConfig.animation), this.layoutEngine = new pe({
|
|
2939
2945
|
layout: this.fullConfig.layout,
|
|
2940
2946
|
image: this.fullConfig.image
|
|
2941
|
-
}), this.zoomEngine = new
|
|
2942
|
-
const
|
|
2947
|
+
}), this.zoomEngine = new Re(this.fullConfig.interaction.focus, this.animationEngine, this.fullConfig.styling), this.defaultStyles = tt(this.fullConfig.styling?.default), this.defaultClassName = this.fullConfig.styling?.default?.className, this.hoverClassName = this.fullConfig.styling?.hover?.className;
|
|
2948
|
+
const i = this.fullConfig.animation.entry || y.animation.entry;
|
|
2943
2949
|
this.entryAnimationEngine = new se(
|
|
2944
|
-
|
|
2950
|
+
i,
|
|
2945
2951
|
this.fullConfig.layout.algorithm
|
|
2946
2952
|
), this.swipeEngine = null, this.imageFilter = this.createImageFilter(), this.imageLoader = this.createLoader(), this.containerEl = null, this.loadingEl = null, this.errorEl = null;
|
|
2947
2953
|
}
|
|
@@ -2957,36 +2963,36 @@ class _e {
|
|
|
2957
2963
|
* Processes loaders array, merges shared config, wraps in CompositeLoader if needed
|
|
2958
2964
|
*/
|
|
2959
2965
|
createLoader() {
|
|
2960
|
-
const t = this.fullConfig.loaders,
|
|
2966
|
+
const t = this.fullConfig.loaders, i = this.fullConfig.config.loaders ?? {};
|
|
2961
2967
|
if (!t || t.length === 0)
|
|
2962
2968
|
throw new Error("No loaders configured. Provide `images`, `loaders`, or both.");
|
|
2963
|
-
const
|
|
2964
|
-
return
|
|
2965
|
-
loaders:
|
|
2969
|
+
const e = t.map((o) => this.createLoaderFromEntry(o, i));
|
|
2970
|
+
return e.length === 1 ? e[0] : new Oe({
|
|
2971
|
+
loaders: e,
|
|
2966
2972
|
debugLogging: this.fullConfig.config.debug?.loaders
|
|
2967
2973
|
});
|
|
2968
2974
|
}
|
|
2969
2975
|
/**
|
|
2970
2976
|
* Create a single loader from a LoaderEntry, merging shared config
|
|
2971
2977
|
*/
|
|
2972
|
-
createLoaderFromEntry(t,
|
|
2978
|
+
createLoaderFromEntry(t, i) {
|
|
2973
2979
|
if ("static" in t) {
|
|
2974
|
-
const
|
|
2975
|
-
...
|
|
2976
|
-
validateUrls:
|
|
2977
|
-
validationTimeout:
|
|
2978
|
-
validationMethod:
|
|
2979
|
-
allowedExtensions:
|
|
2980
|
-
debugLogging:
|
|
2980
|
+
const e = t.static, o = {
|
|
2981
|
+
...e,
|
|
2982
|
+
validateUrls: e.validateUrls ?? i.validateUrls,
|
|
2983
|
+
validationTimeout: e.validationTimeout ?? i.validationTimeout,
|
|
2984
|
+
validationMethod: e.validationMethod ?? i.validationMethod,
|
|
2985
|
+
allowedExtensions: e.allowedExtensions ?? i.allowedExtensions,
|
|
2986
|
+
debugLogging: e.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
2981
2987
|
};
|
|
2982
|
-
return new
|
|
2988
|
+
return new ze(o);
|
|
2983
2989
|
} else if ("googleDrive" in t) {
|
|
2984
|
-
const
|
|
2985
|
-
...
|
|
2986
|
-
allowedExtensions:
|
|
2987
|
-
debugLogging:
|
|
2990
|
+
const e = t.googleDrive, o = {
|
|
2991
|
+
...e,
|
|
2992
|
+
allowedExtensions: e.allowedExtensions ?? i.allowedExtensions,
|
|
2993
|
+
debugLogging: e.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
2988
2994
|
};
|
|
2989
|
-
return new
|
|
2995
|
+
return new Fe(o);
|
|
2990
2996
|
} else
|
|
2991
2997
|
throw new Error(`Unknown loader entry: ${JSON.stringify(t)}`);
|
|
2992
2998
|
}
|
|
@@ -2999,12 +3005,12 @@ class _e {
|
|
|
2999
3005
|
this.containerEl = this.containerRef;
|
|
3000
3006
|
else if (this.containerEl = document.getElementById(this.containerId), !this.containerEl)
|
|
3001
3007
|
throw new Error(`Container #${this.containerId} not found`);
|
|
3002
|
-
this.containerEl.classList.add("fbn-ic-gallery"), this.swipeEngine = new
|
|
3008
|
+
this.containerEl.classList.add("fbn-ic-gallery"), this.swipeEngine = new pt(this.containerEl, {
|
|
3003
3009
|
onNext: () => this.navigateToNextImage(),
|
|
3004
3010
|
onPrev: () => this.navigateToPreviousImage(),
|
|
3005
3011
|
onDragOffset: (t) => this.zoomEngine.setDragOffset(t),
|
|
3006
3012
|
onDragEnd: (t) => {
|
|
3007
|
-
t ? this.zoomEngine.clearDragOffset(!1) : this.zoomEngine.clearDragOffset(!0,
|
|
3013
|
+
t ? this.zoomEngine.clearDragOffset(!1) : this.zoomEngine.clearDragOffset(!0, Le);
|
|
3008
3014
|
}
|
|
3009
3015
|
}), this.setupUI(), this.setupEventListeners(), this.logDebug("ImageCloud initialized"), await this.loadImages();
|
|
3010
3016
|
} catch (t) {
|
|
@@ -3021,10 +3027,10 @@ class _e {
|
|
|
3021
3027
|
createDefaultLoadingElement() {
|
|
3022
3028
|
const t = document.createElement("div");
|
|
3023
3029
|
t.className = "fbn-ic-loading fbn-ic-hidden";
|
|
3024
|
-
const
|
|
3025
|
-
|
|
3026
|
-
const
|
|
3027
|
-
return
|
|
3030
|
+
const i = document.createElement("div");
|
|
3031
|
+
i.className = "fbn-ic-spinner", t.appendChild(i);
|
|
3032
|
+
const e = document.createElement("p");
|
|
3033
|
+
return e.textContent = "Loading images...", t.appendChild(e), this.containerEl.appendChild(t), t;
|
|
3028
3034
|
}
|
|
3029
3035
|
createDefaultErrorElement() {
|
|
3030
3036
|
const t = document.createElement("div");
|
|
@@ -3046,24 +3052,24 @@ class _e {
|
|
|
3046
3052
|
*/
|
|
3047
3053
|
navigateToNextImage() {
|
|
3048
3054
|
if (this.currentFocusIndex === null || this.imageElements.length === 0) return;
|
|
3049
|
-
const t = (this.currentFocusIndex + 1) % this.imageLayouts.length,
|
|
3055
|
+
const t = (this.currentFocusIndex + 1) % this.imageLayouts.length, i = this.imageElements.find(
|
|
3050
3056
|
(o) => o.dataset.imageId === String(t)
|
|
3051
3057
|
);
|
|
3052
|
-
if (!
|
|
3053
|
-
const
|
|
3054
|
-
|
|
3058
|
+
if (!i) return;
|
|
3059
|
+
const e = this.imageLayouts[t];
|
|
3060
|
+
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t));
|
|
3055
3061
|
}
|
|
3056
3062
|
/**
|
|
3057
3063
|
* Navigate to the previous image (Left arrow)
|
|
3058
3064
|
*/
|
|
3059
3065
|
navigateToPreviousImage() {
|
|
3060
3066
|
if (this.currentFocusIndex === null || this.imageElements.length === 0) return;
|
|
3061
|
-
const t = (this.currentFocusIndex - 1 + this.imageLayouts.length) % this.imageLayouts.length,
|
|
3067
|
+
const t = (this.currentFocusIndex - 1 + this.imageLayouts.length) % this.imageLayouts.length, i = this.imageElements.find(
|
|
3062
3068
|
(o) => o.dataset.imageId === String(t)
|
|
3063
3069
|
);
|
|
3064
|
-
if (!
|
|
3065
|
-
const
|
|
3066
|
-
|
|
3070
|
+
if (!i) return;
|
|
3071
|
+
const e = this.imageLayouts[t];
|
|
3072
|
+
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t));
|
|
3067
3073
|
}
|
|
3068
3074
|
/**
|
|
3069
3075
|
* Navigate to a specific image by index
|
|
@@ -3075,8 +3081,8 @@ class _e {
|
|
|
3075
3081
|
}, 500));
|
|
3076
3082
|
}
|
|
3077
3083
|
getImageHeight() {
|
|
3078
|
-
const t = window.innerWidth,
|
|
3079
|
-
return
|
|
3084
|
+
const t = window.innerWidth, i = this.fullConfig.layout.responsive, o = this.fullConfig.image.sizing?.maxSize ?? 400;
|
|
3085
|
+
return i ? t <= i.mobile.maxWidth ? Math.min(100, o) : t <= i.tablet.maxWidth ? Math.min(180, o) : Math.min(225, o) : t <= 767 ? Math.min(100, o) : t <= 1199 ? Math.min(180, o) : Math.min(225, o);
|
|
3080
3086
|
}
|
|
3081
3087
|
/**
|
|
3082
3088
|
* Get container bounds for layout calculations
|
|
@@ -3094,20 +3100,20 @@ class _e {
|
|
|
3094
3100
|
try {
|
|
3095
3101
|
this.showLoading(!0), this.hideError(), this.clearImageCloud(), await this.imageLoader.prepare(this.imageFilter);
|
|
3096
3102
|
const t = this.imageLoader.imagesLength();
|
|
3097
|
-
let
|
|
3103
|
+
let i = this.imageLoader.imageURLs();
|
|
3098
3104
|
if (t === 0) {
|
|
3099
3105
|
this.showError("No images found."), this.showLoading(!1);
|
|
3100
3106
|
return;
|
|
3101
3107
|
}
|
|
3102
|
-
const
|
|
3103
|
-
this.logDebug(`Adaptive sizing input: container=${
|
|
3108
|
+
const e = this.getContainerBounds(), o = this.getImageHeight(), a = window.innerWidth;
|
|
3109
|
+
this.logDebug(`Adaptive sizing input: container=${e.width}x${e.height}px, images=${t}, responsiveMax=${o}px`);
|
|
3104
3110
|
const r = this.layoutEngine.calculateAdaptiveSize(
|
|
3105
|
-
|
|
3111
|
+
e,
|
|
3106
3112
|
t,
|
|
3107
3113
|
o,
|
|
3108
3114
|
a
|
|
3109
3115
|
);
|
|
3110
|
-
this.logDebug(`Adaptive sizing result: height=${r.height}px`), await this.createImageCloud(
|
|
3116
|
+
this.logDebug(`Adaptive sizing result: height=${r.height}px`), await this.createImageCloud(i, r.height), this.showLoading(!1), this.imagesLoaded = !0;
|
|
3111
3117
|
} catch (t) {
|
|
3112
3118
|
console.error("Error loading images:", t), t instanceof Error && this.showError(t.message || "Failed to load images."), this.showLoading(!1);
|
|
3113
3119
|
}
|
|
@@ -3118,11 +3124,11 @@ class _e {
|
|
|
3118
3124
|
logDebug(...t) {
|
|
3119
3125
|
this.fullConfig.config.debug?.enabled && typeof console < "u" && console.log(...t);
|
|
3120
3126
|
}
|
|
3121
|
-
async createImageCloud(t,
|
|
3127
|
+
async createImageCloud(t, i) {
|
|
3122
3128
|
if (!this.containerEl) return;
|
|
3123
|
-
const
|
|
3124
|
-
this.currentImageHeight =
|
|
3125
|
-
const o = this.loadGeneration, a = this.layoutEngine.generateLayout(t.length,
|
|
3129
|
+
const e = this.getContainerBounds();
|
|
3130
|
+
this.currentImageHeight = i;
|
|
3131
|
+
const o = this.loadGeneration, a = this.layoutEngine.generateLayout(t.length, e, { fixedHeight: i });
|
|
3126
3132
|
this.imageLayouts = a, this.displayQueue = [];
|
|
3127
3133
|
let r = 0;
|
|
3128
3134
|
const s = (c) => {
|
|
@@ -3207,41 +3213,41 @@ class _e {
|
|
|
3207
3213
|
const l = document.createElement("img");
|
|
3208
3214
|
l.referrerPolicy = "no-referrer", l.classList.add("fbn-ic-image"), l.dataset.imageId = String(d), l.dataset.createdFlag = "true";
|
|
3209
3215
|
const u = a[d];
|
|
3210
|
-
l.style.position = "absolute", l.style.width = "auto", l.style.height = `${
|
|
3216
|
+
l.style.position = "absolute", l.style.width = "auto", l.style.height = `${i}px`, l.style.left = `${u.x}px`, l.style.top = `${u.y}px`, u.zIndex && (l.style.zIndex = String(u.zIndex)), ot(l, this.defaultClassName), l.addEventListener("mouseenter", () => {
|
|
3211
3217
|
if (this.hoveredImage = { element: l, layout: u }, !this.zoomEngine.isInvolved(l)) {
|
|
3212
3218
|
const g = l.cachedRenderedWidth;
|
|
3213
|
-
|
|
3219
|
+
gt(l, this.fullConfig.styling?.hover, i, g), ot(l, this.hoverClassName);
|
|
3214
3220
|
}
|
|
3215
3221
|
}), l.addEventListener("mouseleave", () => {
|
|
3216
3222
|
if (this.hoveredImage = null, !this.zoomEngine.isInvolved(l)) {
|
|
3217
3223
|
const g = l.cachedRenderedWidth;
|
|
3218
|
-
|
|
3224
|
+
gt(l, this.fullConfig.styling?.default, i, g), mt(l, this.hoverClassName), ot(l, this.defaultClassName);
|
|
3219
3225
|
}
|
|
3220
3226
|
}), l.addEventListener("click", (g) => {
|
|
3221
3227
|
g.stopPropagation(), this.handleImageClick(l, u);
|
|
3222
3228
|
}), l.style.opacity = "0", l.style.transition = this.entryAnimationEngine.getTransitionCSS(), l.onload = () => {
|
|
3223
3229
|
if (o !== this.loadGeneration)
|
|
3224
3230
|
return;
|
|
3225
|
-
const g = l.naturalWidth / l.naturalHeight, p =
|
|
3226
|
-
l.dataset.onloadCalled = "true", window.DEBUG_CLIPPATH && console.log(`[onload #${d}] Called with imageHeight=${
|
|
3227
|
-
const b = { x: u.x, y: u.y }, f = { width: p, height:
|
|
3231
|
+
const g = l.naturalWidth / l.naturalHeight, p = i * g;
|
|
3232
|
+
l.dataset.onloadCalled = "true", window.DEBUG_CLIPPATH && console.log(`[onload #${d}] Called with imageHeight=${i}, renderedWidth=${p}`), l.style.width = `${p}px`, l.cachedRenderedWidth = p, l.aspectRatio = g, gt(l, this.fullConfig.styling?.default, i, p);
|
|
3233
|
+
const b = { x: u.x, y: u.y }, f = { width: p, height: i }, m = this.entryAnimationEngine.calculateStartPosition(
|
|
3228
3234
|
b,
|
|
3229
3235
|
f,
|
|
3230
|
-
|
|
3236
|
+
e,
|
|
3231
3237
|
d,
|
|
3232
3238
|
t.length
|
|
3233
3239
|
), E = this.entryAnimationEngine.calculateStartRotation(u.rotation), v = this.entryAnimationEngine.calculateStartScale(u.scale), w = this.entryAnimationEngine.buildFinalTransform(
|
|
3234
3240
|
u.rotation,
|
|
3235
3241
|
u.scale,
|
|
3236
3242
|
p,
|
|
3237
|
-
|
|
3243
|
+
i
|
|
3238
3244
|
), S = this.entryAnimationEngine.buildStartTransform(
|
|
3239
3245
|
m,
|
|
3240
3246
|
b,
|
|
3241
3247
|
u.rotation,
|
|
3242
3248
|
u.scale,
|
|
3243
3249
|
p,
|
|
3244
|
-
|
|
3250
|
+
i,
|
|
3245
3251
|
E,
|
|
3246
3252
|
v
|
|
3247
3253
|
);
|
|
@@ -3252,22 +3258,22 @@ class _e {
|
|
|
3252
3258
|
top: u.y,
|
|
3253
3259
|
finalTransform: w,
|
|
3254
3260
|
renderedWidth: p,
|
|
3255
|
-
renderedHeight:
|
|
3256
|
-
}), l.style.transform = S, l.dataset.finalTransform = w, (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() || E !== u.rotation || v !== u.scale) && (l.dataset.startX = String(m.x), l.dataset.startY = String(m.y), l.dataset.endX = String(b.x), l.dataset.endY = String(b.y), l.dataset.imageWidth = String(p), l.dataset.imageHeight = String(
|
|
3261
|
+
renderedHeight: i
|
|
3262
|
+
}), l.style.transform = S, l.dataset.finalTransform = w, (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() || E !== u.rotation || v !== u.scale) && (l.dataset.startX = String(m.x), l.dataset.startY = String(m.y), l.dataset.endX = String(b.x), l.dataset.endY = String(b.y), l.dataset.imageWidth = String(p), l.dataset.imageHeight = String(i), l.dataset.rotation = String(u.rotation), l.dataset.scale = String(u.scale), l.dataset.startRotation = String(E), l.dataset.startScale = String(v)), this.displayQueue.push(l);
|
|
3257
3263
|
}, l.onerror = () => r++, l.src = c;
|
|
3258
3264
|
});
|
|
3259
3265
|
}
|
|
3260
|
-
async handleImageClick(t,
|
|
3266
|
+
async handleImageClick(t, i) {
|
|
3261
3267
|
if (!this.containerEl) return;
|
|
3262
|
-
const
|
|
3268
|
+
const e = this.zoomEngine.isFocused(t), o = {
|
|
3263
3269
|
width: this.containerEl.offsetWidth,
|
|
3264
3270
|
height: this.containerEl.offsetHeight
|
|
3265
3271
|
};
|
|
3266
|
-
if (
|
|
3272
|
+
if (e)
|
|
3267
3273
|
await this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter();
|
|
3268
3274
|
else {
|
|
3269
3275
|
const a = t.dataset.imageId;
|
|
3270
|
-
this.currentFocusIndex = a !== void 0 ? parseInt(a, 10) : null, this.swipeEngine?.enable(), await this.zoomEngine.focusImage(t, o,
|
|
3276
|
+
this.currentFocusIndex = a !== void 0 ? parseInt(a, 10) : null, this.swipeEngine?.enable(), await this.zoomEngine.focusImage(t, o, i), this.currentFocusIndex !== null && this.updateCounter(this.currentFocusIndex);
|
|
3271
3277
|
}
|
|
3272
3278
|
}
|
|
3273
3279
|
/**
|
|
@@ -3308,25 +3314,25 @@ const xt = class xt extends HTMLElement {
|
|
|
3308
3314
|
disconnectedCallback() {
|
|
3309
3315
|
this._destroy(), this._container && (this._container.remove(), this._container = null);
|
|
3310
3316
|
}
|
|
3311
|
-
attributeChangedCallback(t,
|
|
3312
|
-
|
|
3317
|
+
attributeChangedCallback(t, i, e) {
|
|
3318
|
+
i !== e && this._container && (this._destroy(), this._init());
|
|
3313
3319
|
}
|
|
3314
3320
|
getInstance() {
|
|
3315
3321
|
return this._instance;
|
|
3316
3322
|
}
|
|
3317
3323
|
_getOptions() {
|
|
3318
|
-
const t = {},
|
|
3319
|
-
if (
|
|
3324
|
+
const t = {}, i = this.getAttribute("config");
|
|
3325
|
+
if (i)
|
|
3320
3326
|
try {
|
|
3321
|
-
const a = JSON.parse(
|
|
3327
|
+
const a = JSON.parse(i), { container: r, ...s } = a;
|
|
3322
3328
|
Object.assign(t, s);
|
|
3323
3329
|
} catch (a) {
|
|
3324
3330
|
console.error("<image-cloud> invalid config JSON:", a);
|
|
3325
3331
|
}
|
|
3326
|
-
const
|
|
3327
|
-
if (
|
|
3332
|
+
const e = this.getAttribute("images");
|
|
3333
|
+
if (e)
|
|
3328
3334
|
try {
|
|
3329
|
-
t.images = JSON.parse(
|
|
3335
|
+
t.images = JSON.parse(e);
|
|
3330
3336
|
} catch (a) {
|
|
3331
3337
|
console.error("<image-cloud> invalid images JSON:", a);
|
|
3332
3338
|
}
|
|
@@ -3345,8 +3351,8 @@ const xt = class xt extends HTMLElement {
|
|
|
3345
3351
|
...t
|
|
3346
3352
|
}), this._instance.init().then(() => {
|
|
3347
3353
|
this.dispatchEvent(new CustomEvent("initialized", { bubbles: !0 }));
|
|
3348
|
-
}).catch((
|
|
3349
|
-
console.error("<image-cloud> init failed:",
|
|
3354
|
+
}).catch((i) => {
|
|
3355
|
+
console.error("<image-cloud> init failed:", i), this.dispatchEvent(new CustomEvent("error", { detail: i, bubbles: !0 }));
|
|
3350
3356
|
});
|
|
3351
3357
|
} catch (t) {
|
|
3352
3358
|
console.error("<image-cloud> creation failed:", t), this.dispatchEvent(new CustomEvent("error", { detail: t, bubbles: !0 }));
|
|
@@ -3357,9 +3363,9 @@ const xt = class xt extends HTMLElement {
|
|
|
3357
3363
|
}
|
|
3358
3364
|
};
|
|
3359
3365
|
xt.observedAttributes = ["config", "images", "layout"];
|
|
3360
|
-
let
|
|
3361
|
-
typeof customElements < "u" && !customElements.get("image-cloud") && customElements.define("image-cloud",
|
|
3366
|
+
let bt = xt;
|
|
3367
|
+
typeof customElements < "u" && !customElements.get("image-cloud") && customElements.define("image-cloud", bt);
|
|
3362
3368
|
export {
|
|
3363
|
-
|
|
3369
|
+
bt as ImageCloudElement
|
|
3364
3370
|
};
|
|
3365
3371
|
//# sourceMappingURL=web-component.js.map
|