@frybynite/image-cloud 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -13
- package/dist/composite-CtUxtN2l.js +96 -0
- package/dist/composite-CtUxtN2l.js.map +1 -0
- package/dist/google-drive-CC-qFSV1.js +260 -0
- package/dist/google-drive-CC-qFSV1.js.map +1 -0
- package/dist/image-cloud-auto-init.js +399 -842
- package/dist/image-cloud-auto-init.js.map +1 -1
- package/dist/image-cloud.js +1356 -1341
- package/dist/image-cloud.js.map +1 -1
- package/dist/image-cloud.umd.js +5 -5
- package/dist/image-cloud.umd.js.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/loaders/all.d.ts +1654 -0
- package/dist/loaders/all.js +496 -0
- package/dist/loaders/all.js.map +1 -0
- package/dist/loaders/composite.d.ts +1654 -0
- package/dist/loaders/composite.js +96 -0
- package/dist/loaders/composite.js.map +1 -0
- package/dist/loaders/google-drive.d.ts +1654 -0
- package/dist/loaders/google-drive.js +260 -0
- package/dist/loaders/google-drive.js.map +1 -0
- package/dist/loaders/static.d.ts +1654 -0
- package/dist/loaders/static.js +219 -0
- package/dist/loaders/static.js.map +1 -0
- package/dist/react.d.ts +17 -0
- package/dist/react.js +575 -1018
- package/dist/react.js.map +1 -1
- package/dist/static-ejylHtQ4.js +219 -0
- package/dist/static-ejylHtQ4.js.map +1 -0
- package/dist/vue.d.ts +17 -0
- package/dist/vue.js +507 -950
- package/dist/vue.js.map +1 -1
- package/dist/web-component.d.ts +17 -0
- package/dist/web-component.js +513 -956
- package/dist/web-component.js.map +1 -1
- package/package.json +24 -5
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
const
|
|
1
|
+
const $t = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary: #1a1a2e;--fbn-ic-bg-glass: rgba(255, 255, 255, .05);--fbn-ic-border-glass: rgba(255, 255, 255, .1);--fbn-ic-text-primary: #ffffff;--fbn-ic-text-secondary: #b8b8d1;--fbn-ic-text-muted: #6b6b8f;--fbn-ic-accent-primary: #6366f1;--fbn-ic-accent-secondary: #8b5cf6;--fbn-ic-accent-glow: rgba(99, 102, 241, .4);--fbn-ic-transition-smooth: cubic-bezier(.4, 0, .2, 1);--fbn-ic-transition-bounce: cubic-bezier(.68, -.55, .265, 1.55);--fbn-ic-shadow-sm: 0 2px 8px rgba(0, 0, 0, .3);--fbn-ic-shadow-md: 0 4px 16px rgba(0, 0, 0, .4);--fbn-ic-shadow-lg: 0 8px 32px rgba(0, 0, 0, .5);--fbn-ic-shadow-glow: 0 0 20px var(--fbn-ic-accent-glow)}.fbn-ic-gallery{position:relative;width:100%;height:100%;overflow:hidden;perspective:1000px}.fbn-ic-image{position:absolute;border-radius:8px;box-shadow:var(--fbn-ic-shadow-md);cursor:pointer;transition:transform .6s var(--fbn-ic-transition-smooth),box-shadow .6s var(--fbn-ic-transition-smooth),filter .3s var(--fbn-ic-transition-smooth),opacity .3s var(--fbn-ic-transition-smooth),border .3s var(--fbn-ic-transition-smooth),outline .3s var(--fbn-ic-transition-smooth),z-index 0s .6s;will-change:transform;-webkit-user-select:none;user-select:none;backface-visibility:hidden;-webkit-backface-visibility:hidden}.fbn-ic-image:hover{box-shadow:var(--fbn-ic-shadow-lg)}.fbn-ic-image.fbn-ic-focused{z-index:1000;box-shadow:0 20px 60px #000000b3,var(--fbn-ic-shadow-glow);transition:transform .6s var(--fbn-ic-transition-smooth),box-shadow .6s var(--fbn-ic-transition-smooth),filter .3s var(--fbn-ic-transition-smooth),opacity .3s var(--fbn-ic-transition-smooth),border .3s var(--fbn-ic-transition-smooth),outline .3s var(--fbn-ic-transition-smooth),z-index 0s 0s;will-change:auto}.fbn-ic-loading{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;color:var(--fbn-ic-text-secondary);z-index:100;pointer-events:none}.fbn-ic-spinner{width:50px;height:50px;margin:0 auto 1rem;border:4px solid var(--fbn-ic-border-glass);border-top:4px solid var(--fbn-ic-accent-primary);border-radius:50%;animation:fbn-ic-spin 1s linear infinite}@keyframes fbn-ic-spin{to{transform:rotate(360deg)}}.fbn-ic-error{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);max-width:600px;padding:1.5rem;background:#ef44441a;border:1px solid rgba(239,68,68,.3);border-radius:12px;color:#fca5a5;text-align:center;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);z-index:100}.fbn-ic-counter{background:#0009;color:#fff;padding:6px 16px;border-radius:16px;font-family:system-ui,sans-serif;font-size:14px}.fbn-ic-hidden{display:none!important}", pt = 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)",
|
|
5
5
|
lg: "0 8px 32px rgba(0,0,0,0.5)",
|
|
6
6
|
glow: "0 0 30px rgba(255,255,255,0.6)"
|
|
7
|
-
}),
|
|
7
|
+
}), St = 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
|
+
}), Et = 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
|
-
}),
|
|
21
|
+
}), yt = Object.freeze({
|
|
22
22
|
type: "linear"
|
|
23
|
-
}),
|
|
23
|
+
}), vt = Object.freeze({
|
|
24
24
|
mode: "none"
|
|
25
|
-
}),
|
|
25
|
+
}), xt = Object.freeze({
|
|
26
26
|
mode: "none"
|
|
27
|
-
}),
|
|
27
|
+
}), Mt = Object.freeze({
|
|
28
28
|
default: Object.freeze({
|
|
29
29
|
border: Object.freeze({
|
|
30
30
|
width: 0,
|
|
@@ -49,17 +49,17 @@ const Dt = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary:
|
|
|
49
49
|
focused: Object.freeze({
|
|
50
50
|
shadow: "none"
|
|
51
51
|
})
|
|
52
|
-
}),
|
|
52
|
+
}), Pt = Object.freeze({
|
|
53
53
|
rows: 1,
|
|
54
54
|
amplitude: 100,
|
|
55
55
|
frequency: 2,
|
|
56
56
|
phaseShift: 0,
|
|
57
57
|
synchronization: "offset"
|
|
58
58
|
// Note: Image rotation along wave is now controlled via image.rotation.mode = 'tangent'
|
|
59
|
-
}),
|
|
59
|
+
}), Nt = Object.freeze({
|
|
60
60
|
mobile: Object.freeze({ maxWidth: 767 }),
|
|
61
61
|
tablet: Object.freeze({ maxWidth: 1199 })
|
|
62
|
-
}),
|
|
62
|
+
}), Ht = Object.freeze({
|
|
63
63
|
mode: "adaptive",
|
|
64
64
|
// Default to adaptive sizing
|
|
65
65
|
minSize: 50,
|
|
@@ -71,21 +71,21 @@ const Dt = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary:
|
|
|
71
71
|
// No variance by default
|
|
72
72
|
max: 1
|
|
73
73
|
})
|
|
74
|
-
}),
|
|
74
|
+
}), jt = Object.freeze({
|
|
75
75
|
mode: "none",
|
|
76
76
|
range: Object.freeze({
|
|
77
77
|
min: -15,
|
|
78
78
|
max: 15
|
|
79
79
|
})
|
|
80
|
-
}),
|
|
81
|
-
sizing:
|
|
82
|
-
rotation:
|
|
80
|
+
}), At = Object.freeze({
|
|
81
|
+
sizing: Ht,
|
|
82
|
+
rotation: jt
|
|
83
83
|
}), Rt = Object.freeze({
|
|
84
84
|
validateUrls: !0,
|
|
85
85
|
validationTimeout: 5e3,
|
|
86
86
|
validationMethod: "head",
|
|
87
87
|
allowedExtensions: ["jpg", "jpeg", "png", "gif", "webp", "bmp"]
|
|
88
|
-
}),
|
|
88
|
+
}), zt = Object.freeze({
|
|
89
89
|
enabled: !1,
|
|
90
90
|
centers: !1,
|
|
91
91
|
loaders: !1
|
|
@@ -95,16 +95,16 @@ const Dt = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary:
|
|
|
95
95
|
// Shared loader settings and debug config
|
|
96
96
|
config: Object.freeze({
|
|
97
97
|
loaders: Rt,
|
|
98
|
-
debug:
|
|
98
|
+
debug: zt
|
|
99
99
|
}),
|
|
100
100
|
// Image sizing and rotation configuration
|
|
101
|
-
image:
|
|
101
|
+
image: At,
|
|
102
102
|
// Pattern-based layout configuration
|
|
103
103
|
layout: Object.freeze({
|
|
104
104
|
algorithm: "radial",
|
|
105
105
|
scaleDecay: 0,
|
|
106
106
|
// No decay by default (0-1 for radial/spiral)
|
|
107
|
-
responsive:
|
|
107
|
+
responsive: Nt,
|
|
108
108
|
targetCoverage: 0.6,
|
|
109
109
|
// Target 60% of container area
|
|
110
110
|
densityFactor: 1,
|
|
@@ -160,9 +160,9 @@ const Dt = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary:
|
|
|
160
160
|
}),
|
|
161
161
|
easing: "cubic-bezier(0.25, 1, 0.5, 1)",
|
|
162
162
|
// smooth deceleration
|
|
163
|
-
path:
|
|
164
|
-
rotation:
|
|
165
|
-
scale:
|
|
163
|
+
path: yt,
|
|
164
|
+
rotation: vt,
|
|
165
|
+
scale: xt
|
|
166
166
|
})
|
|
167
167
|
}),
|
|
168
168
|
// Pattern-based interaction configuration
|
|
@@ -219,21 +219,21 @@ const Dt = ".fbn-ic-gallery{--fbn-ic-bg-primary: #05060F;--fbn-ic-bg-secondary:
|
|
|
219
219
|
})
|
|
220
220
|
}),
|
|
221
221
|
// Image styling
|
|
222
|
-
styling:
|
|
222
|
+
styling: Mt
|
|
223
223
|
});
|
|
224
|
-
function
|
|
224
|
+
function K(n, t) {
|
|
225
225
|
if (!n) return t || {};
|
|
226
226
|
if (!t) return { ...n };
|
|
227
227
|
const e = { ...n };
|
|
228
228
|
return t.border !== void 0 && (e.border = { ...n.border, ...t.border }), t.borderTop !== void 0 && (e.borderTop = { ...n.borderTop, ...t.borderTop }), t.borderRight !== void 0 && (e.borderRight = { ...n.borderRight, ...t.borderRight }), t.borderBottom !== void 0 && (e.borderBottom = { ...n.borderBottom, ...t.borderBottom }), t.borderLeft !== void 0 && (e.borderLeft = { ...n.borderLeft, ...t.borderLeft }), t.filter !== void 0 && (e.filter = { ...n.filter, ...t.filter }), t.outline !== void 0 && (e.outline = { ...n.outline, ...t.outline }), t.shadow !== void 0 && (e.shadow = t.shadow), t.opacity !== void 0 && (e.opacity = t.opacity), t.cursor !== void 0 && (e.cursor = t.cursor), t.className !== void 0 && (e.className = t.className), t.objectFit !== void 0 && (e.objectFit = t.objectFit), t.aspectRatio !== void 0 && (e.aspectRatio = t.aspectRatio), t.borderRadiusTopLeft !== void 0 && (e.borderRadiusTopLeft = t.borderRadiusTopLeft), t.borderRadiusTopRight !== void 0 && (e.borderRadiusTopRight = t.borderRadiusTopRight), t.borderRadiusBottomRight !== void 0 && (e.borderRadiusBottomRight = t.borderRadiusBottomRight), t.borderRadiusBottomLeft !== void 0 && (e.borderRadiusBottomLeft = t.borderRadiusBottomLeft), e;
|
|
229
229
|
}
|
|
230
|
-
function
|
|
230
|
+
function kt(n, t) {
|
|
231
231
|
if (!t) return { ...n };
|
|
232
|
-
const e =
|
|
233
|
-
|
|
232
|
+
const e = K(n.default, t.default), i = K(
|
|
233
|
+
K(e, n.hover),
|
|
234
234
|
t.hover
|
|
235
|
-
), o =
|
|
236
|
-
|
|
235
|
+
), o = K(
|
|
236
|
+
K(e, n.focused),
|
|
237
237
|
t.focused
|
|
238
238
|
);
|
|
239
239
|
return {
|
|
@@ -242,7 +242,7 @@ function _t(n, t) {
|
|
|
242
242
|
focused: o
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
|
-
function
|
|
245
|
+
function Gt(n, t) {
|
|
246
246
|
if (!t) return { ...n };
|
|
247
247
|
const e = { ...n };
|
|
248
248
|
if (t.sizing !== void 0 && (e.sizing = {
|
|
@@ -261,7 +261,7 @@ function Ht(n, t) {
|
|
|
261
261
|
}
|
|
262
262
|
return e;
|
|
263
263
|
}
|
|
264
|
-
function
|
|
264
|
+
function Wt(n) {
|
|
265
265
|
const t = n.layout?.rotation;
|
|
266
266
|
if (t && "enabled" in t)
|
|
267
267
|
return {
|
|
@@ -271,7 +271,7 @@ function Nt(n) {
|
|
|
271
271
|
}
|
|
272
272
|
};
|
|
273
273
|
}
|
|
274
|
-
function
|
|
274
|
+
function Ut(n) {
|
|
275
275
|
const t = n.layout?.sizing?.variance;
|
|
276
276
|
if (t)
|
|
277
277
|
return {
|
|
@@ -282,8 +282,8 @@ function kt(n) {
|
|
|
282
282
|
}
|
|
283
283
|
};
|
|
284
284
|
}
|
|
285
|
-
function
|
|
286
|
-
const t =
|
|
285
|
+
function _t(n = {}) {
|
|
286
|
+
const t = Wt(n), e = Ut(n);
|
|
287
287
|
let i = n.image;
|
|
288
288
|
(t || e) && (i = {
|
|
289
289
|
...e || {},
|
|
@@ -307,12 +307,12 @@ function jt(n = {}) {
|
|
|
307
307
|
}, a = {
|
|
308
308
|
loaders: o,
|
|
309
309
|
config: r,
|
|
310
|
-
image:
|
|
310
|
+
image: Gt(At, i),
|
|
311
311
|
layout: { ...y.layout },
|
|
312
312
|
animation: { ...y.animation },
|
|
313
313
|
interaction: { ...y.interaction },
|
|
314
314
|
rendering: { ...y.rendering },
|
|
315
|
-
styling:
|
|
315
|
+
styling: kt(Mt, n.styling)
|
|
316
316
|
};
|
|
317
317
|
return n.layout && (a.layout = {
|
|
318
318
|
...y.layout,
|
|
@@ -345,9 +345,9 @@ function jt(n = {}) {
|
|
|
345
345
|
circular: n.animation.entry.start.circular ? { ...y.animation.entry.start.circular, ...n.animation.entry.start.circular } : y.animation.entry.start.circular
|
|
346
346
|
} : y.animation.entry.start,
|
|
347
347
|
timing: n.animation.entry.timing ? { ...y.animation.entry.timing, ...n.animation.entry.timing } : y.animation.entry.timing,
|
|
348
|
-
path: n.animation.entry.path ? { ...
|
|
349
|
-
rotation: n.animation.entry.rotation ? { ...
|
|
350
|
-
scale: n.animation.entry.scale ? { ...
|
|
348
|
+
path: n.animation.entry.path ? { ...yt, ...n.animation.entry.path } : y.animation.entry.path,
|
|
349
|
+
rotation: n.animation.entry.rotation ? { ...vt, ...n.animation.entry.rotation } : y.animation.entry.rotation,
|
|
350
|
+
scale: n.animation.entry.scale ? { ...xt, ...n.animation.entry.scale } : y.animation.entry.scale
|
|
351
351
|
})), n.interaction && (a.interaction = {
|
|
352
352
|
...y.interaction,
|
|
353
353
|
...n.interaction
|
|
@@ -375,20 +375,20 @@ function jt(n = {}) {
|
|
|
375
375
|
...y.rendering.performance,
|
|
376
376
|
...n.rendering.performance
|
|
377
377
|
})), a.config.debug = {
|
|
378
|
-
...
|
|
378
|
+
...zt,
|
|
379
379
|
...n.config?.debug ?? {}
|
|
380
380
|
}, a;
|
|
381
381
|
}
|
|
382
|
-
function Wt(n, t) {
|
|
383
|
-
return { ...n ? wt[n] : wt.playful, ...t };
|
|
384
|
-
}
|
|
385
|
-
function Gt(n, t) {
|
|
386
|
-
return { ...n ? xt[n] : xt.gentle, ...t };
|
|
387
|
-
}
|
|
388
382
|
function qt(n, t) {
|
|
383
|
+
return { ...n ? St[n] : St.playful, ...t };
|
|
384
|
+
}
|
|
385
|
+
function Xt(n, t) {
|
|
389
386
|
return { ...n ? Et[n] : Et.gentle, ...t };
|
|
390
387
|
}
|
|
391
|
-
|
|
388
|
+
function Yt(n, t) {
|
|
389
|
+
return { ...n ? It[n] : It.gentle, ...t };
|
|
390
|
+
}
|
|
391
|
+
class Bt {
|
|
392
392
|
constructor(t) {
|
|
393
393
|
this.activeAnimations = /* @__PURE__ */ new Map(), this.animationIdCounter = 0, this.config = t;
|
|
394
394
|
}
|
|
@@ -547,8 +547,8 @@ class Yt {
|
|
|
547
547
|
function V(n, t, e) {
|
|
548
548
|
return n + (t - n) * e;
|
|
549
549
|
}
|
|
550
|
-
function
|
|
551
|
-
const { overshoot: o, bounces: s, decayRatio: r } = i, a = e.x - t.x, h = e.y - t.y, c =
|
|
550
|
+
function Jt(n, t, e, i) {
|
|
551
|
+
const { overshoot: o, bounces: s, decayRatio: r } = i, a = e.x - t.x, h = e.y - t.y, c = Vt(s, r);
|
|
552
552
|
let u = 0, l = 0, d = 1, f = o, b = !1;
|
|
553
553
|
for (let g = 0; g < c.length; g++)
|
|
554
554
|
if (n <= c[g].time) {
|
|
@@ -557,21 +557,21 @@ function Xt(n, t, e, i) {
|
|
|
557
557
|
}
|
|
558
558
|
const p = (n - l) / (d - l);
|
|
559
559
|
if (b)
|
|
560
|
-
u = 1 + f *
|
|
560
|
+
u = 1 + f * at(p);
|
|
561
561
|
else if (l === 0)
|
|
562
|
-
u =
|
|
562
|
+
u = at(p);
|
|
563
563
|
else {
|
|
564
564
|
const m = 1 + (c.find(
|
|
565
|
-
(
|
|
565
|
+
(S, v) => S.time > l && v > 0 && c[v - 1].isOvershoot
|
|
566
566
|
)?.overshoot || f);
|
|
567
|
-
u = V(m, 1,
|
|
567
|
+
u = V(m, 1, at(p));
|
|
568
568
|
}
|
|
569
569
|
return {
|
|
570
570
|
x: t.x + a * u,
|
|
571
571
|
y: t.y + h * u
|
|
572
572
|
};
|
|
573
573
|
}
|
|
574
|
-
function
|
|
574
|
+
function Vt(n, t) {
|
|
575
575
|
const e = [];
|
|
576
576
|
let i = 0.6;
|
|
577
577
|
e.push({ time: i, overshoot: 0, isOvershoot: !1 });
|
|
@@ -581,7 +581,7 @@ function Bt(n, t) {
|
|
|
581
581
|
i += r, e.push({ time: i, overshoot: o, isOvershoot: !0 }), i += r, e.push({ time: i, overshoot: o * t, isOvershoot: !1 }), o *= t;
|
|
582
582
|
return e.push({ time: 1, overshoot: 0, isOvershoot: !1 }), e;
|
|
583
583
|
}
|
|
584
|
-
function
|
|
584
|
+
function Qt(n, t, e, i) {
|
|
585
585
|
const { stiffness: o, damping: s, mass: r, oscillations: a } = i, h = e.x - t.x, c = e.y - t.y, u = Math.sqrt(o / r), l = s / (2 * Math.sqrt(o * r));
|
|
586
586
|
let d;
|
|
587
587
|
if (l < 1) {
|
|
@@ -594,24 +594,24 @@ function Jt(n, t, e, i) {
|
|
|
594
594
|
y: t.y + c * d
|
|
595
595
|
};
|
|
596
596
|
}
|
|
597
|
-
function
|
|
597
|
+
function Zt(n, t, e, i) {
|
|
598
598
|
const { amplitude: o, frequency: s, decay: r, decayRate: a, phase: h } = i, c = e.x - t.x, u = e.y - t.y, l = Math.sqrt(c * c + u * u), d = l > 0 ? -u / l : 0, f = l > 0 ? c / l : 1, b = s * Math.PI * 2 * n + h, p = r ? Math.pow(1 - n, a) : 1, g = o * Math.sin(b) * p, m = Kt(n);
|
|
599
599
|
return {
|
|
600
600
|
x: V(t.x, e.x, m) + g * d,
|
|
601
601
|
y: V(t.y, e.y, m) + g * f
|
|
602
602
|
};
|
|
603
603
|
}
|
|
604
|
-
function
|
|
604
|
+
function at(n) {
|
|
605
605
|
return 1 - (1 - n) * (1 - n);
|
|
606
606
|
}
|
|
607
607
|
function Kt(n) {
|
|
608
608
|
return 1 - Math.pow(1 - n, 3);
|
|
609
609
|
}
|
|
610
|
-
function
|
|
610
|
+
function te(n, t, e) {
|
|
611
611
|
const { amplitude: i, frequency: o, decay: s } = e, r = Math.sin(n * o * Math.PI * 2), a = s ? Math.pow(1 - n, 2) : 1, h = i * r * a;
|
|
612
612
|
return t + h;
|
|
613
613
|
}
|
|
614
|
-
function
|
|
614
|
+
function ee(n, t, e) {
|
|
615
615
|
const { overshoot: i, bounces: o } = e, s = [];
|
|
616
616
|
s.push({ time: 0.5, scale: i });
|
|
617
617
|
let r = i;
|
|
@@ -625,13 +625,13 @@ function Qt(n, t, e) {
|
|
|
625
625
|
let l = 1;
|
|
626
626
|
for (let d = 0; d < s.length; d++)
|
|
627
627
|
if (n <= s[d].time) {
|
|
628
|
-
const f = d === 0 ? 0 : s[d - 1].time, b = d === 0 ? 1 : s[d - 1].scale, p = (n - f) / (s[d].time - f), g =
|
|
628
|
+
const f = d === 0 ? 0 : s[d - 1].time, b = d === 0 ? 1 : s[d - 1].scale, p = (n - f) / (s[d].time - f), g = at(p);
|
|
629
629
|
l = b + (s[d].scale - b) * g;
|
|
630
630
|
break;
|
|
631
631
|
}
|
|
632
632
|
return l * t;
|
|
633
633
|
}
|
|
634
|
-
function
|
|
634
|
+
function ie(n) {
|
|
635
635
|
const {
|
|
636
636
|
element: t,
|
|
637
637
|
startPosition: e,
|
|
@@ -647,38 +647,38 @@ function te(n) {
|
|
|
647
647
|
startRotation: d,
|
|
648
648
|
scaleConfig: f,
|
|
649
649
|
startScale: b
|
|
650
|
-
} = n, p = o.type, g = d !== void 0 && d !== h, m = l?.mode === "wobble",
|
|
651
|
-
if ((p === "linear" || p === "arc") && !v && !(
|
|
650
|
+
} = n, p = o.type, g = d !== void 0 && d !== h, m = l?.mode === "wobble", S = l?.wobble || { amplitude: 15, frequency: 3, decay: !0 }, v = g || m, x = b !== void 0 && b !== c, E = f?.mode === "pop", w = f?.pop || { overshoot: 1.2, bounces: 1 };
|
|
651
|
+
if ((p === "linear" || p === "arc") && !v && !(x || E)) {
|
|
652
652
|
u && u();
|
|
653
653
|
return;
|
|
654
654
|
}
|
|
655
|
-
const z = performance.now(),
|
|
656
|
-
function
|
|
657
|
-
const
|
|
655
|
+
const z = performance.now(), F = -r / 2, N = -a / 2;
|
|
656
|
+
function H(X) {
|
|
657
|
+
const k = X - z, T = Math.min(k / s, 1);
|
|
658
658
|
let D;
|
|
659
659
|
switch (p) {
|
|
660
660
|
case "bounce": {
|
|
661
|
-
const O =
|
|
661
|
+
const O = qt(
|
|
662
662
|
o.bouncePreset,
|
|
663
663
|
o.bounce
|
|
664
664
|
);
|
|
665
|
-
D =
|
|
665
|
+
D = Jt(T, e, i, O);
|
|
666
666
|
break;
|
|
667
667
|
}
|
|
668
668
|
case "elastic": {
|
|
669
|
-
const O =
|
|
669
|
+
const O = Xt(
|
|
670
670
|
o.elasticPreset,
|
|
671
671
|
o.elastic
|
|
672
672
|
);
|
|
673
|
-
D =
|
|
673
|
+
D = Qt(T, e, i, O);
|
|
674
674
|
break;
|
|
675
675
|
}
|
|
676
676
|
case "wave": {
|
|
677
|
-
const O =
|
|
677
|
+
const O = Yt(
|
|
678
678
|
o.wavePreset,
|
|
679
679
|
o.wave
|
|
680
680
|
);
|
|
681
|
-
D =
|
|
681
|
+
D = Zt(T, e, i, O);
|
|
682
682
|
break;
|
|
683
683
|
}
|
|
684
684
|
default:
|
|
@@ -687,18 +687,18 @@ function te(n) {
|
|
|
687
687
|
y: V(e.y, i.y, T)
|
|
688
688
|
};
|
|
689
689
|
}
|
|
690
|
-
const
|
|
690
|
+
const W = D.x - i.x, j = D.y - i.y;
|
|
691
691
|
let A;
|
|
692
|
-
m ? A =
|
|
693
|
-
let
|
|
694
|
-
|
|
692
|
+
m ? A = te(T, h, S) : g ? A = V(d, h, T) : A = h;
|
|
693
|
+
let M;
|
|
694
|
+
E ? M = ee(T, c, w) : x ? M = V(b, c, T) : M = c, t.style.transform = `translate(${F}px, ${N}px) translate(${W}px, ${j}px) rotate(${A}deg) scale(${M})`, T < 1 ? requestAnimationFrame(H) : (t.style.transform = `translate(${F}px, ${N}px) rotate(${h}deg) scale(${c})`, u && u());
|
|
695
695
|
}
|
|
696
|
-
requestAnimationFrame(
|
|
696
|
+
requestAnimationFrame(H);
|
|
697
697
|
}
|
|
698
|
-
function
|
|
698
|
+
function ne(n) {
|
|
699
699
|
return n === "bounce" || n === "elastic" || n === "wave";
|
|
700
700
|
}
|
|
701
|
-
const
|
|
701
|
+
const oe = {
|
|
702
702
|
radial: "center",
|
|
703
703
|
spiral: "center",
|
|
704
704
|
grid: "top",
|
|
@@ -706,15 +706,15 @@ const ie = {
|
|
|
706
706
|
random: "nearest-edge",
|
|
707
707
|
wave: "left"
|
|
708
708
|
};
|
|
709
|
-
class
|
|
709
|
+
class se {
|
|
710
710
|
constructor(t, e) {
|
|
711
|
-
this.config = t, this.layoutAlgorithm = e, this.resolvedStartPosition = this.resolveStartPosition(), this.pathConfig = t.path ||
|
|
711
|
+
this.config = t, this.layoutAlgorithm = e, this.resolvedStartPosition = this.resolveStartPosition(), this.pathConfig = t.path || yt, this.rotationConfig = t.rotation || vt, this.scaleConfig = t.scale || xt;
|
|
712
712
|
}
|
|
713
713
|
/**
|
|
714
714
|
* Get the effective start position, considering layout-aware defaults
|
|
715
715
|
*/
|
|
716
716
|
resolveStartPosition() {
|
|
717
|
-
return this.config.start.position ? this.config.start.position :
|
|
717
|
+
return this.config.start.position ? this.config.start.position : oe[this.layoutAlgorithm] || "nearest-edge";
|
|
718
718
|
}
|
|
719
719
|
/**
|
|
720
720
|
* Calculate the starting position for an image's entry animation
|
|
@@ -859,7 +859,7 @@ class ne {
|
|
|
859
859
|
* Check if the current path type requires JavaScript animation
|
|
860
860
|
*/
|
|
861
861
|
requiresJSAnimation() {
|
|
862
|
-
return
|
|
862
|
+
return ne(this.pathConfig.type);
|
|
863
863
|
}
|
|
864
864
|
/**
|
|
865
865
|
* Get the path configuration
|
|
@@ -1050,7 +1050,7 @@ class ne {
|
|
|
1050
1050
|
return 1 - (1 - t) * (1 - t);
|
|
1051
1051
|
}
|
|
1052
1052
|
}
|
|
1053
|
-
class
|
|
1053
|
+
class ae {
|
|
1054
1054
|
constructor(t, e = {}) {
|
|
1055
1055
|
this.config = t, this.imageConfig = e;
|
|
1056
1056
|
}
|
|
@@ -1062,17 +1062,17 @@ class oe {
|
|
|
1062
1062
|
* @returns Array of layout objects with position, rotation, scale
|
|
1063
1063
|
*/
|
|
1064
1064
|
generate(t, e, i = {}) {
|
|
1065
|
-
const o = [], { width: s, height: r } = e, a = this.config.spacing.padding, h = i.fixedHeight ?? 200, c = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, l = this.imageConfig.rotation?.range?.max ?? 15, d = this.imageConfig.sizing?.variance?.min ?? 1, f = this.imageConfig.sizing?.variance?.max ?? 1, b = d !== 1 || f !== 1, g = h * 1.5 / 2, m = h / 2,
|
|
1066
|
-
for (let
|
|
1067
|
-
const C = this.random(
|
|
1068
|
-
id:
|
|
1065
|
+
const o = [], { width: s, height: r } = e, a = this.config.spacing.padding, h = i.fixedHeight ?? 200, c = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, l = this.imageConfig.rotation?.range?.max ?? 15, d = this.imageConfig.sizing?.variance?.min ?? 1, f = this.imageConfig.sizing?.variance?.max ?? 1, b = d !== 1 || f !== 1, g = h * 1.5 / 2, m = h / 2, S = s - a - g, v = r - a - m, x = a + g, E = a + m;
|
|
1066
|
+
for (let w = 0; w < t; w++) {
|
|
1067
|
+
const C = this.random(x, S), z = this.random(E, v), F = c === "random" ? this.random(u, l) : 0, N = b ? this.random(d, f) : 1, H = h * N, X = {
|
|
1068
|
+
id: w,
|
|
1069
1069
|
x: C,
|
|
1070
1070
|
y: z,
|
|
1071
|
-
rotation:
|
|
1072
|
-
scale:
|
|
1073
|
-
baseSize:
|
|
1071
|
+
rotation: F,
|
|
1072
|
+
scale: N,
|
|
1073
|
+
baseSize: H
|
|
1074
1074
|
};
|
|
1075
|
-
o.push(
|
|
1075
|
+
o.push(X);
|
|
1076
1076
|
}
|
|
1077
1077
|
return o;
|
|
1078
1078
|
}
|
|
@@ -1086,7 +1086,7 @@ class oe {
|
|
|
1086
1086
|
return Math.random() * (e - t) + t;
|
|
1087
1087
|
}
|
|
1088
1088
|
}
|
|
1089
|
-
class
|
|
1089
|
+
class re {
|
|
1090
1090
|
constructor(t, e = {}) {
|
|
1091
1091
|
this.config = t, this.imageConfig = e;
|
|
1092
1092
|
}
|
|
@@ -1098,47 +1098,47 @@ class se {
|
|
|
1098
1098
|
* @returns Array of layout objects with position, rotation, scale
|
|
1099
1099
|
*/
|
|
1100
1100
|
generate(t, e, i = {}) {
|
|
1101
|
-
const o = [], { width: s, height: r } = e, a = i.fixedHeight ?? 200, h = this.imageConfig.rotation?.mode ?? "none", c = this.imageConfig.rotation?.range?.min ?? -15, u = this.imageConfig.rotation?.range?.max ?? 15, l = this.imageConfig.sizing?.variance?.min ?? 1, d = this.imageConfig.sizing?.variance?.max ?? 1, f = l !== 1 || d !== 1, b = this.config.scaleDecay ?? 0, p = i.fixedHeight ?? a, g = s / 2, m = r / 2,
|
|
1101
|
+
const o = [], { width: s, height: r } = e, a = i.fixedHeight ?? 200, h = this.imageConfig.rotation?.mode ?? "none", c = this.imageConfig.rotation?.range?.min ?? -15, u = this.imageConfig.rotation?.range?.max ?? 15, l = this.imageConfig.sizing?.variance?.min ?? 1, d = this.imageConfig.sizing?.variance?.max ?? 1, f = l !== 1 || d !== 1, b = this.config.scaleDecay ?? 0, p = i.fixedHeight ?? a, g = s / 2, m = r / 2, S = Math.ceil(Math.sqrt(t));
|
|
1102
1102
|
if (t > 0) {
|
|
1103
|
-
const
|
|
1103
|
+
const E = f ? this.random(l, d) : 1, w = p * E;
|
|
1104
1104
|
o.push({
|
|
1105
1105
|
id: 0,
|
|
1106
1106
|
x: g,
|
|
1107
1107
|
y: m,
|
|
1108
1108
|
rotation: h === "random" ? this.random(c * 0.33, u * 0.33) : 0,
|
|
1109
1109
|
// Less rotation for center
|
|
1110
|
-
scale:
|
|
1111
|
-
baseSize:
|
|
1110
|
+
scale: E,
|
|
1111
|
+
baseSize: w,
|
|
1112
1112
|
zIndex: 100
|
|
1113
1113
|
// Center image is highest
|
|
1114
1114
|
});
|
|
1115
1115
|
}
|
|
1116
|
-
let v = 1,
|
|
1116
|
+
let v = 1, x = 1;
|
|
1117
1117
|
for (; v < t; ) {
|
|
1118
|
-
const
|
|
1119
|
-
if (
|
|
1120
|
-
|
|
1118
|
+
const E = x / S, w = b > 0 ? 1 - E * b * 0.5 : 1, C = x * (p * 0.8), z = C * 1.5, F = Math.PI * (3 * (z + C) - Math.sqrt((3 * z + C) * (z + 3 * C))), N = this.estimateWidth(p), H = Math.floor(F / (N * 0.7));
|
|
1119
|
+
if (H === 0) {
|
|
1120
|
+
x++;
|
|
1121
1121
|
continue;
|
|
1122
1122
|
}
|
|
1123
|
-
const
|
|
1124
|
-
for (let T = 0; T <
|
|
1125
|
-
const D = T *
|
|
1126
|
-
let
|
|
1127
|
-
const $ = this.config.spacing.padding ?? 50,
|
|
1128
|
-
|
|
1129
|
-
const
|
|
1123
|
+
const X = 2 * Math.PI / H, k = x * (20 * Math.PI / 180);
|
|
1124
|
+
for (let T = 0; T < H && v < t; T++) {
|
|
1125
|
+
const D = T * X + k, W = f ? this.random(l, d) : 1, j = w * W, A = p * j;
|
|
1126
|
+
let M = g + Math.cos(D) * z, O = m + Math.sin(D) * C;
|
|
1127
|
+
const $ = this.config.spacing.padding ?? 50, P = A * 1.5 / 2, R = A / 2;
|
|
1128
|
+
M - P < $ ? M = $ + P : M + P > s - $ && (M = s - $ - P), O - R < $ ? O = $ + R : O + R > r - $ && (O = r - $ - R);
|
|
1129
|
+
const U = h === "random" ? this.random(c, u) : 0;
|
|
1130
1130
|
o.push({
|
|
1131
1131
|
id: v,
|
|
1132
|
-
x:
|
|
1132
|
+
x: M,
|
|
1133
1133
|
y: O,
|
|
1134
|
-
rotation:
|
|
1135
|
-
scale:
|
|
1134
|
+
rotation: U,
|
|
1135
|
+
scale: j,
|
|
1136
1136
|
baseSize: A,
|
|
1137
|
-
zIndex: Math.max(1, 100 -
|
|
1137
|
+
zIndex: Math.max(1, 100 - x)
|
|
1138
1138
|
// Outer rings have lower z-index
|
|
1139
1139
|
}), v++;
|
|
1140
1140
|
}
|
|
1141
|
-
|
|
1141
|
+
x++;
|
|
1142
1142
|
}
|
|
1143
1143
|
return o;
|
|
1144
1144
|
}
|
|
@@ -1161,7 +1161,7 @@ class se {
|
|
|
1161
1161
|
return Math.random() * (e - t) + t;
|
|
1162
1162
|
}
|
|
1163
1163
|
}
|
|
1164
|
-
const
|
|
1164
|
+
const ce = {
|
|
1165
1165
|
columns: "auto",
|
|
1166
1166
|
rows: "auto",
|
|
1167
1167
|
stagger: "none",
|
|
@@ -1171,7 +1171,7 @@ const ae = {
|
|
|
1171
1171
|
alignment: "center",
|
|
1172
1172
|
gap: 10,
|
|
1173
1173
|
overflowOffset: 0.25
|
|
1174
|
-
},
|
|
1174
|
+
}, Ct = [
|
|
1175
1175
|
{ x: 1, y: 1 },
|
|
1176
1176
|
// bottom-right
|
|
1177
1177
|
{ x: -1, y: -1 },
|
|
@@ -1189,7 +1189,7 @@ const ae = {
|
|
|
1189
1189
|
{ x: 0, y: 1 }
|
|
1190
1190
|
// down
|
|
1191
1191
|
];
|
|
1192
|
-
class
|
|
1192
|
+
class le {
|
|
1193
1193
|
constructor(t, e = {}) {
|
|
1194
1194
|
this.config = t, this.imageConfig = e;
|
|
1195
1195
|
}
|
|
@@ -1201,65 +1201,65 @@ class re {
|
|
|
1201
1201
|
* @returns Array of layout objects with position, rotation, scale
|
|
1202
1202
|
*/
|
|
1203
1203
|
generate(t, e, i = {}) {
|
|
1204
|
-
const o = [], { width: s, height: r } = e, a = { ...
|
|
1204
|
+
const o = [], { width: s, height: r } = e, a = { ...ce, ...this.config.grid }, h = this.config.spacing.padding, c = i.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.sizing?.variance?.min ?? 1, d = this.imageConfig.sizing?.variance?.max ?? 1, f = l !== 1 || d !== 1, b = s - 2 * h, p = r - 2 * h, { columns: g, rows: m } = this.calculateGridDimensions(
|
|
1205
1205
|
t,
|
|
1206
1206
|
b,
|
|
1207
1207
|
p,
|
|
1208
1208
|
c,
|
|
1209
1209
|
a
|
|
1210
|
-
),
|
|
1210
|
+
), S = a.stagger === "row", v = a.stagger === "column", x = S ? g + 0.5 : g, E = v ? m + 0.5 : m, w = (b - a.gap * (g - 1)) / x, C = (p - a.gap * (m - 1)) / E, z = S ? w / 2 : 0, F = v ? C / 2 : 0, N = 1 + a.overlap, H = Math.min(w, C) * N, X = i.fixedHeight ? Math.min(i.fixedHeight, H) : H, k = g * w + (g - 1) * a.gap + z, T = m * C + (m - 1) * a.gap + F, D = h + (b - k) / 2, W = h + (p - T) / 2, j = g * m, A = a.columns !== "auto" && a.rows !== "auto", M = A && t > j;
|
|
1211
1211
|
typeof window < "u" && (window.__gridOverflowDebug = {
|
|
1212
1212
|
gridConfigColumns: a.columns,
|
|
1213
1213
|
gridConfigRows: a.rows,
|
|
1214
1214
|
columns: g,
|
|
1215
1215
|
rows: m,
|
|
1216
|
-
cellCount:
|
|
1216
|
+
cellCount: j,
|
|
1217
1217
|
hasFixedGrid: A,
|
|
1218
1218
|
imageCount: t,
|
|
1219
|
-
isOverflowMode:
|
|
1219
|
+
isOverflowMode: M
|
|
1220
1220
|
});
|
|
1221
|
-
const O =
|
|
1222
|
-
for (let
|
|
1223
|
-
let
|
|
1224
|
-
if (
|
|
1225
|
-
const q =
|
|
1226
|
-
|
|
1221
|
+
const O = M ? new Array(j).fill(0) : [], $ = Math.min(w, C) * a.overflowOffset;
|
|
1222
|
+
for (let L = 0; L < t; L++) {
|
|
1223
|
+
let P, R, U = 0;
|
|
1224
|
+
if (M && L >= j) {
|
|
1225
|
+
const q = L - j, G = q % j;
|
|
1226
|
+
U = Math.floor(q / j) + 1, O[G]++, a.fillDirection === "row" ? (P = G % g, R = Math.floor(G / g)) : (R = G % m, P = Math.floor(G / m));
|
|
1227
1227
|
} else
|
|
1228
|
-
a.fillDirection === "row" ? (
|
|
1229
|
-
let
|
|
1230
|
-
if (a.stagger === "row" &&
|
|
1231
|
-
const q = (
|
|
1232
|
-
|
|
1228
|
+
a.fillDirection === "row" ? (P = L % g, R = Math.floor(L / g)) : (R = L % m, P = Math.floor(L / m));
|
|
1229
|
+
let _ = D + P * (w + a.gap) + w / 2, Y = W + R * (C + a.gap) + C / 2;
|
|
1230
|
+
if (a.stagger === "row" && R % 2 === 1 ? _ += w / 2 : a.stagger === "column" && P % 2 === 1 && (Y += C / 2), U > 0) {
|
|
1231
|
+
const q = (U - 1) % Ct.length, G = Ct[q];
|
|
1232
|
+
_ += G.x * $, Y += G.y * $;
|
|
1233
1233
|
}
|
|
1234
1234
|
if (a.jitter > 0) {
|
|
1235
|
-
const q =
|
|
1236
|
-
|
|
1235
|
+
const q = w / 2 * a.jitter, G = C / 2 * a.jitter;
|
|
1236
|
+
_ += this.random(-q, q), Y += this.random(-G, G);
|
|
1237
1237
|
}
|
|
1238
|
-
let B =
|
|
1239
|
-
if (!
|
|
1238
|
+
let B = _, J = Y;
|
|
1239
|
+
if (!M && a.fillDirection === "row") {
|
|
1240
1240
|
const q = t % g || g;
|
|
1241
|
-
if (
|
|
1242
|
-
const
|
|
1243
|
-
let
|
|
1244
|
-
a.alignment === "center" ?
|
|
1241
|
+
if (R === Math.floor((t - 1) / g) && q < g) {
|
|
1242
|
+
const wt = q * w + (q - 1) * a.gap;
|
|
1243
|
+
let mt = 0;
|
|
1244
|
+
a.alignment === "center" ? mt = (k - wt) / 2 : a.alignment === "end" && (mt = k - wt), B += mt;
|
|
1245
1245
|
}
|
|
1246
1246
|
}
|
|
1247
|
-
const
|
|
1248
|
-
B = Math.max(
|
|
1249
|
-
let
|
|
1247
|
+
const lt = f ? this.random(l, d) : 1, Q = X * lt, ot = Q * 1.5 / 2, st = Q / 2, dt = h + ot, ut = s - h - ot, Dt = h + st, Ot = r - h - st;
|
|
1248
|
+
B = Math.max(dt, Math.min(B, ut)), J = Math.max(Dt, Math.min(J, Ot));
|
|
1249
|
+
let gt = 0;
|
|
1250
1250
|
if (u === "random") {
|
|
1251
|
-
const q = this.imageConfig.rotation?.range?.min ?? -15,
|
|
1252
|
-
a.jitter > 0 ?
|
|
1251
|
+
const q = this.imageConfig.rotation?.range?.min ?? -15, G = this.imageConfig.rotation?.range?.max ?? 15;
|
|
1252
|
+
a.jitter > 0 ? gt = this.random(q * a.jitter, G * a.jitter) : gt = this.random(q, G);
|
|
1253
1253
|
}
|
|
1254
|
-
let
|
|
1255
|
-
|
|
1256
|
-
id:
|
|
1254
|
+
let ft;
|
|
1255
|
+
M && U > 0 ? ft = 50 - U : ft = M ? 100 + L : L + 1, o.push({
|
|
1256
|
+
id: L,
|
|
1257
1257
|
x: B,
|
|
1258
1258
|
y: J,
|
|
1259
|
-
rotation:
|
|
1260
|
-
scale:
|
|
1261
|
-
baseSize:
|
|
1262
|
-
zIndex:
|
|
1259
|
+
rotation: gt,
|
|
1260
|
+
scale: lt,
|
|
1261
|
+
baseSize: Q,
|
|
1262
|
+
zIndex: ft
|
|
1263
1263
|
});
|
|
1264
1264
|
}
|
|
1265
1265
|
return o;
|
|
@@ -1289,14 +1289,14 @@ class re {
|
|
|
1289
1289
|
return Math.random() * (e - t) + t;
|
|
1290
1290
|
}
|
|
1291
1291
|
}
|
|
1292
|
-
const
|
|
1292
|
+
const he = Math.PI * (3 - Math.sqrt(5)), de = {
|
|
1293
1293
|
spiralType: "golden",
|
|
1294
1294
|
direction: "counterclockwise",
|
|
1295
1295
|
tightness: 1,
|
|
1296
1296
|
scaleDecay: 0,
|
|
1297
1297
|
startAngle: 0
|
|
1298
1298
|
};
|
|
1299
|
-
class
|
|
1299
|
+
class ue {
|
|
1300
1300
|
constructor(t, e = {}) {
|
|
1301
1301
|
this.config = t, this.imageConfig = e;
|
|
1302
1302
|
}
|
|
@@ -1308,36 +1308,36 @@ class he {
|
|
|
1308
1308
|
* @returns Array of layout objects with position, rotation, scale
|
|
1309
1309
|
*/
|
|
1310
1310
|
generate(t, e, i = {}) {
|
|
1311
|
-
const o = [], { width: s, height: r } = e, a = { ...
|
|
1311
|
+
const o = [], { width: s, height: r } = e, a = { ...de, ...this.config.spiral }, h = this.config.spacing.padding, c = i.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.rotation?.range?.min ?? -15, d = this.imageConfig.rotation?.range?.max ?? 15, f = this.imageConfig.sizing?.variance?.min ?? 1, b = this.imageConfig.sizing?.variance?.max ?? 1, p = f !== 1 || b !== 1, g = this.config.scaleDecay ?? a.scaleDecay, m = s / 2, S = r / 2, v = Math.min(
|
|
1312
1312
|
m - h - c / 2,
|
|
1313
|
-
|
|
1314
|
-
),
|
|
1315
|
-
for (let
|
|
1316
|
-
let
|
|
1313
|
+
S - h - c / 2
|
|
1314
|
+
), x = a.direction === "clockwise" ? -1 : 1;
|
|
1315
|
+
for (let E = 0; E < t; E++) {
|
|
1316
|
+
let w, C;
|
|
1317
1317
|
if (a.spiralType === "golden")
|
|
1318
|
-
|
|
1318
|
+
w = E * he * x + a.startAngle, C = this.calculateGoldenRadius(E, t, v, a.tightness);
|
|
1319
1319
|
else if (a.spiralType === "archimedean") {
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1320
|
+
const _ = E * 0.5 * a.tightness;
|
|
1321
|
+
w = _ * x + a.startAngle, C = this.calculateArchimedeanRadius(_, t, v, a.tightness);
|
|
1322
1322
|
} else {
|
|
1323
|
-
const
|
|
1324
|
-
|
|
1323
|
+
const _ = E * 0.3 * a.tightness;
|
|
1324
|
+
w = _ * x + a.startAngle, C = this.calculateLogarithmicRadius(_, t, v, a.tightness);
|
|
1325
1325
|
}
|
|
1326
|
-
const z = m + Math.cos(
|
|
1327
|
-
let
|
|
1326
|
+
const z = m + Math.cos(w) * C, F = S + Math.sin(w) * C, N = C / v, H = g > 0 ? 1 - N * g * 0.5 : 1, X = p ? this.random(f, b) : 1, k = H * X, T = c * k, W = T * 1.5 / 2, j = T / 2, A = h + W, M = s - h - W, O = h + j, $ = r - h - j, L = Math.max(A, Math.min(z, M)), P = Math.max(O, Math.min(F, $));
|
|
1327
|
+
let R = 0;
|
|
1328
1328
|
if (u === "random") {
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
} else u === "tangent" && (
|
|
1332
|
-
const
|
|
1329
|
+
const _ = w * 180 / Math.PI % 360, Y = this.random(l, d);
|
|
1330
|
+
R = a.spiralType === "golden" ? Y : _ * 0.1 + Y * 0.9;
|
|
1331
|
+
} else u === "tangent" && (R = this.calculateSpiralTangent(w, C, a));
|
|
1332
|
+
const U = t - E;
|
|
1333
1333
|
o.push({
|
|
1334
|
-
id:
|
|
1335
|
-
x:
|
|
1336
|
-
y:
|
|
1337
|
-
rotation:
|
|
1338
|
-
scale:
|
|
1334
|
+
id: E,
|
|
1335
|
+
x: L,
|
|
1336
|
+
y: P,
|
|
1337
|
+
rotation: R,
|
|
1338
|
+
scale: k,
|
|
1339
1339
|
baseSize: T,
|
|
1340
|
-
zIndex:
|
|
1340
|
+
zIndex: U
|
|
1341
1341
|
});
|
|
1342
1342
|
}
|
|
1343
1343
|
return o;
|
|
@@ -1390,7 +1390,7 @@ class he {
|
|
|
1390
1390
|
return Math.random() * (e - t) + t;
|
|
1391
1391
|
}
|
|
1392
1392
|
}
|
|
1393
|
-
const
|
|
1393
|
+
const ge = {
|
|
1394
1394
|
clusterCount: "auto",
|
|
1395
1395
|
clusterSpread: 150,
|
|
1396
1396
|
clusterSpacing: 200,
|
|
@@ -1398,7 +1398,7 @@ const de = {
|
|
|
1398
1398
|
overlap: 0.3,
|
|
1399
1399
|
distribution: "gaussian"
|
|
1400
1400
|
};
|
|
1401
|
-
class
|
|
1401
|
+
class fe {
|
|
1402
1402
|
constructor(t, e = {}) {
|
|
1403
1403
|
this.config = t, this.imageConfig = e;
|
|
1404
1404
|
}
|
|
@@ -1410,7 +1410,7 @@ class ue {
|
|
|
1410
1410
|
* @returns Array of layout objects with position, rotation, scale
|
|
1411
1411
|
*/
|
|
1412
1412
|
generate(t, e, i = {}) {
|
|
1413
|
-
const o = [], { width: s, height: r } = e, a = { ...
|
|
1413
|
+
const o = [], { width: s, height: r } = e, a = { ...ge, ...this.config.cluster }, h = this.config.spacing.padding, c = i.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.rotation?.range?.min ?? -15, d = this.imageConfig.rotation?.range?.max ?? 15, f = this.imageConfig.sizing?.variance?.min ?? 1, b = this.imageConfig.sizing?.variance?.max ?? 1, p = f !== 1 || b !== 1, g = this.calculateClusterCount(
|
|
1414
1414
|
t,
|
|
1415
1415
|
a.clusterCount,
|
|
1416
1416
|
s,
|
|
@@ -1422,35 +1422,35 @@ class ue {
|
|
|
1422
1422
|
r,
|
|
1423
1423
|
h,
|
|
1424
1424
|
a
|
|
1425
|
-
),
|
|
1426
|
-
for (let
|
|
1427
|
-
|
|
1425
|
+
), S = new Array(g).fill(0);
|
|
1426
|
+
for (let x = 0; x < t; x++)
|
|
1427
|
+
S[x % g]++;
|
|
1428
1428
|
let v = 0;
|
|
1429
|
-
for (let
|
|
1430
|
-
const
|
|
1431
|
-
for (let C = 0; C <
|
|
1432
|
-
let z,
|
|
1429
|
+
for (let x = 0; x < g; x++) {
|
|
1430
|
+
const E = m[x], w = S[x];
|
|
1431
|
+
for (let C = 0; C < w; C++) {
|
|
1432
|
+
let z, F;
|
|
1433
1433
|
if (a.distribution === "gaussian")
|
|
1434
|
-
z = this.gaussianRandom() *
|
|
1434
|
+
z = this.gaussianRandom() * E.spread, F = this.gaussianRandom() * E.spread;
|
|
1435
1435
|
else {
|
|
1436
|
-
const
|
|
1437
|
-
z = Math.cos(
|
|
1436
|
+
const R = this.random(0, Math.PI * 2), U = this.random(0, E.spread);
|
|
1437
|
+
z = Math.cos(R) * U, F = Math.sin(R) * U;
|
|
1438
1438
|
}
|
|
1439
|
-
const
|
|
1440
|
-
z /=
|
|
1441
|
-
const
|
|
1442
|
-
let D =
|
|
1443
|
-
const A = T * 1.5 / 2,
|
|
1444
|
-
D = Math.max(h + A, Math.min(D, s - h - A)),
|
|
1445
|
-
const O = u === "random" ? this.random(l, d) : 0,
|
|
1439
|
+
const N = 1 + a.overlap * 0.5, H = 1 + a.overlap * 0.3;
|
|
1440
|
+
z /= N, F /= N;
|
|
1441
|
+
const X = p ? this.random(f, b) : 1, k = H * X, T = c * k;
|
|
1442
|
+
let D = E.x + z, W = E.y + F;
|
|
1443
|
+
const A = T * 1.5 / 2, M = T / 2;
|
|
1444
|
+
D = Math.max(h + A, Math.min(D, s - h - A)), W = Math.max(h + M, Math.min(W, r - h - M));
|
|
1445
|
+
const O = u === "random" ? this.random(l, d) : 0, L = Math.sqrt(z * z + F * F) / E.spread, P = Math.round((1 - L) * 50) + 1;
|
|
1446
1446
|
o.push({
|
|
1447
1447
|
id: v,
|
|
1448
1448
|
x: D,
|
|
1449
|
-
y:
|
|
1449
|
+
y: W,
|
|
1450
1450
|
rotation: O,
|
|
1451
|
-
scale:
|
|
1451
|
+
scale: k,
|
|
1452
1452
|
baseSize: T,
|
|
1453
|
-
zIndex:
|
|
1453
|
+
zIndex: P
|
|
1454
1454
|
}), v++;
|
|
1455
1455
|
}
|
|
1456
1456
|
}
|
|
@@ -1481,9 +1481,9 @@ class ue {
|
|
|
1481
1481
|
spread: this.calculateClusterSpread(s)
|
|
1482
1482
|
};
|
|
1483
1483
|
let m = 1 / 0;
|
|
1484
|
-
for (const
|
|
1485
|
-
const v = g.x -
|
|
1486
|
-
m = Math.min(m,
|
|
1484
|
+
for (const S of r) {
|
|
1485
|
+
const v = g.x - S.x, x = g.y - S.y, E = Math.sqrt(v * v + x * x);
|
|
1486
|
+
m = Math.min(m, E);
|
|
1487
1487
|
}
|
|
1488
1488
|
if ((r.length === 0 || m > b) && (f = g, b = m), m >= s.clusterSpacing)
|
|
1489
1489
|
break;
|
|
@@ -1516,7 +1516,7 @@ class ue {
|
|
|
1516
1516
|
return Math.random() * (e - t) + t;
|
|
1517
1517
|
}
|
|
1518
1518
|
}
|
|
1519
|
-
class
|
|
1519
|
+
class me {
|
|
1520
1520
|
constructor(t, e = {}) {
|
|
1521
1521
|
this.config = t, this.imageConfig = e;
|
|
1522
1522
|
}
|
|
@@ -1529,25 +1529,25 @@ class ge {
|
|
|
1529
1529
|
*/
|
|
1530
1530
|
generate(t, e, i = {}) {
|
|
1531
1531
|
const o = [], { width: s, height: r } = e, a = i.fixedHeight ?? 200, h = this.config.spacing.padding ?? 50, c = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, l = this.imageConfig.rotation?.range?.max ?? 15, d = this.imageConfig.sizing?.variance?.min ?? 1, f = this.imageConfig.sizing?.variance?.max ?? 1, b = d !== 1 || f !== 1, p = i.fixedHeight ?? a, g = {
|
|
1532
|
-
...
|
|
1532
|
+
...Pt,
|
|
1533
1533
|
...this.config.wave
|
|
1534
|
-
}, { rows: m, amplitude:
|
|
1534
|
+
}, { rows: m, amplitude: S, frequency: v, phaseShift: x, synchronization: E } = g, w = Math.ceil(t / m), F = p * 1.5 / 2, N = h + F, H = s - h - F, X = H - N, k = w > 1 ? X / (w - 1) : 0, T = h + S + p / 2, D = r - h - S - p / 2, W = D - T, j = m > 1 ? W / (m - 1) : 0;
|
|
1535
1535
|
let A = 0;
|
|
1536
|
-
for (let
|
|
1537
|
-
const O = m === 1 ? (T + D) / 2 : T +
|
|
1536
|
+
for (let M = 0; M < m && A < t; M++) {
|
|
1537
|
+
const O = m === 1 ? (T + D) / 2 : T + M * j;
|
|
1538
1538
|
let $ = 0;
|
|
1539
|
-
|
|
1540
|
-
for (let
|
|
1541
|
-
const
|
|
1539
|
+
E === "offset" ? $ = M * x : E === "alternating" && ($ = M * Math.PI);
|
|
1540
|
+
for (let L = 0; L < w && A < t; L++) {
|
|
1541
|
+
const P = w === 1 ? (N + H) / 2 : N + L * k, R = this.calculateWaveY(P, s, S, v, $), U = P, _ = O + R, Y = b ? this.random(d, f) : 1, B = p * Y;
|
|
1542
1542
|
let J = 0;
|
|
1543
|
-
c === "tangent" ? J = this.calculateRotation(
|
|
1544
|
-
const
|
|
1543
|
+
c === "tangent" ? J = this.calculateRotation(P, s, S, v, $) : c === "random" && (J = this.random(u, l));
|
|
1544
|
+
const Q = B * 1.5 / 2, ht = B / 2, ot = h + Q, st = s - h - Q, dt = h + ht, ut = r - h - ht;
|
|
1545
1545
|
o.push({
|
|
1546
1546
|
id: A,
|
|
1547
|
-
x: Math.max(
|
|
1548
|
-
y: Math.max(
|
|
1547
|
+
x: Math.max(ot, Math.min(U, st)),
|
|
1548
|
+
y: Math.max(dt, Math.min(_, ut)),
|
|
1549
1549
|
rotation: J,
|
|
1550
|
-
scale:
|
|
1550
|
+
scale: Y,
|
|
1551
1551
|
baseSize: B,
|
|
1552
1552
|
zIndex: A + 1
|
|
1553
1553
|
}), A++;
|
|
@@ -1593,7 +1593,7 @@ class ge {
|
|
|
1593
1593
|
return Math.random() * (e - t) + t;
|
|
1594
1594
|
}
|
|
1595
1595
|
}
|
|
1596
|
-
class
|
|
1596
|
+
class pe {
|
|
1597
1597
|
constructor(t) {
|
|
1598
1598
|
this.config = t.layout, this.imageConfig = t.image, this.layouts = /* @__PURE__ */ new Map(), this.placementLayout = this.initLayout();
|
|
1599
1599
|
}
|
|
@@ -1604,17 +1604,17 @@ class fe {
|
|
|
1604
1604
|
initLayout() {
|
|
1605
1605
|
switch (this.config.algorithm) {
|
|
1606
1606
|
case "radial":
|
|
1607
|
-
return new se(this.config, this.imageConfig);
|
|
1608
|
-
case "grid":
|
|
1609
1607
|
return new re(this.config, this.imageConfig);
|
|
1608
|
+
case "grid":
|
|
1609
|
+
return new le(this.config, this.imageConfig);
|
|
1610
1610
|
case "spiral":
|
|
1611
|
-
return new he(this.config, this.imageConfig);
|
|
1612
|
-
case "cluster":
|
|
1613
1611
|
return new ue(this.config, this.imageConfig);
|
|
1612
|
+
case "cluster":
|
|
1613
|
+
return new fe(this.config, this.imageConfig);
|
|
1614
1614
|
case "wave":
|
|
1615
|
-
return new
|
|
1615
|
+
return new me(this.config, this.imageConfig);
|
|
1616
1616
|
default:
|
|
1617
|
-
return new
|
|
1617
|
+
return new ae(this.config, this.imageConfig);
|
|
1618
1618
|
}
|
|
1619
1619
|
}
|
|
1620
1620
|
/**
|
|
@@ -1699,12 +1699,12 @@ class fe {
|
|
|
1699
1699
|
const a = s?.minSize ?? 50, h = s?.maxSize ?? 400, c = this.config.targetCoverage ?? 0.6, u = this.config.densityFactor ?? 1, { width: l, height: d } = t, p = l * d * c / e;
|
|
1700
1700
|
let m = Math.sqrt(p / 1.4);
|
|
1701
1701
|
m *= u, m = Math.min(m, i);
|
|
1702
|
-
let
|
|
1703
|
-
if (
|
|
1702
|
+
let S = this.clamp(m, a, h);
|
|
1703
|
+
if (S === a && m < a) {
|
|
1704
1704
|
const v = Math.max(a * 0.05, 20);
|
|
1705
|
-
|
|
1705
|
+
S = Math.max(v, m);
|
|
1706
1706
|
}
|
|
1707
|
-
return { height:
|
|
1707
|
+
return { height: S };
|
|
1708
1708
|
}
|
|
1709
1709
|
/**
|
|
1710
1710
|
* Utility: Clamp a value between min and max
|
|
@@ -1713,14 +1713,48 @@ class fe {
|
|
|
1713
1713
|
return Math.max(e, Math.min(i, t));
|
|
1714
1714
|
}
|
|
1715
1715
|
}
|
|
1716
|
+
const Z = class Z {
|
|
1717
|
+
/**
|
|
1718
|
+
* Register a loader implementation with the registry
|
|
1719
|
+
* @param name - Loader identifier (e.g., 'static', 'google-drive', 'composite')
|
|
1720
|
+
* @param Loader - Loader class constructor to register
|
|
1721
|
+
*/
|
|
1722
|
+
static registerLoader(t, e) {
|
|
1723
|
+
Z.registry.set(t, e);
|
|
1724
|
+
}
|
|
1725
|
+
/**
|
|
1726
|
+
* Get a registered loader implementation
|
|
1727
|
+
* @param name - Loader identifier
|
|
1728
|
+
* @returns Loader class constructor
|
|
1729
|
+
* @throws Error if loader is not registered
|
|
1730
|
+
*/
|
|
1731
|
+
static getLoader(t) {
|
|
1732
|
+
const e = Z.registry.get(t);
|
|
1733
|
+
if (!e)
|
|
1734
|
+
throw new Error(
|
|
1735
|
+
`Loader "${t}" is not registered. Import "@frybynite/image-cloud/loaders/${t}" or "@frybynite/image-cloud/loaders/all".`
|
|
1736
|
+
);
|
|
1737
|
+
return e;
|
|
1738
|
+
}
|
|
1739
|
+
/**
|
|
1740
|
+
* Check if a loader is registered
|
|
1741
|
+
* @param name - Loader identifier
|
|
1742
|
+
* @returns True if the loader is registered, false otherwise
|
|
1743
|
+
*/
|
|
1744
|
+
static isRegistered(t) {
|
|
1745
|
+
return Z.registry.has(t);
|
|
1746
|
+
}
|
|
1747
|
+
};
|
|
1748
|
+
Z.registry = /* @__PURE__ */ new Map();
|
|
1749
|
+
let et = Z;
|
|
1716
1750
|
var I = /* @__PURE__ */ ((n) => (n.IDLE = "idle", n.FOCUSING = "focusing", n.FOCUSED = "focused", n.UNFOCUSING = "unfocusing", n.CROSS_ANIMATING = "cross_animating", n))(I || {});
|
|
1717
|
-
function
|
|
1718
|
-
return n in
|
|
1751
|
+
function be(n) {
|
|
1752
|
+
return n in pt;
|
|
1719
1753
|
}
|
|
1720
|
-
function
|
|
1721
|
-
return n ?
|
|
1754
|
+
function ye(n) {
|
|
1755
|
+
return n ? be(n) ? pt[n] : n : pt.md;
|
|
1722
1756
|
}
|
|
1723
|
-
function
|
|
1757
|
+
function ve(n) {
|
|
1724
1758
|
if (!n) return "";
|
|
1725
1759
|
const t = [];
|
|
1726
1760
|
if (n.grayscale !== void 0 && t.push(`grayscale(${n.grayscale})`), n.blur !== void 0 && t.push(`blur(${n.blur}px)`), n.brightness !== void 0 && t.push(`brightness(${n.brightness})`), n.contrast !== void 0 && t.push(`contrast(${n.contrast})`), n.saturate !== void 0 && t.push(`saturate(${n.saturate})`), n.opacity !== void 0 && t.push(`opacity(${n.opacity})`), n.sepia !== void 0 && t.push(`sepia(${n.sepia})`), n.hueRotate !== void 0 && t.push(`hue-rotate(${n.hueRotate}deg)`), n.invert !== void 0 && t.push(`invert(${n.invert})`), n.dropShadow !== void 0)
|
|
@@ -1732,13 +1766,13 @@ function be(n) {
|
|
|
1732
1766
|
}
|
|
1733
1767
|
return t.join(" ");
|
|
1734
1768
|
}
|
|
1735
|
-
function
|
|
1769
|
+
function tt(n) {
|
|
1736
1770
|
if (!n || n.style === "none" || n.width === 0)
|
|
1737
1771
|
return "none";
|
|
1738
1772
|
const t = n.width ?? 0, e = n.style ?? "solid", i = n.color ?? "#000000";
|
|
1739
1773
|
return `${t}px ${e} ${i}`;
|
|
1740
1774
|
}
|
|
1741
|
-
function
|
|
1775
|
+
function rt(n) {
|
|
1742
1776
|
if (!n) return {};
|
|
1743
1777
|
const t = {};
|
|
1744
1778
|
if (n.borderRadiusTopLeft !== void 0 || n.borderRadiusTopRight !== void 0 || n.borderRadiusBottomRight !== void 0 || n.borderRadiusBottomLeft !== void 0) {
|
|
@@ -1747,41 +1781,41 @@ function st(n) {
|
|
|
1747
1781
|
} else n.border?.radius !== void 0 && (t.borderRadius = `${n.border.radius}px`);
|
|
1748
1782
|
if (n.borderTop || n.borderRight || n.borderBottom || n.borderLeft) {
|
|
1749
1783
|
const s = n.border || {}, r = { ...s, ...n.borderTop }, a = { ...s, ...n.borderRight }, h = { ...s, ...n.borderBottom }, c = { ...s, ...n.borderLeft };
|
|
1750
|
-
t.borderTop =
|
|
1751
|
-
} else n.border && (t.border =
|
|
1752
|
-
n.shadow !== void 0 && (t.boxShadow =
|
|
1753
|
-
const o =
|
|
1784
|
+
t.borderTop = tt(r), t.borderRight = tt(a), t.borderBottom = tt(h), t.borderLeft = tt(c);
|
|
1785
|
+
} else n.border && (t.border = tt(n.border));
|
|
1786
|
+
n.shadow !== void 0 && (t.boxShadow = ye(n.shadow));
|
|
1787
|
+
const o = ve(n.filter);
|
|
1754
1788
|
if (t.filter = o || "none", n.opacity !== void 0 && (t.opacity = String(n.opacity)), n.cursor !== void 0 && (t.cursor = n.cursor), n.outline && n.outline.style !== "none" && (n.outline.width ?? 0) > 0) {
|
|
1755
1789
|
const s = n.outline.width ?? 0, r = n.outline.style ?? "solid", a = n.outline.color ?? "#000000";
|
|
1756
1790
|
t.outline = `${s}px ${r} ${a}`, n.outline.offset !== void 0 && (t.outlineOffset = `${n.outline.offset}px`);
|
|
1757
1791
|
}
|
|
1758
1792
|
return n.objectFit !== void 0 && (t.objectFit = n.objectFit), n.aspectRatio !== void 0 && (t.aspectRatio = n.aspectRatio), t;
|
|
1759
1793
|
}
|
|
1760
|
-
function
|
|
1794
|
+
function it(n, t) {
|
|
1761
1795
|
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);
|
|
1762
1796
|
}
|
|
1763
|
-
function
|
|
1797
|
+
function Ft(n) {
|
|
1764
1798
|
return n ? Array.isArray(n) ? n.join(" ") : n : "";
|
|
1765
1799
|
}
|
|
1766
|
-
function
|
|
1767
|
-
const e =
|
|
1800
|
+
function nt(n, t) {
|
|
1801
|
+
const e = Ft(t);
|
|
1768
1802
|
e && e.split(" ").forEach((i) => {
|
|
1769
1803
|
i.trim() && n.classList.add(i.trim());
|
|
1770
1804
|
});
|
|
1771
1805
|
}
|
|
1772
|
-
function
|
|
1773
|
-
const e =
|
|
1806
|
+
function Lt(n, t) {
|
|
1807
|
+
const e = Ft(t);
|
|
1774
1808
|
e && e.split(" ").forEach((i) => {
|
|
1775
1809
|
i.trim() && n.classList.remove(i.trim());
|
|
1776
1810
|
});
|
|
1777
1811
|
}
|
|
1778
|
-
const
|
|
1812
|
+
const Tt = {
|
|
1779
1813
|
UNFOCUSING: 999,
|
|
1780
1814
|
FOCUSING: 1e3
|
|
1781
1815
|
};
|
|
1782
|
-
class
|
|
1816
|
+
class xe {
|
|
1783
1817
|
constructor(t, e, i) {
|
|
1784
|
-
this.state = I.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null, this.focusGeneration = 0, this.config = t, this.animationEngine = e, this.defaultStyles =
|
|
1818
|
+
this.state = I.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null, this.focusGeneration = 0, this.config = t, this.animationEngine = e, this.defaultStyles = rt(i?.default), this.focusedStyles = rt(i?.focused), this.defaultClassName = i?.default?.className, this.focusedClassName = i?.focused?.className;
|
|
1785
1819
|
}
|
|
1786
1820
|
/**
|
|
1787
1821
|
* Get current state machine state
|
|
@@ -1866,13 +1900,13 @@ class ye {
|
|
|
1866
1900
|
* Apply focused styling to an element
|
|
1867
1901
|
*/
|
|
1868
1902
|
applyFocusedStyling(t, e) {
|
|
1869
|
-
t.style.zIndex = String(e), t.classList.add("fbn-ic-focused"),
|
|
1903
|
+
t.style.zIndex = String(e), t.classList.add("fbn-ic-focused"), it(t, this.focusedStyles), nt(t, this.focusedClassName);
|
|
1870
1904
|
}
|
|
1871
1905
|
/**
|
|
1872
1906
|
* Remove focused styling from an element
|
|
1873
1907
|
*/
|
|
1874
1908
|
removeFocusedStyling(t, e) {
|
|
1875
|
-
t.style.zIndex = e, t.classList.remove("fbn-ic-focused"),
|
|
1909
|
+
t.style.zIndex = e, t.classList.remove("fbn-ic-focused"), Lt(t, this.focusedClassName), it(t, this.defaultStyles), nt(t, this.defaultClassName);
|
|
1876
1910
|
}
|
|
1877
1911
|
/**
|
|
1878
1912
|
* Start focus animation for an image using dimension-based zoom
|
|
@@ -1882,7 +1916,7 @@ class ye {
|
|
|
1882
1916
|
*/
|
|
1883
1917
|
startFocusAnimation(t, e, i, o, s) {
|
|
1884
1918
|
const r = t.style.zIndex || "", a = t.offsetWidth, h = t.offsetHeight, c = this.calculateFocusDimensions(a, h, e), u = this.calculateFocusTransform(e, i);
|
|
1885
|
-
this.applyFocusedStyling(t,
|
|
1919
|
+
this.applyFocusedStyling(t, Tt.FOCUSING), this.animationEngine.cancelAllAnimations(t);
|
|
1886
1920
|
const l = o ?? {
|
|
1887
1921
|
x: 0,
|
|
1888
1922
|
y: 0,
|
|
@@ -1931,7 +1965,7 @@ class ye {
|
|
|
1931
1965
|
* @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
|
|
1932
1966
|
*/
|
|
1933
1967
|
startUnfocusAnimation(t, e, i, o) {
|
|
1934
|
-
t.style.zIndex = String(
|
|
1968
|
+
t.style.zIndex = String(Tt.UNFOCUSING), this.animationEngine.cancelAllAnimations(t);
|
|
1935
1969
|
const s = i ?? this.focusData?.focusTransform ?? { x: 0, y: 0, rotation: 0, scale: 1 }, r = o?.width ?? this.focusData?.focusWidth ?? t.offsetWidth, a = o?.height ?? this.focusData?.focusHeight ?? t.offsetHeight, h = {
|
|
1936
1970
|
x: 0,
|
|
1937
1971
|
y: 0,
|
|
@@ -1965,6 +1999,27 @@ class ye {
|
|
|
1965
1999
|
originalHeight: u
|
|
1966
2000
|
};
|
|
1967
2001
|
}
|
|
2002
|
+
/**
|
|
2003
|
+
* Capture the current visual state of an element mid-animation, BEFORE cancelling.
|
|
2004
|
+
*
|
|
2005
|
+
* The computed matrix.e/f include the -50%/-50% centering offset resolved to pixels.
|
|
2006
|
+
* buildDimensionZoomTransform prepends its own translate(-50%,-50%), so passing raw
|
|
2007
|
+
* matrix.e/f doubles the centering and produces the wrong starting position.
|
|
2008
|
+
*
|
|
2009
|
+
* This method extracts the PURE positional offset (pureX = matrix.e + 0.5*midWidth)
|
|
2010
|
+
* and commits width/height/transform to inline styles before the animation is cancelled,
|
|
2011
|
+
* preventing any visual snap.
|
|
2012
|
+
*
|
|
2013
|
+
* Must be called while the animation is still running (offsetWidth reflects animated size).
|
|
2014
|
+
* Caller is responsible for calling animationEngine.cancelAllAnimations() afterwards.
|
|
2015
|
+
*/
|
|
2016
|
+
captureMidAnimationState(t) {
|
|
2017
|
+
const e = getComputedStyle(t), i = new DOMMatrix(e.transform), o = t.offsetWidth, s = t.offsetHeight, r = i.e + o * 0.5, a = i.f + s * 0.5, h = Math.atan2(i.b, i.a) * (180 / Math.PI);
|
|
2018
|
+
return t.style.width = `${o}px`, t.style.height = `${s}px`, t.style.transform = `translate(-50%, -50%) translate(${r}px, ${a}px) rotate(${h}deg)`, t.style.transition = "none", {
|
|
2019
|
+
transform: { x: r, y: a, rotation: h, scale: 1 },
|
|
2020
|
+
dimensions: { width: o, height: s }
|
|
2021
|
+
};
|
|
2022
|
+
}
|
|
1968
2023
|
/**
|
|
1969
2024
|
* Handle animation completion
|
|
1970
2025
|
*/
|
|
@@ -1990,21 +2045,12 @@ class ye {
|
|
|
1990
2045
|
if (this.currentFocus === t && this.state === I.FOCUSED)
|
|
1991
2046
|
return this.unfocusImage();
|
|
1992
2047
|
if (this.incoming?.element === t && this.state === I.FOCUSING) {
|
|
1993
|
-
const
|
|
1994
|
-
|
|
1995
|
-
y: s.y,
|
|
1996
|
-
rotation: s.rotation,
|
|
1997
|
-
scale: 1
|
|
1998
|
-
// No scale transform - using dimensions
|
|
1999
|
-
}, a = {
|
|
2000
|
-
width: t.offsetWidth,
|
|
2001
|
-
height: t.offsetHeight
|
|
2002
|
-
};
|
|
2003
|
-
this.outgoing = this.startUnfocusAnimation(
|
|
2048
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(t);
|
|
2049
|
+
this.animationEngine.cancelAllAnimations(t), this.outgoing = this.startUnfocusAnimation(
|
|
2004
2050
|
t,
|
|
2005
2051
|
this.incoming.originalState,
|
|
2006
|
-
|
|
2007
|
-
|
|
2052
|
+
s,
|
|
2053
|
+
r
|
|
2008
2054
|
), this.incoming = null, this.state = I.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 = I.IDLE;
|
|
2009
2055
|
return;
|
|
2010
2056
|
}
|
|
@@ -2046,36 +2092,18 @@ class ye {
|
|
|
2046
2092
|
if (this.incoming?.element === t)
|
|
2047
2093
|
return;
|
|
2048
2094
|
if (this.outgoing?.element === t) {
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
scale: 1
|
|
2054
|
-
// No scale - using dimensions
|
|
2055
|
-
}, a = {
|
|
2056
|
-
width: t.offsetWidth,
|
|
2057
|
-
height: t.offsetHeight
|
|
2058
|
-
};
|
|
2059
|
-
if (this.incoming) {
|
|
2060
|
-
const h = this.animationEngine.cancelAnimation(this.incoming.animationHandle, !0), c = {
|
|
2061
|
-
x: h.x,
|
|
2062
|
-
y: h.y,
|
|
2063
|
-
rotation: h.rotation,
|
|
2064
|
-
scale: 1
|
|
2065
|
-
// No scale - using dimensions
|
|
2066
|
-
}, u = {
|
|
2067
|
-
width: this.incoming.element.offsetWidth,
|
|
2068
|
-
height: this.incoming.element.offsetHeight
|
|
2069
|
-
};
|
|
2070
|
-
this.outgoing = this.startUnfocusAnimation(
|
|
2095
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(t);
|
|
2096
|
+
if (this.animationEngine.cancelAllAnimations(t), this.incoming) {
|
|
2097
|
+
const { transform: a, dimensions: h } = this.captureMidAnimationState(this.incoming.element);
|
|
2098
|
+
this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2071
2099
|
this.incoming.element,
|
|
2072
2100
|
this.incoming.originalState,
|
|
2073
|
-
|
|
2074
|
-
|
|
2101
|
+
a,
|
|
2102
|
+
h
|
|
2075
2103
|
);
|
|
2076
2104
|
} else
|
|
2077
2105
|
this.outgoing = null;
|
|
2078
|
-
if (this.incoming = this.startFocusAnimation(t, e, i,
|
|
2106
|
+
if (this.incoming = this.startFocusAnimation(t, e, i, s, r), await Promise.all([
|
|
2079
2107
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2080
2108
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2081
2109
|
]), this.focusGeneration !== o) return;
|
|
@@ -2089,21 +2117,12 @@ class ye {
|
|
|
2089
2117
|
this.outgoing.originalWidth,
|
|
2090
2118
|
this.outgoing.originalHeight
|
|
2091
2119
|
), this.outgoing = null), this.incoming) {
|
|
2092
|
-
const s = this.
|
|
2093
|
-
|
|
2094
|
-
y: s.y,
|
|
2095
|
-
rotation: s.rotation,
|
|
2096
|
-
scale: 1
|
|
2097
|
-
// No scale - using dimensions
|
|
2098
|
-
}, a = {
|
|
2099
|
-
width: this.incoming.element.offsetWidth,
|
|
2100
|
-
height: this.incoming.element.offsetHeight
|
|
2101
|
-
};
|
|
2102
|
-
this.outgoing = this.startUnfocusAnimation(
|
|
2120
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2121
|
+
this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2103
2122
|
this.incoming.element,
|
|
2104
2123
|
this.incoming.originalState,
|
|
2105
|
-
|
|
2106
|
-
|
|
2124
|
+
s,
|
|
2125
|
+
r
|
|
2107
2126
|
);
|
|
2108
2127
|
}
|
|
2109
2128
|
if (this.incoming = this.startFocusAnimation(t, e, i), await Promise.all([
|
|
@@ -2118,50 +2137,36 @@ class ye {
|
|
|
2118
2137
|
* Unfocus current image, returning it to original position
|
|
2119
2138
|
*/
|
|
2120
2139
|
async unfocusImage() {
|
|
2140
|
+
if (this.state === I.UNFOCUSING)
|
|
2141
|
+
return;
|
|
2121
2142
|
const t = ++this.focusGeneration;
|
|
2122
2143
|
if (!this.currentFocus || !this.focusData) {
|
|
2123
2144
|
if (this.incoming && this.state === I.FOCUSING) {
|
|
2124
|
-
const s = this.
|
|
2125
|
-
|
|
2126
|
-
y: s.y,
|
|
2127
|
-
rotation: s.rotation,
|
|
2128
|
-
scale: 1
|
|
2129
|
-
// No scale - using dimensions
|
|
2130
|
-
}, a = {
|
|
2131
|
-
width: this.incoming.element.offsetWidth,
|
|
2132
|
-
height: this.incoming.element.offsetHeight
|
|
2133
|
-
};
|
|
2134
|
-
if (this.outgoing = this.startUnfocusAnimation(
|
|
2145
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2146
|
+
if (this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2135
2147
|
this.incoming.element,
|
|
2136
2148
|
this.incoming.originalState,
|
|
2137
|
-
|
|
2138
|
-
|
|
2149
|
+
s,
|
|
2150
|
+
r
|
|
2139
2151
|
), this.incoming = null, this.state = I.UNFOCUSING, await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration !== t) return;
|
|
2140
2152
|
this.removeFocusedStyling(this.outgoing.element, this.focusData?.originalZIndex || ""), this.outgoing = null, this.focusData = null, this.state = I.IDLE;
|
|
2141
2153
|
}
|
|
2142
2154
|
return;
|
|
2143
2155
|
}
|
|
2144
2156
|
if (this.state === I.CROSS_ANIMATING && this.incoming) {
|
|
2145
|
-
const s = this.
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
rotation: s.rotation,
|
|
2149
|
-
scale: 1
|
|
2150
|
-
// No scale - using dimensions
|
|
2151
|
-
}, a = {
|
|
2152
|
-
width: this.incoming.element.offsetWidth,
|
|
2153
|
-
height: this.incoming.element.offsetHeight
|
|
2154
|
-
}, h = this.startUnfocusAnimation(
|
|
2157
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2158
|
+
this.animationEngine.cancelAllAnimations(this.incoming.element);
|
|
2159
|
+
const a = this.startUnfocusAnimation(
|
|
2155
2160
|
this.incoming.element,
|
|
2156
2161
|
this.incoming.originalState,
|
|
2157
|
-
|
|
2158
|
-
|
|
2162
|
+
s,
|
|
2163
|
+
r
|
|
2159
2164
|
);
|
|
2160
2165
|
if (await Promise.all([
|
|
2161
2166
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2162
|
-
this.waitForAnimation(
|
|
2167
|
+
this.waitForAnimation(a.animationHandle)
|
|
2163
2168
|
]), this.focusGeneration !== t) return;
|
|
2164
|
-
this.outgoing && this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.removeFocusedStyling(
|
|
2169
|
+
this.outgoing && this.removeFocusedStyling(this.outgoing.element, this.outgoing.originalState.zIndex?.toString() || ""), this.removeFocusedStyling(a.element, this.incoming.originalState.zIndex?.toString() || ""), this.outgoing = null, this.incoming = null, this.currentFocus = null, this.focusData = null, this.state = I.IDLE;
|
|
2165
2170
|
return;
|
|
2166
2171
|
}
|
|
2167
2172
|
this.state = I.UNFOCUSING;
|
|
@@ -2248,7 +2253,7 @@ class ye {
|
|
|
2248
2253
|
), this.state = I.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null;
|
|
2249
2254
|
}
|
|
2250
2255
|
}
|
|
2251
|
-
const
|
|
2256
|
+
const we = 50, Se = 0.5, Ee = 20, Ie = 0.3, Ce = 150, Te = 30, ct = class ct {
|
|
2252
2257
|
constructor(t, e) {
|
|
2253
2258
|
this.enabled = !1, this.touchState = null, this.recentTouchTimestamp = 0, this.container = t, this.callbacks = e, this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchMove = this.handleTouchMove.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundTouchCancel = this.handleTouchCancel.bind(this);
|
|
2254
2259
|
}
|
|
@@ -2275,7 +2280,7 @@ const ve = 50, we = 0.5, xe = 20, Ee = 0.3, Se = 150, Ie = 30, at = class at {
|
|
|
2275
2280
|
* Used to prevent click-outside from unfocusing immediately after touch
|
|
2276
2281
|
*/
|
|
2277
2282
|
hadRecentTouch() {
|
|
2278
|
-
return Date.now() - this.recentTouchTimestamp <
|
|
2283
|
+
return Date.now() - this.recentTouchTimestamp < ct.TOUCH_CLICK_DELAY;
|
|
2279
2284
|
}
|
|
2280
2285
|
handleTouchStart(t) {
|
|
2281
2286
|
if (t.touches.length !== 1) return;
|
|
@@ -2295,11 +2300,11 @@ const ve = 50, we = 0.5, xe = 20, Ee = 0.3, Se = 150, Ie = 30, at = class at {
|
|
|
2295
2300
|
const e = t.touches[0], i = e.clientX - this.touchState.startX, o = e.clientY - this.touchState.startY;
|
|
2296
2301
|
if (this.touchState.isHorizontalSwipe === null && Math.sqrt(i * i + o * o) > 10) {
|
|
2297
2302
|
const a = Math.atan2(Math.abs(o), Math.abs(i)) * (180 / Math.PI);
|
|
2298
|
-
this.touchState.isHorizontalSwipe = a <=
|
|
2303
|
+
this.touchState.isHorizontalSwipe = a <= Te;
|
|
2299
2304
|
}
|
|
2300
2305
|
if (this.touchState.isHorizontalSwipe !== !1 && this.touchState.isHorizontalSwipe === !0) {
|
|
2301
2306
|
t.preventDefault(), this.touchState.isDragging = !0, this.touchState.currentX = e.clientX;
|
|
2302
|
-
const s = i *
|
|
2307
|
+
const s = i * Ie;
|
|
2303
2308
|
this.callbacks.onDragOffset(s);
|
|
2304
2309
|
}
|
|
2305
2310
|
}
|
|
@@ -2308,473 +2313,15 @@ const ve = 50, we = 0.5, xe = 20, Ee = 0.3, Se = 150, Ie = 30, at = class at {
|
|
|
2308
2313
|
this.recentTouchTimestamp = Date.now();
|
|
2309
2314
|
const e = this.touchState.currentX - this.touchState.startX, i = performance.now() - this.touchState.startTime, o = Math.abs(e) / i, s = Math.abs(e);
|
|
2310
2315
|
let r = !1;
|
|
2311
|
-
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (s >=
|
|
2316
|
+
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (s >= we || o >= Se && s >= Ee) && (r = !0, e < 0 ? this.callbacks.onNext() : this.callbacks.onPrev()), this.touchState.isDragging && this.callbacks.onDragEnd(r), this.touchState = null;
|
|
2312
2317
|
}
|
|
2313
2318
|
handleTouchCancel(t) {
|
|
2314
2319
|
this.touchState?.isDragging && this.callbacks.onDragEnd(!1), this.touchState = null;
|
|
2315
2320
|
}
|
|
2316
2321
|
};
|
|
2317
|
-
|
|
2318
|
-
let
|
|
2319
|
-
class
|
|
2320
|
-
constructor(t) {
|
|
2321
|
-
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)
|
|
2322
|
-
throw new Error("GoogleDriveLoader requires at least one source to be configured");
|
|
2323
|
-
}
|
|
2324
|
-
/**
|
|
2325
|
-
* Prepare the loader by discovering all images from configured sources
|
|
2326
|
-
* @param filter - Filter to apply to discovered images
|
|
2327
|
-
*/
|
|
2328
|
-
async prepare(t) {
|
|
2329
|
-
this._discoveredUrls = [];
|
|
2330
|
-
for (const e of this.sources)
|
|
2331
|
-
if ("folders" in e)
|
|
2332
|
-
for (const i of e.folders) {
|
|
2333
|
-
const o = e.recursive !== void 0 ? e.recursive : !0, s = await this.loadFromFolder(i, t, o);
|
|
2334
|
-
this._discoveredUrls.push(...s);
|
|
2335
|
-
}
|
|
2336
|
-
else if ("files" in e) {
|
|
2337
|
-
const i = await this.loadFiles(e.files, t);
|
|
2338
|
-
this._discoveredUrls.push(...i);
|
|
2339
|
-
}
|
|
2340
|
-
this._prepared = !0;
|
|
2341
|
-
}
|
|
2342
|
-
/**
|
|
2343
|
-
* Get the number of discovered images
|
|
2344
|
-
* @throws Error if called before prepare()
|
|
2345
|
-
*/
|
|
2346
|
-
imagesLength() {
|
|
2347
|
-
if (!this._prepared)
|
|
2348
|
-
throw new Error("GoogleDriveLoader.imagesLength() called before prepare()");
|
|
2349
|
-
return this._discoveredUrls.length;
|
|
2350
|
-
}
|
|
2351
|
-
/**
|
|
2352
|
-
* Get the ordered list of image URLs
|
|
2353
|
-
* @throws Error if called before prepare()
|
|
2354
|
-
*/
|
|
2355
|
-
imageURLs() {
|
|
2356
|
-
if (!this._prepared)
|
|
2357
|
-
throw new Error("GoogleDriveLoader.imageURLs() called before prepare()");
|
|
2358
|
-
return [...this._discoveredUrls];
|
|
2359
|
-
}
|
|
2360
|
-
/**
|
|
2361
|
-
* Check if the loader has been prepared
|
|
2362
|
-
*/
|
|
2363
|
-
isPrepared() {
|
|
2364
|
-
return this._prepared;
|
|
2365
|
-
}
|
|
2366
|
-
/**
|
|
2367
|
-
* Extract folder ID from various Google Drive URL formats
|
|
2368
|
-
* @param folderUrl - Google Drive folder URL
|
|
2369
|
-
* @returns Folder ID or null if invalid
|
|
2370
|
-
*/
|
|
2371
|
-
extractFolderId(t) {
|
|
2372
|
-
const e = [
|
|
2373
|
-
/\/folders\/([a-zA-Z0-9_-]+)/,
|
|
2374
|
-
// Standard format
|
|
2375
|
-
/id=([a-zA-Z0-9_-]+)/
|
|
2376
|
-
// Alternative format
|
|
2377
|
-
];
|
|
2378
|
-
for (const i of e) {
|
|
2379
|
-
const o = t.match(i);
|
|
2380
|
-
if (o && o[1])
|
|
2381
|
-
return o[1];
|
|
2382
|
-
}
|
|
2383
|
-
return null;
|
|
2384
|
-
}
|
|
2385
|
-
/**
|
|
2386
|
-
* Load images from a Google Drive folder
|
|
2387
|
-
* @param folderUrl - Google Drive folder URL
|
|
2388
|
-
* @param filter - Filter to apply to discovered images
|
|
2389
|
-
* @param recursive - Whether to include images from subfolders
|
|
2390
|
-
* @returns Promise resolving to array of image URLs
|
|
2391
|
-
*/
|
|
2392
|
-
async loadFromFolder(t, e, i = !0) {
|
|
2393
|
-
const o = this.extractFolderId(t);
|
|
2394
|
-
if (!o)
|
|
2395
|
-
throw new Error("Invalid Google Drive folder URL. Please check the URL format.");
|
|
2396
|
-
if (!this.apiKey || this.apiKey === "YOUR_API_KEY_HERE")
|
|
2397
|
-
return this.loadImagesDirectly(o, e);
|
|
2398
|
-
try {
|
|
2399
|
-
return i ? await this.loadImagesRecursively(o, e) : await this.loadImagesFromSingleFolder(o, e);
|
|
2400
|
-
} catch (s) {
|
|
2401
|
-
return console.error("Error loading from Google Drive API:", s), this.loadImagesDirectly(o, e);
|
|
2402
|
-
}
|
|
2403
|
-
}
|
|
2404
|
-
/**
|
|
2405
|
-
* Load images from a single folder (non-recursive)
|
|
2406
|
-
* @param folderId - Google Drive folder ID
|
|
2407
|
-
* @param filter - Filter to apply to discovered images
|
|
2408
|
-
* @returns Promise resolving to array of image URLs
|
|
2409
|
-
*/
|
|
2410
|
-
async loadImagesFromSingleFolder(t, e) {
|
|
2411
|
-
const i = [], o = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(o)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
|
|
2412
|
-
if (!a.ok)
|
|
2413
|
-
throw new Error(`API request failed: ${a.status} ${a.statusText}`);
|
|
2414
|
-
const c = (await a.json()).files.filter(
|
|
2415
|
-
(u) => u.mimeType.startsWith("image/") && e.isAllowed(u.name)
|
|
2416
|
-
);
|
|
2417
|
-
return this.log(`Found ${c.length} images in folder ${t} (non-recursive)`), c.forEach((u) => {
|
|
2418
|
-
i.push(`https://lh3.googleusercontent.com/d/${u.id}=s1600`), this.log(`Added file: ${u.name}`);
|
|
2419
|
-
}), i;
|
|
2420
|
-
}
|
|
2421
|
-
/**
|
|
2422
|
-
* Load specific files by their URLs or IDs
|
|
2423
|
-
* @param fileUrls - Array of Google Drive file URLs or IDs
|
|
2424
|
-
* @param filter - Filter to apply to discovered images
|
|
2425
|
-
* @returns Promise resolving to array of image URLs
|
|
2426
|
-
*/
|
|
2427
|
-
async loadFiles(t, e) {
|
|
2428
|
-
const i = [];
|
|
2429
|
-
for (const o of t) {
|
|
2430
|
-
const s = this.extractFileId(o);
|
|
2431
|
-
if (!s) {
|
|
2432
|
-
this.log(`Skipping invalid file URL: ${o}`);
|
|
2433
|
-
continue;
|
|
2434
|
-
}
|
|
2435
|
-
if (this.apiKey && this.apiKey !== "YOUR_API_KEY_HERE")
|
|
2436
|
-
try {
|
|
2437
|
-
const r = `${this.apiEndpoint}/${s}?fields=name,mimeType&key=${this.apiKey}`, a = await fetch(r);
|
|
2438
|
-
if (a.ok) {
|
|
2439
|
-
const h = await a.json();
|
|
2440
|
-
h.mimeType.startsWith("image/") && e.isAllowed(h.name) ? (i.push(`https://lh3.googleusercontent.com/d/${s}=s1600`), this.log(`Added file: ${h.name}`)) : this.log(`Skipping non-image file: ${h.name} (${h.mimeType})`);
|
|
2441
|
-
} else
|
|
2442
|
-
this.log(`Failed to fetch metadata for file ${s}: ${a.status}`);
|
|
2443
|
-
} catch (r) {
|
|
2444
|
-
this.log(`Error fetching metadata for file ${s}:`, r);
|
|
2445
|
-
}
|
|
2446
|
-
else
|
|
2447
|
-
i.push(`https://lh3.googleusercontent.com/d/${s}=s1600`);
|
|
2448
|
-
}
|
|
2449
|
-
return i;
|
|
2450
|
-
}
|
|
2451
|
-
/**
|
|
2452
|
-
* Extract file ID from Google Drive file URL
|
|
2453
|
-
* @param fileUrl - Google Drive file URL or file ID
|
|
2454
|
-
* @returns File ID or null if invalid
|
|
2455
|
-
*/
|
|
2456
|
-
extractFileId(t) {
|
|
2457
|
-
if (!/[/:.]/.test(t))
|
|
2458
|
-
return t;
|
|
2459
|
-
const e = [
|
|
2460
|
-
/\/file\/d\/([a-zA-Z0-9_-]+)/,
|
|
2461
|
-
// Standard file format
|
|
2462
|
-
/\/open\?id=([a-zA-Z0-9_-]+)/,
|
|
2463
|
-
// Alternative format
|
|
2464
|
-
/id=([a-zA-Z0-9_-]+)/
|
|
2465
|
-
// Generic id parameter
|
|
2466
|
-
];
|
|
2467
|
-
for (const i of e) {
|
|
2468
|
-
const o = t.match(i);
|
|
2469
|
-
if (o && o[1])
|
|
2470
|
-
return o[1];
|
|
2471
|
-
}
|
|
2472
|
-
return null;
|
|
2473
|
-
}
|
|
2474
|
-
/**
|
|
2475
|
-
* Recursively load images from a folder and all its subfolders
|
|
2476
|
-
* @param folderId - Google Drive folder ID
|
|
2477
|
-
* @param filter - Filter to apply to discovered images
|
|
2478
|
-
* @returns Promise resolving to array of image URLs
|
|
2479
|
-
*/
|
|
2480
|
-
async loadImagesRecursively(t, e) {
|
|
2481
|
-
const i = [], o = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(o)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
|
|
2482
|
-
if (!a.ok)
|
|
2483
|
-
throw new Error(`API request failed: ${a.status} ${a.statusText}`);
|
|
2484
|
-
const h = await a.json(), c = h.files.filter(
|
|
2485
|
-
(l) => l.mimeType.startsWith("image/") && e.isAllowed(l.name)
|
|
2486
|
-
), u = h.files.filter(
|
|
2487
|
-
(l) => l.mimeType === "application/vnd.google-apps.folder"
|
|
2488
|
-
);
|
|
2489
|
-
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(`- ${u.length} subfolders`), c.forEach((l) => {
|
|
2490
|
-
i.push(`https://lh3.googleusercontent.com/d/${l.id}=s1600`), this.log(`Added file: ${l.name}`);
|
|
2491
|
-
});
|
|
2492
|
-
for (const l of u) {
|
|
2493
|
-
this.log(`Loading images from subfolder: ${l.name}`);
|
|
2494
|
-
const d = await this.loadImagesRecursively(l.id, e);
|
|
2495
|
-
i.push(...d);
|
|
2496
|
-
}
|
|
2497
|
-
return i;
|
|
2498
|
-
}
|
|
2499
|
-
/**
|
|
2500
|
-
* Direct loading method (no API key required, but less reliable)
|
|
2501
|
-
* Uses embedded folder view to scrape image IDs
|
|
2502
|
-
* @param folderId - Google Drive folder ID
|
|
2503
|
-
* @param filter - Filter to apply (not used in fallback mode)
|
|
2504
|
-
* @returns Promise resolving to array of image URLs
|
|
2505
|
-
*/
|
|
2506
|
-
async loadImagesDirectly(t, e) {
|
|
2507
|
-
try {
|
|
2508
|
-
const i = `https://drive.google.com/embeddedfolderview?id=${t}`, o = await fetch(i, { mode: "cors" });
|
|
2509
|
-
if (!o.ok)
|
|
2510
|
-
throw new Error("Cannot access folder directly (CORS or permissions issue)");
|
|
2511
|
-
const s = await o.text(), r = /\/file\/d\/([a-zA-Z0-9_-]+)/g, a = [...s.matchAll(r)];
|
|
2512
|
-
return [...new Set(a.map((u) => u[1]))].map(
|
|
2513
|
-
(u) => `https://drive.google.com/uc?export=view&id=${u}`
|
|
2514
|
-
);
|
|
2515
|
-
} catch (i) {
|
|
2516
|
-
throw console.error("Direct loading failed:", i), new Error(
|
|
2517
|
-
`Unable to load images. Please ensure:
|
|
2518
|
-
1. The folder is shared publicly (Anyone with the link can view)
|
|
2519
|
-
2. The folder contains image files
|
|
2520
|
-
3. Consider adding a Google Drive API key in config.js for better reliability`
|
|
2521
|
-
);
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
/**
|
|
2525
|
-
* Manually add image URLs (for testing or when auto-loading fails)
|
|
2526
|
-
* @param imageIds - Array of Google Drive file IDs
|
|
2527
|
-
* @returns Array of direct image URLs
|
|
2528
|
-
*/
|
|
2529
|
-
manualImageUrls(t) {
|
|
2530
|
-
return t.map((e) => `https://drive.google.com/uc?export=view&id=${e}`);
|
|
2531
|
-
}
|
|
2532
|
-
/**
|
|
2533
|
-
* Debug logging helper
|
|
2534
|
-
* @param args - Arguments to log
|
|
2535
|
-
*/
|
|
2536
|
-
log(...t) {
|
|
2537
|
-
this.debugLogging && typeof console < "u" && console.log(...t);
|
|
2538
|
-
}
|
|
2539
|
-
}
|
|
2540
|
-
class Te {
|
|
2541
|
-
constructor(t) {
|
|
2542
|
-
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)
|
|
2543
|
-
throw new Error("StaticImageLoader requires at least one source to be configured");
|
|
2544
|
-
this.log("StaticImageLoader initialized with config:", t);
|
|
2545
|
-
}
|
|
2546
|
-
/**
|
|
2547
|
-
* Prepare the loader by discovering all images from configured sources
|
|
2548
|
-
* @param filter - Filter to apply to discovered images
|
|
2549
|
-
*/
|
|
2550
|
-
async prepare(t) {
|
|
2551
|
-
this._discoveredUrls = [], this.log(`Processing ${this.sources.length} source(s)`);
|
|
2552
|
-
for (const e of this.sources)
|
|
2553
|
-
try {
|
|
2554
|
-
const i = await this.processSource(e, t);
|
|
2555
|
-
this._discoveredUrls.push(...i);
|
|
2556
|
-
} catch (i) {
|
|
2557
|
-
console.warn("Failed to process source:", e, i);
|
|
2558
|
-
}
|
|
2559
|
-
this._prepared = !0, this.log(`Successfully loaded ${this._discoveredUrls.length} image(s)`);
|
|
2560
|
-
}
|
|
2561
|
-
/**
|
|
2562
|
-
* Get the number of discovered images
|
|
2563
|
-
* @throws Error if called before prepare()
|
|
2564
|
-
*/
|
|
2565
|
-
imagesLength() {
|
|
2566
|
-
if (!this._prepared)
|
|
2567
|
-
throw new Error("StaticImageLoader.imagesLength() called before prepare()");
|
|
2568
|
-
return this._discoveredUrls.length;
|
|
2569
|
-
}
|
|
2570
|
-
/**
|
|
2571
|
-
* Get the ordered list of image URLs
|
|
2572
|
-
* @throws Error if called before prepare()
|
|
2573
|
-
*/
|
|
2574
|
-
imageURLs() {
|
|
2575
|
-
if (!this._prepared)
|
|
2576
|
-
throw new Error("StaticImageLoader.imageURLs() called before prepare()");
|
|
2577
|
-
return [...this._discoveredUrls];
|
|
2578
|
-
}
|
|
2579
|
-
/**
|
|
2580
|
-
* Check if the loader has been prepared
|
|
2581
|
-
*/
|
|
2582
|
-
isPrepared() {
|
|
2583
|
-
return this._prepared;
|
|
2584
|
-
}
|
|
2585
|
-
/**
|
|
2586
|
-
* Process a single source object using shape-based detection
|
|
2587
|
-
* @param source - Source configuration detected by key presence
|
|
2588
|
-
* @param filter - Filter to apply to discovered images
|
|
2589
|
-
* @returns Promise resolving to array of valid URLs from this source
|
|
2590
|
-
*/
|
|
2591
|
-
async processSource(t, e) {
|
|
2592
|
-
return t ? "urls" in t ? await this.processUrls(t.urls, e) : "path" in t ? await this.processPath(t.path, t.files, e) : "json" in t ? await this.processJson(t.json, e) : (console.warn("Unknown source shape:", t), []) : (console.warn("Invalid source object:", t), []);
|
|
2593
|
-
}
|
|
2594
|
-
/**
|
|
2595
|
-
* Process a list of direct URLs
|
|
2596
|
-
* @param urls - Array of image URLs
|
|
2597
|
-
* @param filter - Filter to apply to discovered images
|
|
2598
|
-
* @returns Promise resolving to array of validated URLs
|
|
2599
|
-
*/
|
|
2600
|
-
async processUrls(t, e) {
|
|
2601
|
-
if (!Array.isArray(t))
|
|
2602
|
-
return console.warn("URLs must be an array:", t), [];
|
|
2603
|
-
const i = [];
|
|
2604
|
-
for (const o of t) {
|
|
2605
|
-
const s = o.split("/").pop() || o;
|
|
2606
|
-
if (!e.isAllowed(s)) {
|
|
2607
|
-
this.log(`Skipping filtered URL: ${o}`);
|
|
2608
|
-
continue;
|
|
2609
|
-
}
|
|
2610
|
-
this.validateUrls ? await this.validateUrl(o) ? i.push(o) : console.warn(`Skipping invalid/missing URL: ${o}`) : i.push(o);
|
|
2611
|
-
}
|
|
2612
|
-
return i;
|
|
2613
|
-
}
|
|
2614
|
-
/**
|
|
2615
|
-
* Process a path-based source
|
|
2616
|
-
* @param basePath - Base path (relative or absolute)
|
|
2617
|
-
* @param files - Array of filenames
|
|
2618
|
-
* @param filter - Filter to apply to discovered images
|
|
2619
|
-
* @returns Promise resolving to array of validated URLs
|
|
2620
|
-
*/
|
|
2621
|
-
async processPath(t, e, i) {
|
|
2622
|
-
if (!Array.isArray(e))
|
|
2623
|
-
return console.warn("files must be an array:", e), [];
|
|
2624
|
-
const o = [];
|
|
2625
|
-
for (const s of e) {
|
|
2626
|
-
if (!i.isAllowed(s)) {
|
|
2627
|
-
this.log(`Skipping filtered file: ${s}`);
|
|
2628
|
-
continue;
|
|
2629
|
-
}
|
|
2630
|
-
const r = this.constructUrl(t, s);
|
|
2631
|
-
this.validateUrls ? await this.validateUrl(r) ? o.push(r) : console.warn(`Skipping invalid/missing file: ${r}`) : o.push(r);
|
|
2632
|
-
}
|
|
2633
|
-
return o;
|
|
2634
|
-
}
|
|
2635
|
-
/**
|
|
2636
|
-
* Process a JSON endpoint source
|
|
2637
|
-
* Fetches a JSON endpoint that returns { images: string[] }
|
|
2638
|
-
* @param url - JSON endpoint URL
|
|
2639
|
-
* @param filter - Filter to apply to discovered images
|
|
2640
|
-
* @returns Promise resolving to array of validated URLs
|
|
2641
|
-
*/
|
|
2642
|
-
async processJson(t, e) {
|
|
2643
|
-
this.log(`Fetching JSON endpoint: ${t}`);
|
|
2644
|
-
const i = new AbortController(), o = setTimeout(() => i.abort(), 1e4);
|
|
2645
|
-
try {
|
|
2646
|
-
const s = await fetch(t, { signal: i.signal });
|
|
2647
|
-
if (clearTimeout(o), !s.ok)
|
|
2648
|
-
throw new Error(`HTTP ${s.status} fetching ${t}`);
|
|
2649
|
-
const r = await s.json();
|
|
2650
|
-
if (!r || !Array.isArray(r.images))
|
|
2651
|
-
throw new Error('JSON source must return JSON with shape { "images": ["url1", "url2", ...] }');
|
|
2652
|
-
return this.log(`JSON endpoint returned ${r.images.length} image(s)`), await this.processUrls(r.images, e);
|
|
2653
|
-
} catch (s) {
|
|
2654
|
-
throw clearTimeout(o), s instanceof Error && s.name === "AbortError" ? new Error(`Timeout fetching JSON endpoint: ${t}`) : s;
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
/**
|
|
2658
|
-
* Validate a single URL using HEAD request
|
|
2659
|
-
* @param url - URL to validate
|
|
2660
|
-
* @returns Promise resolving to true if valid and accessible
|
|
2661
|
-
*/
|
|
2662
|
-
async validateUrl(t) {
|
|
2663
|
-
if (this.validationMethod === "none")
|
|
2664
|
-
return !0;
|
|
2665
|
-
if (this.validationMethod === "simple")
|
|
2666
|
-
try {
|
|
2667
|
-
return typeof window < "u" ? new URL(t, window.location.origin) : new URL(t), !0;
|
|
2668
|
-
} catch {
|
|
2669
|
-
return !1;
|
|
2670
|
-
}
|
|
2671
|
-
if (typeof window > "u")
|
|
2672
|
-
return !0;
|
|
2673
|
-
if (!(t.startsWith(window.location.origin) || t.startsWith("/")))
|
|
2674
|
-
return this.log(`Skipping validation for cross-origin URL: ${t}`), !0;
|
|
2675
|
-
try {
|
|
2676
|
-
const i = new AbortController(), o = setTimeout(() => i.abort(), this.validationTimeout), s = await fetch(t, {
|
|
2677
|
-
method: "HEAD",
|
|
2678
|
-
signal: i.signal
|
|
2679
|
-
});
|
|
2680
|
-
return clearTimeout(o), s.ok ? !0 : (this.log(`Validation failed for ${t}: HTTP ${s.status}`), !1);
|
|
2681
|
-
} catch (i) {
|
|
2682
|
-
return i instanceof Error && (i.name === "AbortError" ? this.log(`Validation timeout for ${t}`) : this.log(`Validation failed for ${t}:`, i.message)), !1;
|
|
2683
|
-
}
|
|
2684
|
-
}
|
|
2685
|
-
/**
|
|
2686
|
-
* Construct full URL from basePath and filename
|
|
2687
|
-
* @param basePath - Base path (relative or absolute)
|
|
2688
|
-
* @param filename - Filename to append
|
|
2689
|
-
* @returns Complete URL
|
|
2690
|
-
*/
|
|
2691
|
-
constructUrl(t, e) {
|
|
2692
|
-
const i = t.replace(/\/$/, "");
|
|
2693
|
-
if (this.isAbsoluteUrl(t))
|
|
2694
|
-
return `${i}/${e}`;
|
|
2695
|
-
if (typeof window > "u")
|
|
2696
|
-
return `${i}/${e}`;
|
|
2697
|
-
const o = window.location.origin, r = (t.startsWith("/") ? t : "/" + t).replace(/\/$/, "");
|
|
2698
|
-
return `${o}${r}/${e}`;
|
|
2699
|
-
}
|
|
2700
|
-
/**
|
|
2701
|
-
* Check if URL is absolute (contains protocol)
|
|
2702
|
-
* @param url - URL to check
|
|
2703
|
-
* @returns True if absolute URL
|
|
2704
|
-
*/
|
|
2705
|
-
isAbsoluteUrl(t) {
|
|
2706
|
-
try {
|
|
2707
|
-
return new URL(t), !0;
|
|
2708
|
-
} catch {
|
|
2709
|
-
return !1;
|
|
2710
|
-
}
|
|
2711
|
-
}
|
|
2712
|
-
/**
|
|
2713
|
-
* Debug logging helper
|
|
2714
|
-
* @param args - Arguments to log
|
|
2715
|
-
*/
|
|
2716
|
-
log(...t) {
|
|
2717
|
-
this.debugLogging && typeof console < "u" && console.log(...t);
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
|
-
class Re {
|
|
2721
|
-
constructor(t) {
|
|
2722
|
-
if (this._prepared = !1, this._discoveredUrls = [], this.loaders = t.loaders, this.debugLogging = t.debugLogging ?? !1, !this.loaders || this.loaders.length === 0)
|
|
2723
|
-
throw new Error("CompositeLoader requires at least one loader to be configured");
|
|
2724
|
-
this.log(`CompositeLoader initialized with ${this.loaders.length} loader(s)`);
|
|
2725
|
-
}
|
|
2726
|
-
/**
|
|
2727
|
-
* Prepare all loaders in parallel and combine their results
|
|
2728
|
-
* @param filter - Filter to apply to discovered images
|
|
2729
|
-
*/
|
|
2730
|
-
async prepare(t) {
|
|
2731
|
-
this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);
|
|
2732
|
-
const e = this.loaders.map((i, o) => i.prepare(t).then(() => {
|
|
2733
|
-
this.log(`Loader ${o} prepared with ${i.imagesLength()} images`);
|
|
2734
|
-
}).catch((s) => {
|
|
2735
|
-
console.warn(`Loader ${o} failed to prepare:`, s);
|
|
2736
|
-
}));
|
|
2737
|
-
await Promise.all(e);
|
|
2738
|
-
for (const i of this.loaders)
|
|
2739
|
-
if (i.isPrepared()) {
|
|
2740
|
-
const o = i.imageURLs();
|
|
2741
|
-
this._discoveredUrls.push(...o);
|
|
2742
|
-
}
|
|
2743
|
-
this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);
|
|
2744
|
-
}
|
|
2745
|
-
/**
|
|
2746
|
-
* Get the combined number of discovered images
|
|
2747
|
-
* @throws Error if called before prepare()
|
|
2748
|
-
*/
|
|
2749
|
-
imagesLength() {
|
|
2750
|
-
if (!this._prepared)
|
|
2751
|
-
throw new Error("CompositeLoader.imagesLength() called before prepare()");
|
|
2752
|
-
return this._discoveredUrls.length;
|
|
2753
|
-
}
|
|
2754
|
-
/**
|
|
2755
|
-
* Get the combined ordered list of image URLs
|
|
2756
|
-
* @throws Error if called before prepare()
|
|
2757
|
-
*/
|
|
2758
|
-
imageURLs() {
|
|
2759
|
-
if (!this._prepared)
|
|
2760
|
-
throw new Error("CompositeLoader.imageURLs() called before prepare()");
|
|
2761
|
-
return [...this._discoveredUrls];
|
|
2762
|
-
}
|
|
2763
|
-
/**
|
|
2764
|
-
* Check if the loader has been prepared
|
|
2765
|
-
*/
|
|
2766
|
-
isPrepared() {
|
|
2767
|
-
return this._prepared;
|
|
2768
|
-
}
|
|
2769
|
-
/**
|
|
2770
|
-
* Debug logging helper
|
|
2771
|
-
* @param args - Arguments to log
|
|
2772
|
-
*/
|
|
2773
|
-
log(...t) {
|
|
2774
|
-
this.debugLogging && typeof console < "u" && console.log("[CompositeLoader]", ...t);
|
|
2775
|
-
}
|
|
2776
|
-
}
|
|
2777
|
-
class Ae {
|
|
2322
|
+
ct.TOUCH_CLICK_DELAY = 300;
|
|
2323
|
+
let bt = ct;
|
|
2324
|
+
class Me {
|
|
2778
2325
|
/**
|
|
2779
2326
|
* Create a new ImageFilter
|
|
2780
2327
|
* @param extensions - Array of allowed file extensions (without dots)
|
|
@@ -2811,7 +2358,7 @@ class Ae {
|
|
|
2811
2358
|
// isAllowedDate(date: Date): boolean
|
|
2812
2359
|
// isAllowedDimensions(width: number, height: number): boolean
|
|
2813
2360
|
}
|
|
2814
|
-
const
|
|
2361
|
+
const Ae = `
|
|
2815
2362
|
.fbn-ic-gallery {
|
|
2816
2363
|
position: relative;
|
|
2817
2364
|
width: 100%;
|
|
@@ -2861,67 +2408,77 @@ const Le = `
|
|
|
2861
2408
|
display: none !important;
|
|
2862
2409
|
}
|
|
2863
2410
|
`;
|
|
2864
|
-
function
|
|
2411
|
+
function Re() {
|
|
2865
2412
|
if (typeof document > "u") return;
|
|
2866
2413
|
const n = "fbn-ic-functional-styles";
|
|
2867
2414
|
if (document.getElementById(n)) return;
|
|
2868
2415
|
const t = document.createElement("style");
|
|
2869
|
-
t.id = n, t.textContent =
|
|
2416
|
+
t.id = n, t.textContent = Ae, document.head.appendChild(t);
|
|
2870
2417
|
}
|
|
2871
|
-
class
|
|
2418
|
+
class ze {
|
|
2872
2419
|
constructor(t = {}) {
|
|
2873
|
-
this.fullConfig =
|
|
2420
|
+
this.fullConfig = _t(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 Bt(this.fullConfig.animation), this.layoutEngine = new pe({
|
|
2874
2421
|
layout: this.fullConfig.layout,
|
|
2875
2422
|
image: this.fullConfig.image
|
|
2876
|
-
}), this.zoomEngine = new
|
|
2423
|
+
}), this.zoomEngine = new xe(this.fullConfig.interaction.focus, this.animationEngine, this.fullConfig.styling), this.defaultStyles = rt(this.fullConfig.styling?.default), this.hoverStyles = rt(this.fullConfig.styling?.hover), this.defaultClassName = this.fullConfig.styling?.default?.className, this.hoverClassName = this.fullConfig.styling?.hover?.className;
|
|
2877
2424
|
const e = this.fullConfig.animation.entry || y.animation.entry;
|
|
2878
|
-
this.entryAnimationEngine = new
|
|
2425
|
+
this.entryAnimationEngine = new se(
|
|
2879
2426
|
e,
|
|
2880
2427
|
this.fullConfig.layout.algorithm
|
|
2881
|
-
), this.swipeEngine = null, this.imageFilter = this.createImageFilter(), this.
|
|
2428
|
+
), this.swipeEngine = null, this.imageFilter = this.createImageFilter(), this.containerEl = null, this.loadingEl = null, this.errorEl = null;
|
|
2882
2429
|
}
|
|
2883
2430
|
/**
|
|
2884
2431
|
* Create image filter based on shared loader config
|
|
2885
2432
|
*/
|
|
2886
2433
|
createImageFilter() {
|
|
2887
2434
|
const t = this.fullConfig.config.loaders?.allowedExtensions;
|
|
2888
|
-
return new
|
|
2435
|
+
return new Me(t);
|
|
2889
2436
|
}
|
|
2890
2437
|
/**
|
|
2891
2438
|
* Create appropriate image loader based on config
|
|
2892
2439
|
* Processes loaders array, merges shared config, wraps in CompositeLoader if needed
|
|
2440
|
+
* Uses dynamic imports to trigger loader registration and enable tree-shaking
|
|
2893
2441
|
*/
|
|
2894
|
-
createLoader() {
|
|
2442
|
+
async createLoader() {
|
|
2895
2443
|
const t = this.fullConfig.loaders, e = this.fullConfig.config.loaders ?? {};
|
|
2896
2444
|
if (!t || t.length === 0)
|
|
2897
2445
|
throw new Error("No loaders configured. Provide `images`, `loaders`, or both.");
|
|
2898
|
-
const i =
|
|
2899
|
-
|
|
2446
|
+
const i = await Promise.all(
|
|
2447
|
+
t.map((s) => this.createLoaderFromEntry(s, e))
|
|
2448
|
+
);
|
|
2449
|
+
if (i.length === 1)
|
|
2450
|
+
return i[0];
|
|
2451
|
+
await import("@frybynite/image-cloud/loaders/composite");
|
|
2452
|
+
const o = et.getLoader("composite");
|
|
2453
|
+
return new o({
|
|
2900
2454
|
loaders: i,
|
|
2901
2455
|
debugLogging: this.fullConfig.config.debug?.loaders
|
|
2902
2456
|
});
|
|
2903
2457
|
}
|
|
2904
2458
|
/**
|
|
2905
2459
|
* Create a single loader from a LoaderEntry, merging shared config
|
|
2460
|
+
* Uses dynamic imports to trigger loader registration and enable tree-shaking
|
|
2906
2461
|
*/
|
|
2907
|
-
createLoaderFromEntry(t, e) {
|
|
2462
|
+
async createLoaderFromEntry(t, e) {
|
|
2908
2463
|
if ("static" in t) {
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2464
|
+
await import("@frybynite/image-cloud/loaders/static");
|
|
2465
|
+
const i = et.getLoader("static"), o = t.static, s = {
|
|
2466
|
+
...o,
|
|
2467
|
+
validateUrls: o.validateUrls ?? e.validateUrls,
|
|
2468
|
+
validationTimeout: o.validationTimeout ?? e.validationTimeout,
|
|
2469
|
+
validationMethod: o.validationMethod ?? e.validationMethod,
|
|
2470
|
+
allowedExtensions: o.allowedExtensions ?? e.allowedExtensions,
|
|
2471
|
+
debugLogging: o.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
2916
2472
|
};
|
|
2917
|
-
return new
|
|
2473
|
+
return new i(s);
|
|
2918
2474
|
} else if ("googleDrive" in t) {
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2475
|
+
await import("@frybynite/image-cloud/loaders/google-drive");
|
|
2476
|
+
const i = et.getLoader("google-drive"), o = t.googleDrive, s = {
|
|
2477
|
+
...o,
|
|
2478
|
+
allowedExtensions: o.allowedExtensions ?? e.allowedExtensions,
|
|
2479
|
+
debugLogging: o.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
2923
2480
|
};
|
|
2924
|
-
return new
|
|
2481
|
+
return new i(s);
|
|
2925
2482
|
} else
|
|
2926
2483
|
throw new Error(`Unknown loader entry: ${JSON.stringify(t)}`);
|
|
2927
2484
|
}
|
|
@@ -2930,18 +2487,18 @@ class Me {
|
|
|
2930
2487
|
*/
|
|
2931
2488
|
async init() {
|
|
2932
2489
|
try {
|
|
2933
|
-
if (
|
|
2490
|
+
if (Re(), this.containerRef)
|
|
2934
2491
|
this.containerEl = this.containerRef;
|
|
2935
2492
|
else if (this.containerEl = document.getElementById(this.containerId), !this.containerEl)
|
|
2936
2493
|
throw new Error(`Container #${this.containerId} not found`);
|
|
2937
|
-
this.containerEl.classList.add("fbn-ic-gallery"), this.swipeEngine = new
|
|
2494
|
+
this.containerEl.classList.add("fbn-ic-gallery"), this.swipeEngine = new bt(this.containerEl, {
|
|
2938
2495
|
onNext: () => this.navigateToNextImage(),
|
|
2939
2496
|
onPrev: () => this.navigateToPreviousImage(),
|
|
2940
2497
|
onDragOffset: (t) => this.zoomEngine.setDragOffset(t),
|
|
2941
2498
|
onDragEnd: (t) => {
|
|
2942
|
-
t ? this.zoomEngine.clearDragOffset(!1) : this.zoomEngine.clearDragOffset(!0,
|
|
2499
|
+
t ? this.zoomEngine.clearDragOffset(!1) : this.zoomEngine.clearDragOffset(!0, Ce);
|
|
2943
2500
|
}
|
|
2944
|
-
}), this.setupUI(), this.setupEventListeners(), this.logDebug("ImageCloud initialized"), await this.loadImages();
|
|
2501
|
+
}), this.setupUI(), this.setupEventListeners(), this.imageLoader = await this.createLoader(), this.logDebug("ImageCloud initialized"), await this.loadImages();
|
|
2945
2502
|
} catch (t) {
|
|
2946
2503
|
console.error("Gallery initialization failed:", t), this.errorEl && t instanceof Error && this.showError("Gallery failed to initialize: " + t.message);
|
|
2947
2504
|
}
|
|
@@ -3069,19 +2626,19 @@ class Me {
|
|
|
3069
2626
|
}, f = {
|
|
3070
2627
|
x: parseFloat(c.dataset.endX),
|
|
3071
2628
|
y: parseFloat(c.dataset.endY)
|
|
3072
|
-
}, b = parseFloat(c.dataset.imageWidth), p = parseFloat(c.dataset.imageHeight), g = parseFloat(c.dataset.rotation), m = parseFloat(c.dataset.scale),
|
|
3073
|
-
|
|
2629
|
+
}, b = parseFloat(c.dataset.imageWidth), p = parseFloat(c.dataset.imageHeight), g = parseFloat(c.dataset.rotation), m = parseFloat(c.dataset.scale), S = c.dataset.startRotation ? parseFloat(c.dataset.startRotation) : g, v = c.dataset.startScale ? parseFloat(c.dataset.startScale) : m, x = this.entryAnimationEngine.getTiming();
|
|
2630
|
+
ie({
|
|
3074
2631
|
element: c,
|
|
3075
2632
|
startPosition: d,
|
|
3076
2633
|
endPosition: f,
|
|
3077
2634
|
pathConfig: this.entryAnimationEngine.getPathConfig(),
|
|
3078
|
-
duration:
|
|
2635
|
+
duration: x.duration,
|
|
3079
2636
|
imageWidth: b,
|
|
3080
2637
|
imageHeight: p,
|
|
3081
2638
|
rotation: g,
|
|
3082
2639
|
scale: m,
|
|
3083
2640
|
rotationConfig: this.entryAnimationEngine.getRotationConfig(),
|
|
3084
|
-
startRotation:
|
|
2641
|
+
startRotation: S,
|
|
3085
2642
|
scaleConfig: this.entryAnimationEngine.getScaleConfig(),
|
|
3086
2643
|
startScale: v
|
|
3087
2644
|
});
|
|
@@ -3142,10 +2699,10 @@ class Me {
|
|
|
3142
2699
|
const l = document.createElement("img");
|
|
3143
2700
|
l.referrerPolicy = "no-referrer", l.classList.add("fbn-ic-image"), l.dataset.imageId = String(u);
|
|
3144
2701
|
const d = s[u];
|
|
3145
|
-
l.style.position = "absolute", l.style.width = "auto", l.style.height = `${e}px`, l.style.left = `${d.x}px`, l.style.top = `${d.y}px`, d.zIndex && (l.style.zIndex = String(d.zIndex)),
|
|
3146
|
-
this.hoveredImage = { element: l, layout: d }, this.zoomEngine.isInvolved(l) || (
|
|
2702
|
+
l.style.position = "absolute", l.style.width = "auto", l.style.height = `${e}px`, l.style.left = `${d.x}px`, l.style.top = `${d.y}px`, d.zIndex && (l.style.zIndex = String(d.zIndex)), it(l, this.defaultStyles), nt(l, this.defaultClassName), l.addEventListener("mouseenter", () => {
|
|
2703
|
+
this.hoveredImage = { element: l, layout: d }, this.zoomEngine.isInvolved(l) || (it(l, this.hoverStyles), nt(l, this.hoverClassName));
|
|
3147
2704
|
}), l.addEventListener("mouseleave", () => {
|
|
3148
|
-
this.hoveredImage = null, this.zoomEngine.isInvolved(l) || (
|
|
2705
|
+
this.hoveredImage = null, this.zoomEngine.isInvolved(l) || (it(l, this.defaultStyles), Lt(l, this.hoverClassName), nt(l, this.defaultClassName));
|
|
3149
2706
|
}), l.addEventListener("click", (f) => {
|
|
3150
2707
|
f.stopPropagation(), this.handleImageClick(l, d);
|
|
3151
2708
|
}), l.style.opacity = "0", l.style.transition = this.entryAnimationEngine.getTransitionCSS(), l.onload = () => {
|
|
@@ -3159,19 +2716,19 @@ class Me {
|
|
|
3159
2716
|
i,
|
|
3160
2717
|
u,
|
|
3161
2718
|
t.length
|
|
3162
|
-
),
|
|
2719
|
+
), S = this.entryAnimationEngine.calculateStartRotation(d.rotation), v = this.entryAnimationEngine.calculateStartScale(d.scale), x = this.entryAnimationEngine.buildFinalTransform(
|
|
3163
2720
|
d.rotation,
|
|
3164
2721
|
d.scale,
|
|
3165
2722
|
b,
|
|
3166
2723
|
e
|
|
3167
|
-
),
|
|
2724
|
+
), E = this.entryAnimationEngine.buildStartTransform(
|
|
3168
2725
|
m,
|
|
3169
2726
|
p,
|
|
3170
2727
|
d.rotation,
|
|
3171
2728
|
d.scale,
|
|
3172
2729
|
b,
|
|
3173
2730
|
e,
|
|
3174
|
-
|
|
2731
|
+
S,
|
|
3175
2732
|
v
|
|
3176
2733
|
);
|
|
3177
2734
|
this.fullConfig.config.debug?.enabled && u < 3 && console.log(`Image ${u}:`, {
|
|
@@ -3179,10 +2736,10 @@ class Me {
|
|
|
3179
2736
|
imageSize: g,
|
|
3180
2737
|
left: d.x,
|
|
3181
2738
|
top: d.y,
|
|
3182
|
-
finalTransform:
|
|
2739
|
+
finalTransform: x,
|
|
3183
2740
|
renderedWidth: b,
|
|
3184
2741
|
renderedHeight: e
|
|
3185
|
-
}), l.style.transform =
|
|
2742
|
+
}), l.style.transform = E, l.dataset.finalTransform = x, (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() || S !== d.rotation || v !== d.scale) && (l.dataset.startX = String(m.x), l.dataset.startY = String(m.y), l.dataset.endX = String(p.x), l.dataset.endY = String(p.y), l.dataset.imageWidth = String(b), l.dataset.imageHeight = String(e), l.dataset.rotation = String(d.rotation), l.dataset.scale = String(d.scale), l.dataset.startRotation = String(S), l.dataset.startScale = String(v)), this.displayQueue.push(l);
|
|
3186
2743
|
}, l.onerror = () => r++, l.src = c;
|
|
3187
2744
|
});
|
|
3188
2745
|
}
|
|
@@ -3232,10 +2789,10 @@ function Fe() {
|
|
|
3232
2789
|
const n = "fbn-ic-styles";
|
|
3233
2790
|
if (document.getElementById(n)) return;
|
|
3234
2791
|
const t = document.createElement("style");
|
|
3235
|
-
t.id = n, t.textContent =
|
|
2792
|
+
t.id = n, t.textContent = $t, document.head.appendChild(t);
|
|
3236
2793
|
}
|
|
3237
2794
|
Fe();
|
|
3238
|
-
function
|
|
2795
|
+
function Le() {
|
|
3239
2796
|
if (typeof document > "u") {
|
|
3240
2797
|
console.warn("ImageCloud: Document not available (not in browser environment)");
|
|
3241
2798
|
return;
|
|
@@ -3265,17 +2822,17 @@ function De() {
|
|
|
3265
2822
|
console.error(`ImageCloud: Missing configuration for #${i.id}. Add data-config='{...}' attribute.`);
|
|
3266
2823
|
return;
|
|
3267
2824
|
}
|
|
3268
|
-
new
|
|
2825
|
+
new ze(s).init().catch((a) => {
|
|
3269
2826
|
console.error("ImageCloud initialization failed:", a);
|
|
3270
2827
|
});
|
|
3271
2828
|
});
|
|
3272
2829
|
};
|
|
3273
2830
|
document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", n) : n();
|
|
3274
2831
|
}
|
|
3275
|
-
|
|
2832
|
+
Le();
|
|
3276
2833
|
export {
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
2834
|
+
ze as ImageCloud,
|
|
2835
|
+
ze as ImageGallery,
|
|
2836
|
+
Le as autoInitialize
|
|
3280
2837
|
};
|
|
3281
2838
|
//# sourceMappingURL=image-cloud-auto-init.js.map
|