@frybynite/image-cloud 0.9.3 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/image-cloud-auto-init.js +455 -388
- package/dist/image-cloud-auto-init.js.map +1 -1
- package/dist/image-cloud.js +1005 -938
- package/dist/image-cloud.js.map +1 -1
- package/dist/image-cloud.umd.js +34 -3
- package/dist/image-cloud.umd.js.map +1 -1
- package/dist/index.d.ts +16 -2
- package/dist/react.d.ts +16 -2
- package/dist/react.js +913 -846
- package/dist/react.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/vue.d.ts +16 -2
- package/dist/vue.js +994 -927
- package/dist/vue.js.map +1 -1
- package/dist/web-component.d.ts +16 -2
- package/dist/web-component.js +740 -673
- package/dist/web-component.js.map +1 -1
- package/package.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as Ht } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as Nt, useRef as It, useImperativeHandle as kt, useEffect as
|
|
2
|
+
import { forwardRef as Nt, useRef as It, useImperativeHandle as kt, useEffect as Bt } from "react";
|
|
3
3
|
const mt = Object.freeze({
|
|
4
4
|
none: "none",
|
|
5
5
|
sm: "0 2px 4px rgba(0,0,0,0.1)",
|
|
@@ -10,23 +10,23 @@ const mt = Object.freeze({
|
|
|
10
10
|
energetic: Object.freeze({ overshoot: 0.25, bounces: 2, decayRatio: 0.5 }),
|
|
11
11
|
playful: Object.freeze({ overshoot: 0.15, bounces: 1, decayRatio: 0.5 }),
|
|
12
12
|
subtle: Object.freeze({ overshoot: 0.08, bounces: 1, decayRatio: 0.5 })
|
|
13
|
-
}),
|
|
13
|
+
}), At = Object.freeze({
|
|
14
14
|
gentle: Object.freeze({ stiffness: 150, damping: 30, mass: 1, oscillations: 2 }),
|
|
15
15
|
bouncy: Object.freeze({ stiffness: 300, damping: 15, mass: 1, oscillations: 4 }),
|
|
16
16
|
wobbly: Object.freeze({ stiffness: 180, damping: 12, mass: 1.5, oscillations: 5 }),
|
|
17
17
|
snappy: Object.freeze({ stiffness: 400, damping: 25, mass: 0.8, oscillations: 2 })
|
|
18
|
-
}),
|
|
18
|
+
}), Ct = Object.freeze({
|
|
19
19
|
gentle: Object.freeze({ amplitude: 30, frequency: 1.5, decay: !0, decayRate: 0.9, phase: 0 }),
|
|
20
20
|
playful: Object.freeze({ amplitude: 50, frequency: 2.5, decay: !0, decayRate: 0.7, phase: 0 }),
|
|
21
21
|
serpentine: Object.freeze({ amplitude: 60, frequency: 3, decay: !1, decayRate: 1, phase: 0 }),
|
|
22
22
|
flutter: Object.freeze({ amplitude: 20, frequency: 4, decay: !0, decayRate: 0.5, phase: 0 })
|
|
23
|
-
}),
|
|
23
|
+
}), yt = Object.freeze({
|
|
24
24
|
type: "linear"
|
|
25
25
|
}), vt = Object.freeze({
|
|
26
26
|
mode: "none"
|
|
27
|
-
}),
|
|
27
|
+
}), Et = Object.freeze({
|
|
28
28
|
mode: "none"
|
|
29
|
-
}),
|
|
29
|
+
}), Mt = Object.freeze({
|
|
30
30
|
default: Object.freeze({
|
|
31
31
|
border: Object.freeze({
|
|
32
32
|
width: 0,
|
|
@@ -52,18 +52,18 @@ const mt = Object.freeze({
|
|
|
52
52
|
focused: Object.freeze({
|
|
53
53
|
shadow: "none"
|
|
54
54
|
})
|
|
55
|
-
}),
|
|
55
|
+
}), jt = Object.freeze({
|
|
56
56
|
tightness: 1
|
|
57
|
-
}),
|
|
57
|
+
}), Wt = Object.freeze({
|
|
58
58
|
rows: 1,
|
|
59
59
|
amplitude: 100,
|
|
60
60
|
frequency: 2,
|
|
61
61
|
phaseShift: 0,
|
|
62
62
|
synchronization: "offset"
|
|
63
63
|
// Note: Image rotation along wave is now controlled via image.rotation.mode = 'tangent'
|
|
64
|
-
}),
|
|
64
|
+
}), Gt = Object.freeze({
|
|
65
65
|
spacing: 0
|
|
66
|
-
}),
|
|
66
|
+
}), qt = Object.freeze({
|
|
67
67
|
mobile: Object.freeze({ maxWidth: 767 }),
|
|
68
68
|
tablet: Object.freeze({ maxWidth: 1199 })
|
|
69
69
|
}), Xt = Object.freeze({
|
|
@@ -111,7 +111,7 @@ const mt = Object.freeze({
|
|
|
111
111
|
algorithm: "radial",
|
|
112
112
|
scaleDecay: 0,
|
|
113
113
|
// No decay by default (0-1 for radial/spiral)
|
|
114
|
-
responsive:
|
|
114
|
+
responsive: qt,
|
|
115
115
|
targetCoverage: 0.6,
|
|
116
116
|
// Target 60% of container area
|
|
117
117
|
densityFactor: 1,
|
|
@@ -157,9 +157,9 @@ const mt = Object.freeze({
|
|
|
157
157
|
}),
|
|
158
158
|
easing: "cubic-bezier(0.25, 1, 0.5, 1)",
|
|
159
159
|
// smooth deceleration
|
|
160
|
-
path:
|
|
160
|
+
path: yt,
|
|
161
161
|
rotation: vt,
|
|
162
|
-
scale:
|
|
162
|
+
scale: Et
|
|
163
163
|
}),
|
|
164
164
|
idle: $t
|
|
165
165
|
}),
|
|
@@ -183,53 +183,55 @@ const mt = Object.freeze({
|
|
|
183
183
|
// UI configuration
|
|
184
184
|
ui: Object.freeze({
|
|
185
185
|
showLoadingSpinner: !1,
|
|
186
|
-
showImageCounter: !1
|
|
186
|
+
showImageCounter: !1,
|
|
187
|
+
showNavButtons: !1,
|
|
188
|
+
showFocusOutline: !1
|
|
187
189
|
}),
|
|
188
190
|
// Image styling
|
|
189
|
-
styling:
|
|
191
|
+
styling: Mt
|
|
190
192
|
});
|
|
191
|
-
function Z(
|
|
192
|
-
if (!
|
|
193
|
-
if (!t) return { ...
|
|
194
|
-
const i = { ...
|
|
195
|
-
return t.border !== void 0 && (i.border = { ...
|
|
193
|
+
function Z(o, t) {
|
|
194
|
+
if (!o) return t || {};
|
|
195
|
+
if (!t) return { ...o };
|
|
196
|
+
const i = { ...o };
|
|
197
|
+
return t.border !== void 0 && (i.border = { ...o.border, ...t.border }), t.borderTop !== void 0 && (i.borderTop = { ...o.borderTop, ...t.borderTop }), t.borderRight !== void 0 && (i.borderRight = { ...o.borderRight, ...t.borderRight }), t.borderBottom !== void 0 && (i.borderBottom = { ...o.borderBottom, ...t.borderBottom }), t.borderLeft !== void 0 && (i.borderLeft = { ...o.borderLeft, ...t.borderLeft }), t.filter !== void 0 && (i.filter = { ...o.filter, ...t.filter }), t.outline !== void 0 && (i.outline = { ...o.outline, ...t.outline }), t.shadow !== void 0 && (i.shadow = t.shadow), t.clipPath !== void 0 && (i.clipPath = t.clipPath), t.opacity !== void 0 && (i.opacity = t.opacity), t.cursor !== void 0 && (i.cursor = t.cursor), t.className !== void 0 && (i.className = t.className), t.objectFit !== void 0 && (i.objectFit = t.objectFit), t.aspectRatio !== void 0 && (i.aspectRatio = t.aspectRatio), t.borderRadiusTopLeft !== void 0 && (i.borderRadiusTopLeft = t.borderRadiusTopLeft), t.borderRadiusTopRight !== void 0 && (i.borderRadiusTopRight = t.borderRadiusTopRight), t.borderRadiusBottomRight !== void 0 && (i.borderRadiusBottomRight = t.borderRadiusBottomRight), t.borderRadiusBottomLeft !== void 0 && (i.borderRadiusBottomLeft = t.borderRadiusBottomLeft), i;
|
|
196
198
|
}
|
|
197
|
-
function Qt(
|
|
198
|
-
if (!t) return { ...
|
|
199
|
-
const i = Z(
|
|
200
|
-
Z(i,
|
|
199
|
+
function Qt(o, t) {
|
|
200
|
+
if (!t) return { ...o };
|
|
201
|
+
const i = Z(o.default, t.default), e = Z(
|
|
202
|
+
Z(i, o.hover),
|
|
201
203
|
t.hover
|
|
202
|
-
),
|
|
203
|
-
Z(i,
|
|
204
|
+
), n = Z(
|
|
205
|
+
Z(i, o.focused),
|
|
204
206
|
t.focused
|
|
205
207
|
);
|
|
206
208
|
return {
|
|
207
209
|
default: i,
|
|
208
210
|
hover: e,
|
|
209
|
-
focused:
|
|
211
|
+
focused: n
|
|
210
212
|
};
|
|
211
213
|
}
|
|
212
|
-
function te(
|
|
213
|
-
if (!t) return { ...
|
|
214
|
-
const i = { ...
|
|
214
|
+
function te(o, t) {
|
|
215
|
+
if (!t) return { ...o };
|
|
216
|
+
const i = { ...o };
|
|
215
217
|
if (t.sizing !== void 0 && (i.sizing = {
|
|
216
|
-
...
|
|
218
|
+
...o.sizing,
|
|
217
219
|
...t.sizing
|
|
218
220
|
}, t.sizing.variance)) {
|
|
219
|
-
const e = t.sizing.variance,
|
|
220
|
-
i.sizing.variance = { min:
|
|
221
|
+
const e = t.sizing.variance, n = e.min !== void 0 && e.min >= 0.25 && e.min <= 1 ? e.min : o.sizing?.variance?.min ?? 1, s = e.max !== void 0 && e.max >= 1 && e.max <= 1.75 ? e.max : o.sizing?.variance?.max ?? 1;
|
|
222
|
+
i.sizing.variance = { min: n, max: s };
|
|
221
223
|
}
|
|
222
224
|
if (t.rotation !== void 0 && (i.rotation = {
|
|
223
|
-
...
|
|
225
|
+
...o.rotation,
|
|
224
226
|
...t.rotation
|
|
225
227
|
}, t.rotation.range)) {
|
|
226
|
-
const e = t.rotation.range,
|
|
227
|
-
i.rotation.range = { min:
|
|
228
|
+
const e = t.rotation.range, n = e.min !== void 0 && e.min >= -180 && e.min <= 0 ? e.min : o.rotation?.range?.min ?? -15, s = e.max !== void 0 && e.max >= 0 && e.max <= 180 ? e.max : o.rotation?.range?.max ?? 15;
|
|
229
|
+
i.rotation.range = { min: n, max: s };
|
|
228
230
|
}
|
|
229
231
|
return i;
|
|
230
232
|
}
|
|
231
|
-
function ee(
|
|
232
|
-
const t =
|
|
233
|
+
function ee(o) {
|
|
234
|
+
const t = o.layout?.rotation;
|
|
233
235
|
if (t && "enabled" in t)
|
|
234
236
|
return {
|
|
235
237
|
rotation: {
|
|
@@ -238,8 +240,8 @@ function ee(n) {
|
|
|
238
240
|
}
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
|
-
function ie(
|
|
242
|
-
const t =
|
|
243
|
+
function ie(o) {
|
|
244
|
+
const t = o.layout?.sizing?.variance;
|
|
243
245
|
if (t)
|
|
244
246
|
return {
|
|
245
247
|
sizing: {
|
|
@@ -249,109 +251,109 @@ function ie(n) {
|
|
|
249
251
|
}
|
|
250
252
|
};
|
|
251
253
|
}
|
|
252
|
-
function
|
|
253
|
-
const t = ee(
|
|
254
|
-
let e =
|
|
254
|
+
function ne(o = {}) {
|
|
255
|
+
const t = ee(o), i = ie(o);
|
|
256
|
+
let e = o.image;
|
|
255
257
|
(t || i) && (e = {
|
|
256
258
|
...i || {},
|
|
257
259
|
...t || {},
|
|
258
260
|
...e
|
|
259
|
-
}, e.rotation && t?.rotation &&
|
|
261
|
+
}, e.rotation && t?.rotation && o.image?.rotation && (e.rotation = {
|
|
260
262
|
...t.rotation,
|
|
261
|
-
...
|
|
263
|
+
...o.image.rotation
|
|
262
264
|
}));
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
+
const n = [...o.loaders ?? []];
|
|
266
|
+
o.images && o.images.length > 0 && n.unshift({
|
|
265
267
|
static: {
|
|
266
|
-
sources: [{ urls:
|
|
268
|
+
sources: [{ urls: o.images }]
|
|
267
269
|
}
|
|
268
270
|
});
|
|
269
271
|
const r = {
|
|
270
272
|
loaders: {
|
|
271
273
|
...Ot,
|
|
272
|
-
...
|
|
274
|
+
...o.config?.loaders ?? {}
|
|
273
275
|
}
|
|
274
|
-
},
|
|
275
|
-
loaders:
|
|
276
|
+
}, a = {
|
|
277
|
+
loaders: n,
|
|
276
278
|
config: r,
|
|
277
279
|
image: te(zt, e),
|
|
278
280
|
layout: { ...R.layout },
|
|
279
281
|
animation: { ...R.animation },
|
|
280
282
|
interaction: { ...R.interaction },
|
|
281
283
|
ui: { ...R.ui },
|
|
282
|
-
styling: Qt(
|
|
284
|
+
styling: Qt(Mt, o.styling)
|
|
283
285
|
};
|
|
284
|
-
|
|
286
|
+
o.layout && (a.layout = {
|
|
285
287
|
...R.layout,
|
|
286
|
-
...
|
|
287
|
-
},
|
|
288
|
+
...o.layout
|
|
289
|
+
}, o.layout.responsive && (a.layout.responsive = {
|
|
288
290
|
...R.layout.responsive,
|
|
289
|
-
mobile:
|
|
290
|
-
tablet:
|
|
291
|
-
}),
|
|
291
|
+
mobile: o.layout.responsive.mobile ? { ...R.layout.responsive.mobile, ...o.layout.responsive.mobile } : R.layout.responsive.mobile,
|
|
292
|
+
tablet: o.layout.responsive.tablet ? { ...R.layout.responsive.tablet, ...o.layout.responsive.tablet } : R.layout.responsive.tablet
|
|
293
|
+
}), o.layout.spacing && (a.layout.spacing = {
|
|
292
294
|
...R.layout.spacing,
|
|
293
|
-
...
|
|
294
|
-
})),
|
|
295
|
+
...o.layout.spacing
|
|
296
|
+
})), o.animation && (a.animation = {
|
|
295
297
|
...R.animation,
|
|
296
|
-
...
|
|
297
|
-
},
|
|
298
|
+
...o.animation
|
|
299
|
+
}, o.animation.easing && (a.animation.easing = {
|
|
298
300
|
...R.animation.easing,
|
|
299
|
-
...
|
|
300
|
-
}),
|
|
301
|
+
...o.animation.easing
|
|
302
|
+
}), o.animation.queue && (a.animation.queue = {
|
|
301
303
|
...R.animation.queue,
|
|
302
|
-
...
|
|
303
|
-
}),
|
|
304
|
+
...o.animation.queue
|
|
305
|
+
}), o.animation.entry && (a.animation.entry = {
|
|
304
306
|
...R.animation.entry,
|
|
305
|
-
...
|
|
306
|
-
start:
|
|
307
|
+
...o.animation.entry,
|
|
308
|
+
start: o.animation.entry.start ? {
|
|
307
309
|
...R.animation.entry.start,
|
|
308
|
-
...
|
|
309
|
-
circular:
|
|
310
|
+
...o.animation.entry.start,
|
|
311
|
+
circular: o.animation.entry.start.circular ? { ...R.animation.entry.start.circular, ...o.animation.entry.start.circular } : R.animation.entry.start.circular
|
|
310
312
|
} : R.animation.entry.start,
|
|
311
|
-
timing:
|
|
312
|
-
path:
|
|
313
|
-
rotation:
|
|
314
|
-
scale:
|
|
315
|
-
}),
|
|
313
|
+
timing: o.animation.entry.timing ? { ...R.animation.entry.timing, ...o.animation.entry.timing } : R.animation.entry.timing,
|
|
314
|
+
path: o.animation.entry.path ? { ...yt, ...o.animation.entry.path } : R.animation.entry.path,
|
|
315
|
+
rotation: o.animation.entry.rotation ? { ...vt, ...o.animation.entry.rotation } : R.animation.entry.rotation,
|
|
316
|
+
scale: o.animation.entry.scale ? { ...Et, ...o.animation.entry.scale } : R.animation.entry.scale
|
|
317
|
+
}), o.animation.idle && (a.animation.idle = {
|
|
316
318
|
...$t,
|
|
317
|
-
...
|
|
318
|
-
})),
|
|
319
|
+
...o.animation.idle
|
|
320
|
+
})), o.interaction && (a.interaction = {
|
|
319
321
|
...R.interaction,
|
|
320
|
-
...
|
|
321
|
-
},
|
|
322
|
+
...o.interaction
|
|
323
|
+
}, o.interaction.focus && (a.interaction.focus = {
|
|
322
324
|
...R.interaction.focus,
|
|
323
|
-
...
|
|
324
|
-
}),
|
|
325
|
+
...o.interaction.focus
|
|
326
|
+
}), o.interaction.navigation && (a.interaction.navigation = {
|
|
325
327
|
...R.interaction.navigation,
|
|
326
|
-
...
|
|
328
|
+
...o.interaction.navigation
|
|
327
329
|
}));
|
|
328
|
-
const c =
|
|
329
|
-
if (c && console.warn("[ImageCloud] rendering.ui is deprecated. Use top-level ui instead."),
|
|
330
|
+
const c = o.rendering?.ui;
|
|
331
|
+
if (c && console.warn("[ImageCloud] rendering.ui is deprecated. Use top-level ui instead."), a.ui = {
|
|
330
332
|
...R.ui,
|
|
331
333
|
...c,
|
|
332
|
-
...
|
|
333
|
-
},
|
|
334
|
+
...o.ui
|
|
335
|
+
}, a.config.debug = {
|
|
334
336
|
...Dt,
|
|
335
|
-
...
|
|
336
|
-
},
|
|
337
|
+
...o.config?.debug ?? {}
|
|
338
|
+
}, a.layout.algorithm === "honeycomb" && a.styling) {
|
|
337
339
|
const l = { shape: "hexagon", mode: "height-relative" };
|
|
338
|
-
|
|
339
|
-
...
|
|
340
|
-
default: { ...
|
|
341
|
-
hover: { ...
|
|
340
|
+
a.styling = {
|
|
341
|
+
...a.styling,
|
|
342
|
+
default: { ...a.styling.default, clipPath: l },
|
|
343
|
+
hover: { ...a.styling.hover, clipPath: l }
|
|
342
344
|
// focused: untouched — user config respected
|
|
343
345
|
};
|
|
344
346
|
}
|
|
345
|
-
return
|
|
347
|
+
return a;
|
|
346
348
|
}
|
|
347
|
-
function
|
|
348
|
-
return { ...
|
|
349
|
+
function oe(o, t) {
|
|
350
|
+
return { ...o ? Rt[o] : Rt.playful, ...t };
|
|
349
351
|
}
|
|
350
|
-
function se(
|
|
351
|
-
return { ...
|
|
352
|
+
function se(o, t) {
|
|
353
|
+
return { ...o ? At[o] : At.gentle, ...t };
|
|
352
354
|
}
|
|
353
|
-
function ae(
|
|
354
|
-
return { ...
|
|
355
|
+
function ae(o, t) {
|
|
356
|
+
return { ...o ? Ct[o] : Ct.gentle, ...t };
|
|
355
357
|
}
|
|
356
358
|
class re {
|
|
357
359
|
constructor(t) {
|
|
@@ -364,8 +366,8 @@ class re {
|
|
|
364
366
|
buildTransformString(t) {
|
|
365
367
|
const i = ["translate(-50%, -50%)"];
|
|
366
368
|
if (t.x !== void 0 || t.y !== void 0) {
|
|
367
|
-
const e = t.x ?? 0,
|
|
368
|
-
i.push(`translate(${e}px, ${
|
|
369
|
+
const e = t.x ?? 0, n = t.y ?? 0;
|
|
370
|
+
i.push(`translate(${e}px, ${n}px)`);
|
|
369
371
|
}
|
|
370
372
|
return t.rotation !== void 0 && i.push(`rotate(${t.rotation}deg)`), t.scale !== void 0 && i.push(`scale(${t.scale})`), i.join(" ");
|
|
371
373
|
}
|
|
@@ -378,9 +380,9 @@ class re {
|
|
|
378
380
|
* @param easing - CSS easing function (optional)
|
|
379
381
|
* @returns AnimationHandle that can be used to cancel or query the animation
|
|
380
382
|
*/
|
|
381
|
-
animateTransformCancellable(t, i, e,
|
|
383
|
+
animateTransformCancellable(t, i, e, n = null, s = null) {
|
|
382
384
|
this.cancelAllAnimations(t);
|
|
383
|
-
const r =
|
|
385
|
+
const r = n ?? this.config.duration, a = s ?? this.config.easing.default, c = this.buildTransformString(i), l = this.buildTransformString(e);
|
|
384
386
|
t.style.transition = "none";
|
|
385
387
|
const u = t.animate(
|
|
386
388
|
[
|
|
@@ -389,7 +391,7 @@ class re {
|
|
|
389
391
|
],
|
|
390
392
|
{
|
|
391
393
|
duration: r,
|
|
392
|
-
easing:
|
|
394
|
+
easing: a,
|
|
393
395
|
fill: "forwards"
|
|
394
396
|
// Keep final state after animation
|
|
395
397
|
}
|
|
@@ -417,13 +419,13 @@ class re {
|
|
|
417
419
|
cancelAnimation(t, i = !0) {
|
|
418
420
|
const e = this.getCurrentTransform(t.element);
|
|
419
421
|
if (t.animation.cancel(), i) {
|
|
420
|
-
const
|
|
422
|
+
const n = this.buildTransformString({
|
|
421
423
|
x: e.x,
|
|
422
424
|
y: e.y,
|
|
423
425
|
rotation: e.rotation,
|
|
424
426
|
scale: e.scale
|
|
425
427
|
});
|
|
426
|
-
t.element.style.transform =
|
|
428
|
+
t.element.style.transform = n;
|
|
427
429
|
}
|
|
428
430
|
return this.activeAnimations.delete(t.element), e;
|
|
429
431
|
}
|
|
@@ -436,8 +438,8 @@ class re {
|
|
|
436
438
|
const i = this.activeAnimations.get(t);
|
|
437
439
|
i && this.cancelAnimation(i, !1);
|
|
438
440
|
const e = t.getAnimations();
|
|
439
|
-
for (const
|
|
440
|
-
|
|
441
|
+
for (const n of e)
|
|
442
|
+
n.cancel();
|
|
441
443
|
}
|
|
442
444
|
/**
|
|
443
445
|
* Get current transform state of an element (works mid-animation)
|
|
@@ -449,8 +451,8 @@ class re {
|
|
|
449
451
|
const e = getComputedStyle(t).transform;
|
|
450
452
|
if (e === "none" || !e)
|
|
451
453
|
return { x: 0, y: 0, rotation: 0, scale: 1 };
|
|
452
|
-
const
|
|
453
|
-
return { x:
|
|
454
|
+
const n = new DOMMatrix(e), s = Math.sqrt(n.a * n.a + n.b * n.b), r = Math.atan2(n.b, n.a) * (180 / Math.PI), a = n.e, c = n.f;
|
|
455
|
+
return { x: a, y: c, rotation: r, scale: s };
|
|
454
456
|
}
|
|
455
457
|
/**
|
|
456
458
|
* Check if an element has an active animation
|
|
@@ -476,11 +478,11 @@ class re {
|
|
|
476
478
|
* @param easing - CSS easing function (optional)
|
|
477
479
|
* @returns Promise that resolves when animation completes
|
|
478
480
|
*/
|
|
479
|
-
animateTransform(t, i, e = null,
|
|
480
|
-
return new Promise((
|
|
481
|
-
const r = e ?? this.config.duration,
|
|
482
|
-
t.style.transition = `transform ${r}ms ${
|
|
483
|
-
|
|
481
|
+
animateTransform(t, i, e = null, n = null) {
|
|
482
|
+
return new Promise((s) => {
|
|
483
|
+
const r = e ?? this.config.duration, a = n ?? this.config.easing.default;
|
|
484
|
+
t.style.transition = `transform ${r}ms ${a}, box-shadow ${r}ms ${a}`, t.style.transform = this.buildTransformString(i), setTimeout(() => {
|
|
485
|
+
s();
|
|
484
486
|
}, r);
|
|
485
487
|
});
|
|
486
488
|
}
|
|
@@ -509,161 +511,161 @@ class re {
|
|
|
509
511
|
return new Promise((i) => setTimeout(i, t));
|
|
510
512
|
}
|
|
511
513
|
}
|
|
512
|
-
function J(
|
|
513
|
-
return
|
|
514
|
+
function J(o, t, i) {
|
|
515
|
+
return o + (t - o) * i;
|
|
514
516
|
}
|
|
515
|
-
function ce(
|
|
516
|
-
const { overshoot:
|
|
517
|
-
let u = 0, h = 0, d = 1,
|
|
518
|
-
for (let
|
|
519
|
-
if (
|
|
520
|
-
h =
|
|
517
|
+
function ce(o, t, i, e) {
|
|
518
|
+
const { overshoot: n, bounces: s, decayRatio: r } = e, a = i.x - t.x, c = i.y - t.y, l = le(s, r);
|
|
519
|
+
let u = 0, h = 0, d = 1, g = n, b = !1;
|
|
520
|
+
for (let f = 0; f < l.length; f++)
|
|
521
|
+
if (o <= l[f].time) {
|
|
522
|
+
h = f === 0 ? 0 : l[f - 1].time, d = l[f].time, g = l[f].overshoot, b = l[f].isOvershoot;
|
|
521
523
|
break;
|
|
522
524
|
}
|
|
523
|
-
const p = (
|
|
524
|
-
if (
|
|
525
|
-
u = 1 +
|
|
525
|
+
const p = (o - h) / (d - h);
|
|
526
|
+
if (b)
|
|
527
|
+
u = 1 + g * at(p);
|
|
526
528
|
else if (h === 0)
|
|
527
|
-
u =
|
|
529
|
+
u = at(p);
|
|
528
530
|
else {
|
|
529
531
|
const m = 1 + (l.find(
|
|
530
|
-
(
|
|
531
|
-
)?.overshoot ||
|
|
532
|
-
u = J(m, 1,
|
|
532
|
+
(y, E) => y.time > h && E > 0 && l[E - 1].isOvershoot
|
|
533
|
+
)?.overshoot || g);
|
|
534
|
+
u = J(m, 1, at(p));
|
|
533
535
|
}
|
|
534
536
|
return {
|
|
535
|
-
x: t.x +
|
|
537
|
+
x: t.x + a * u,
|
|
536
538
|
y: t.y + c * u
|
|
537
539
|
};
|
|
538
540
|
}
|
|
539
|
-
function le(
|
|
541
|
+
function le(o, t) {
|
|
540
542
|
const i = [];
|
|
541
543
|
let e = 0.6;
|
|
542
544
|
i.push({ time: e, overshoot: 0, isOvershoot: !1 });
|
|
543
|
-
let
|
|
544
|
-
const r = 0.4 / (
|
|
545
|
-
for (let
|
|
546
|
-
e += r, i.push({ time: e, overshoot:
|
|
545
|
+
let n = 0.15;
|
|
546
|
+
const r = 0.4 / (o * 2);
|
|
547
|
+
for (let a = 0; a < o; a++)
|
|
548
|
+
e += r, i.push({ time: e, overshoot: n, isOvershoot: !0 }), e += r, i.push({ time: e, overshoot: n * t, isOvershoot: !1 }), n *= t;
|
|
547
549
|
return i.push({ time: 1, overshoot: 0, isOvershoot: !1 }), i;
|
|
548
550
|
}
|
|
549
|
-
function he(
|
|
550
|
-
const { stiffness:
|
|
551
|
+
function he(o, t, i, e) {
|
|
552
|
+
const { stiffness: n, damping: s, mass: r, oscillations: a } = e, c = i.x - t.x, l = i.y - t.y, u = Math.sqrt(n / r), h = s / (2 * Math.sqrt(n * r));
|
|
551
553
|
let d;
|
|
552
554
|
if (h < 1) {
|
|
553
|
-
const
|
|
554
|
-
d = 1 -
|
|
555
|
+
const g = u * Math.sqrt(1 - h * h), b = Math.exp(-h * u * o * 3), p = Math.cos(g * o * a * Math.PI);
|
|
556
|
+
d = 1 - b * p;
|
|
555
557
|
} else
|
|
556
|
-
d = 1 - Math.exp(-u *
|
|
558
|
+
d = 1 - Math.exp(-u * o * 3);
|
|
557
559
|
return d = Math.max(0, Math.min(d, 1.3)), {
|
|
558
560
|
x: t.x + c * d,
|
|
559
561
|
y: t.y + l * d
|
|
560
562
|
};
|
|
561
563
|
}
|
|
562
|
-
function de(
|
|
563
|
-
const { amplitude:
|
|
564
|
+
function de(o, t, i, e) {
|
|
565
|
+
const { amplitude: n, frequency: s, decay: r, decayRate: a, phase: c } = e, l = i.x - t.x, u = i.y - t.y, h = Math.sqrt(l * l + u * u), d = h > 0 ? -u / h : 0, g = h > 0 ? l / h : 1, b = s * Math.PI * 2 * o + c, p = r ? Math.pow(1 - o, a) : 1, f = n * Math.sin(b) * p, m = ue(o);
|
|
564
566
|
return {
|
|
565
|
-
x: J(t.x, i.x, m) +
|
|
566
|
-
y: J(t.y, i.y, m) +
|
|
567
|
+
x: J(t.x, i.x, m) + f * d,
|
|
568
|
+
y: J(t.y, i.y, m) + f * g
|
|
567
569
|
};
|
|
568
570
|
}
|
|
569
|
-
function
|
|
570
|
-
return 1 - (1 -
|
|
571
|
+
function at(o) {
|
|
572
|
+
return 1 - (1 - o) * (1 - o);
|
|
571
573
|
}
|
|
572
|
-
function ue(
|
|
573
|
-
return 1 - Math.pow(1 -
|
|
574
|
+
function ue(o) {
|
|
575
|
+
return 1 - Math.pow(1 - o, 3);
|
|
574
576
|
}
|
|
575
|
-
function
|
|
576
|
-
const { amplitude: e, frequency:
|
|
577
|
+
function fe(o, t, i) {
|
|
578
|
+
const { amplitude: e, frequency: n, decay: s } = i, r = Math.sin(o * n * Math.PI * 2), a = s ? Math.pow(1 - o, 2) : 1, c = e * r * a;
|
|
577
579
|
return t + c;
|
|
578
580
|
}
|
|
579
|
-
function
|
|
580
|
-
const { overshoot: e, bounces:
|
|
581
|
-
|
|
581
|
+
function ge(o, t, i) {
|
|
582
|
+
const { overshoot: e, bounces: n } = i, s = [];
|
|
583
|
+
s.push({ time: 0.5, scale: e });
|
|
582
584
|
let r = e;
|
|
583
|
-
const
|
|
585
|
+
const a = 0.5, l = 0.5 / (n * 2);
|
|
584
586
|
let u = 0.5;
|
|
585
|
-
for (let d = 0; d <
|
|
586
|
-
const
|
|
587
|
-
u += l,
|
|
587
|
+
for (let d = 0; d < n; d++) {
|
|
588
|
+
const g = 1 - (r - 1) * a;
|
|
589
|
+
u += l, s.push({ time: u, scale: g }), r = 1 + (r - 1) * a * a, u += l, d < n - 1 && s.push({ time: u, scale: r });
|
|
588
590
|
}
|
|
589
|
-
|
|
591
|
+
s.push({ time: 1, scale: 1 });
|
|
590
592
|
let h = 1;
|
|
591
|
-
for (let d = 0; d <
|
|
592
|
-
if (
|
|
593
|
-
const
|
|
594
|
-
h =
|
|
593
|
+
for (let d = 0; d < s.length; d++)
|
|
594
|
+
if (o <= s[d].time) {
|
|
595
|
+
const g = d === 0 ? 0 : s[d - 1].time, b = d === 0 ? 1 : s[d - 1].scale, p = (o - g) / (s[d].time - g), f = at(p);
|
|
596
|
+
h = b + (s[d].scale - b) * f;
|
|
595
597
|
break;
|
|
596
598
|
}
|
|
597
599
|
return h * t;
|
|
598
600
|
}
|
|
599
|
-
function me(
|
|
601
|
+
function me(o) {
|
|
600
602
|
const {
|
|
601
603
|
element: t,
|
|
602
604
|
startPosition: i,
|
|
603
605
|
endPosition: e,
|
|
604
|
-
pathConfig:
|
|
605
|
-
duration:
|
|
606
|
+
pathConfig: n,
|
|
607
|
+
duration: s,
|
|
606
608
|
imageWidth: r,
|
|
607
|
-
imageHeight:
|
|
609
|
+
imageHeight: a,
|
|
608
610
|
rotation: c,
|
|
609
611
|
scale: l,
|
|
610
612
|
onComplete: u,
|
|
611
613
|
rotationConfig: h,
|
|
612
614
|
startRotation: d,
|
|
613
|
-
scaleConfig:
|
|
614
|
-
startScale:
|
|
615
|
-
} =
|
|
616
|
-
if ((p === "linear" || p === "arc") && !
|
|
615
|
+
scaleConfig: g,
|
|
616
|
+
startScale: b
|
|
617
|
+
} = o, p = n.type, f = d !== void 0 && d !== c, m = h?.mode === "wobble", y = h?.wobble || { amplitude: 15, frequency: 3, decay: !0 }, E = f || m, v = b !== void 0 && b !== l, S = g?.mode === "pop", w = g?.pop || { overshoot: 1.2, bounces: 1 };
|
|
618
|
+
if ((p === "linear" || p === "arc") && !E && !(v || S)) {
|
|
617
619
|
u && u();
|
|
618
620
|
return;
|
|
619
621
|
}
|
|
620
|
-
const z = performance.now(), L = -r / 2, _ = -
|
|
622
|
+
const z = performance.now(), L = -r / 2, _ = -a / 2;
|
|
621
623
|
function O(H) {
|
|
622
|
-
const N = H - z,
|
|
624
|
+
const N = H - z, A = Math.min(N / s, 1);
|
|
623
625
|
let D;
|
|
624
626
|
switch (p) {
|
|
625
627
|
case "bounce": {
|
|
626
|
-
const k =
|
|
627
|
-
|
|
628
|
-
|
|
628
|
+
const k = oe(
|
|
629
|
+
n.bouncePreset,
|
|
630
|
+
n.bounce
|
|
629
631
|
);
|
|
630
|
-
D = ce(
|
|
632
|
+
D = ce(A, i, e, k);
|
|
631
633
|
break;
|
|
632
634
|
}
|
|
633
635
|
case "elastic": {
|
|
634
636
|
const k = se(
|
|
635
|
-
|
|
636
|
-
|
|
637
|
+
n.elasticPreset,
|
|
638
|
+
n.elastic
|
|
637
639
|
);
|
|
638
|
-
D = he(
|
|
640
|
+
D = he(A, i, e, k);
|
|
639
641
|
break;
|
|
640
642
|
}
|
|
641
643
|
case "wave": {
|
|
642
644
|
const k = ae(
|
|
643
|
-
|
|
644
|
-
|
|
645
|
+
n.wavePreset,
|
|
646
|
+
n.wave
|
|
645
647
|
);
|
|
646
|
-
D = de(
|
|
648
|
+
D = de(A, i, e, k);
|
|
647
649
|
break;
|
|
648
650
|
}
|
|
649
651
|
default:
|
|
650
652
|
D = {
|
|
651
|
-
x: J(i.x, e.x,
|
|
652
|
-
y: J(i.y, e.y,
|
|
653
|
+
x: J(i.x, e.x, A),
|
|
654
|
+
y: J(i.y, e.y, A)
|
|
653
655
|
};
|
|
654
656
|
}
|
|
655
|
-
const
|
|
656
|
-
let
|
|
657
|
-
m ?
|
|
658
|
-
let
|
|
659
|
-
S ?
|
|
657
|
+
const W = D.x - e.x, U = D.y - e.y;
|
|
658
|
+
let F;
|
|
659
|
+
m ? F = fe(A, c, y) : f ? F = J(d, c, A) : F = c;
|
|
660
|
+
let C;
|
|
661
|
+
S ? C = ge(A, l, w) : v ? C = J(b, l, A) : C = l, t.style.transform = `translate(${L}px, ${_}px) translate(${W}px, ${U}px) rotate(${F}deg) scale(${C})`, A < 1 ? requestAnimationFrame(O) : (t.style.transform = `translate(${L}px, ${_}px) rotate(${c}deg) scale(${l})`, u && u());
|
|
660
662
|
}
|
|
661
663
|
requestAnimationFrame(O);
|
|
662
664
|
}
|
|
663
|
-
function pe(
|
|
664
|
-
return
|
|
665
|
+
function pe(o) {
|
|
666
|
+
return o === "bounce" || o === "elastic" || o === "wave";
|
|
665
667
|
}
|
|
666
|
-
const
|
|
668
|
+
const be = {
|
|
667
669
|
radial: "center",
|
|
668
670
|
spiral: "center",
|
|
669
671
|
grid: "top",
|
|
@@ -672,85 +674,85 @@ const ye = {
|
|
|
672
674
|
wave: "left",
|
|
673
675
|
honeycomb: "center"
|
|
674
676
|
};
|
|
675
|
-
class
|
|
677
|
+
class ye {
|
|
676
678
|
constructor(t, i) {
|
|
677
|
-
this.config = t, this.layoutAlgorithm = i, this.resolvedStartPosition = this.resolveStartPosition(), this.pathConfig = t.path ||
|
|
679
|
+
this.config = t, this.layoutAlgorithm = i, this.resolvedStartPosition = this.resolveStartPosition(), this.pathConfig = t.path || yt, this.rotationConfig = t.rotation || vt, this.scaleConfig = t.scale || Et;
|
|
678
680
|
}
|
|
679
681
|
/**
|
|
680
682
|
* Get the effective start position, considering layout-aware defaults
|
|
681
683
|
*/
|
|
682
684
|
resolveStartPosition() {
|
|
683
|
-
return this.config.start.position ? this.config.start.position :
|
|
685
|
+
return this.config.start.position ? this.config.start.position : be[this.layoutAlgorithm] || "nearest-edge";
|
|
684
686
|
}
|
|
685
687
|
/**
|
|
686
688
|
* Calculate the starting position for an image's entry animation
|
|
687
689
|
*/
|
|
688
|
-
calculateStartPosition(t, i, e,
|
|
689
|
-
const r = this.resolvedStartPosition,
|
|
690
|
+
calculateStartPosition(t, i, e, n, s) {
|
|
691
|
+
const r = this.resolvedStartPosition, a = this.config.start.offset ?? 100;
|
|
690
692
|
switch (r) {
|
|
691
693
|
case "nearest-edge":
|
|
692
|
-
return this.calculateNearestEdge(t, i, e,
|
|
694
|
+
return this.calculateNearestEdge(t, i, e, a);
|
|
693
695
|
case "top":
|
|
694
|
-
return this.calculateEdgePosition("top", t, i, e,
|
|
696
|
+
return this.calculateEdgePosition("top", t, i, e, a);
|
|
695
697
|
case "bottom":
|
|
696
|
-
return this.calculateEdgePosition("bottom", t, i, e,
|
|
698
|
+
return this.calculateEdgePosition("bottom", t, i, e, a);
|
|
697
699
|
case "left":
|
|
698
|
-
return this.calculateEdgePosition("left", t, i, e,
|
|
700
|
+
return this.calculateEdgePosition("left", t, i, e, a);
|
|
699
701
|
case "right":
|
|
700
|
-
return this.calculateEdgePosition("right", t, i, e,
|
|
702
|
+
return this.calculateEdgePosition("right", t, i, e, a);
|
|
701
703
|
case "center":
|
|
702
704
|
return this.calculateCenterPosition(e, t, i);
|
|
703
705
|
case "random-edge":
|
|
704
|
-
return this.calculateRandomEdge(t, i, e,
|
|
706
|
+
return this.calculateRandomEdge(t, i, e, a);
|
|
705
707
|
case "circular":
|
|
706
708
|
return this.calculateCircularPosition(
|
|
707
709
|
t,
|
|
708
710
|
i,
|
|
709
711
|
e,
|
|
710
|
-
|
|
711
|
-
|
|
712
|
+
n,
|
|
713
|
+
s
|
|
712
714
|
);
|
|
713
715
|
default:
|
|
714
|
-
return this.calculateNearestEdge(t, i, e,
|
|
716
|
+
return this.calculateNearestEdge(t, i, e, a);
|
|
715
717
|
}
|
|
716
718
|
}
|
|
717
719
|
/**
|
|
718
720
|
* Calculate start position from the nearest edge (current default behavior)
|
|
719
721
|
*/
|
|
720
|
-
calculateNearestEdge(t, i, e,
|
|
721
|
-
const
|
|
722
|
-
let d = t.x,
|
|
723
|
-
return h ===
|
|
722
|
+
calculateNearestEdge(t, i, e, n) {
|
|
723
|
+
const s = t.x, r = t.y, a = s, c = e.width - s, l = r, u = e.height - r, h = Math.min(a, c, l, u);
|
|
724
|
+
let d = t.x, g = t.y;
|
|
725
|
+
return h === a ? d = -(i.width + n) : h === c ? d = e.width + n : h === l ? g = -(i.height + n) : g = e.height + n, { x: d, y: g };
|
|
724
726
|
}
|
|
725
727
|
/**
|
|
726
728
|
* Calculate start position from a specific edge
|
|
727
729
|
*/
|
|
728
|
-
calculateEdgePosition(t, i, e,
|
|
729
|
-
let r = i.x,
|
|
730
|
+
calculateEdgePosition(t, i, e, n, s) {
|
|
731
|
+
let r = i.x, a = i.y;
|
|
730
732
|
switch (t) {
|
|
731
733
|
case "top":
|
|
732
|
-
|
|
734
|
+
a = -(e.height + s);
|
|
733
735
|
break;
|
|
734
736
|
case "bottom":
|
|
735
|
-
|
|
737
|
+
a = n.height + s;
|
|
736
738
|
break;
|
|
737
739
|
case "left":
|
|
738
|
-
r = -(e.width +
|
|
740
|
+
r = -(e.width + s);
|
|
739
741
|
break;
|
|
740
742
|
case "right":
|
|
741
|
-
r =
|
|
743
|
+
r = n.width + s;
|
|
742
744
|
break;
|
|
743
745
|
}
|
|
744
|
-
return { x: r, y:
|
|
746
|
+
return { x: r, y: a };
|
|
745
747
|
}
|
|
746
748
|
/**
|
|
747
749
|
* Calculate start position from center with scale animation
|
|
748
750
|
*/
|
|
749
751
|
calculateCenterPosition(t, i, e) {
|
|
750
|
-
const
|
|
752
|
+
const n = t.width / 2, s = t.height / 2;
|
|
751
753
|
return {
|
|
752
|
-
x:
|
|
753
|
-
y:
|
|
754
|
+
x: n,
|
|
755
|
+
y: s,
|
|
754
756
|
useScale: !0
|
|
755
757
|
// Signal to use scale animation from 0
|
|
756
758
|
};
|
|
@@ -758,15 +760,15 @@ class be {
|
|
|
758
760
|
/**
|
|
759
761
|
* Calculate start position from a random edge
|
|
760
762
|
*/
|
|
761
|
-
calculateRandomEdge(t, i, e,
|
|
762
|
-
const
|
|
763
|
-
return this.calculateEdgePosition(r, t, i, e,
|
|
763
|
+
calculateRandomEdge(t, i, e, n) {
|
|
764
|
+
const s = ["top", "bottom", "left", "right"], r = s[Math.floor(Math.random() * s.length)];
|
|
765
|
+
return this.calculateEdgePosition(r, t, i, e, n);
|
|
764
766
|
}
|
|
765
767
|
/**
|
|
766
768
|
* Calculate start position on a circle around the container
|
|
767
769
|
*/
|
|
768
|
-
calculateCircularPosition(t, i, e,
|
|
769
|
-
const r = this.config.start.circular || {},
|
|
770
|
+
calculateCircularPosition(t, i, e, n, s) {
|
|
771
|
+
const r = this.config.start.circular || {}, a = r.distribution || "even";
|
|
770
772
|
let c;
|
|
771
773
|
const l = r.radius || "120%";
|
|
772
774
|
if (typeof l == "string" && l.endsWith("%")) {
|
|
@@ -777,9 +779,9 @@ class be {
|
|
|
777
779
|
} else
|
|
778
780
|
c = typeof l == "number" ? l : 500;
|
|
779
781
|
let u;
|
|
780
|
-
|
|
781
|
-
const h = e.width / 2, d = e.height / 2,
|
|
782
|
-
return { x:
|
|
782
|
+
a === "even" ? u = n / s * 2 * Math.PI : u = Math.random() * 2 * Math.PI;
|
|
783
|
+
const h = e.width / 2, d = e.height / 2, g = h + Math.cos(u) * c, b = d + Math.sin(u) * c;
|
|
784
|
+
return { x: g, y: b };
|
|
783
785
|
}
|
|
784
786
|
/**
|
|
785
787
|
* Get animation parameters for an image
|
|
@@ -798,18 +800,18 @@ class be {
|
|
|
798
800
|
* Build a CSS transform string for the start position
|
|
799
801
|
* Uses pixel-based centering offset for reliable cross-browser behavior
|
|
800
802
|
*/
|
|
801
|
-
buildStartTransform(t, i, e,
|
|
802
|
-
const l = t.x - i.x, u = t.y - i.y, h =
|
|
803
|
+
buildStartTransform(t, i, e, n, s, r, a, c) {
|
|
804
|
+
const l = t.x - i.x, u = t.y - i.y, h = a !== void 0 ? a : e, d = c !== void 0 ? c : n, g = s !== void 0 ? -s / 2 : 0, b = r !== void 0 ? -r / 2 : 0, p = s !== void 0 ? `translate(${g}px, ${b}px)` : "translate(-50%, -50%)";
|
|
803
805
|
return t.useScale ? `${p} translate(${l}px, ${u}px) rotate(${h}deg) scale(0)` : `${p} translate(${l}px, ${u}px) rotate(${h}deg) scale(${d})`;
|
|
804
806
|
}
|
|
805
807
|
/**
|
|
806
808
|
* Build the final CSS transform string
|
|
807
809
|
* Uses pixel-based centering offset for reliable cross-browser behavior
|
|
808
810
|
*/
|
|
809
|
-
buildFinalTransform(t, i, e,
|
|
810
|
-
if (e !== void 0 &&
|
|
811
|
-
const
|
|
812
|
-
return `translate(${
|
|
811
|
+
buildFinalTransform(t, i, e, n) {
|
|
812
|
+
if (e !== void 0 && n !== void 0) {
|
|
813
|
+
const s = -e / 2, r = -n / 2;
|
|
814
|
+
return `translate(${s}px, ${r}px) rotate(${t}deg) scale(${i})`;
|
|
813
815
|
}
|
|
814
816
|
return `translate(-50%, -50%) rotate(${t}deg) scale(${i})`;
|
|
815
817
|
}
|
|
@@ -874,12 +876,12 @@ class be {
|
|
|
874
876
|
return t + (Math.random() - 0.5) * 60;
|
|
875
877
|
if (typeof e == "number")
|
|
876
878
|
return e;
|
|
877
|
-
const
|
|
878
|
-
return e.min + Math.random() *
|
|
879
|
+
const n = e.max - e.min;
|
|
880
|
+
return e.min + Math.random() * n;
|
|
879
881
|
}
|
|
880
882
|
case "spin": {
|
|
881
|
-
const e = this.rotationConfig.spinCount ?? 1,
|
|
882
|
-
return t + e * 360 *
|
|
883
|
+
const e = this.rotationConfig.spinCount ?? 1, n = this.resolveSpinDirection(t);
|
|
884
|
+
return t + e * 360 * n;
|
|
883
885
|
}
|
|
884
886
|
case "random":
|
|
885
887
|
return t + (Math.random() - 0.5) * 60;
|
|
@@ -927,7 +929,7 @@ class be {
|
|
|
927
929
|
amplitude: 15,
|
|
928
930
|
frequency: 3,
|
|
929
931
|
decay: !0
|
|
930
|
-
}, { amplitude:
|
|
932
|
+
}, { amplitude: n, frequency: s, decay: r } = e, a = Math.sin(t * s * Math.PI * 2), c = r ? Math.pow(1 - t, 2) : 1, l = n * a * c;
|
|
931
933
|
return i + l;
|
|
932
934
|
}
|
|
933
935
|
/**
|
|
@@ -984,15 +986,15 @@ class be {
|
|
|
984
986
|
const e = this.scaleConfig.pop || {
|
|
985
987
|
overshoot: 1.2,
|
|
986
988
|
bounces: 1
|
|
987
|
-
}, { overshoot:
|
|
988
|
-
let
|
|
989
|
+
}, { overshoot: n, bounces: s } = e, r = this.generateScaleBounceKeyframes(s, n);
|
|
990
|
+
let a = i;
|
|
989
991
|
for (let c = 0; c < r.length; c++)
|
|
990
992
|
if (t <= r[c].time) {
|
|
991
993
|
const l = c === 0 ? 0 : r[c - 1].time, u = c === 0 ? i : r[c - 1].scale, h = (t - l) / (r[c].time - l), d = this.easeOutQuad(h);
|
|
992
|
-
|
|
994
|
+
a = u + (r[c].scale - u) * d;
|
|
993
995
|
break;
|
|
994
996
|
}
|
|
995
|
-
return
|
|
997
|
+
return a * i;
|
|
996
998
|
}
|
|
997
999
|
/**
|
|
998
1000
|
* Generate keyframes for scale bounce animation
|
|
@@ -1000,12 +1002,12 @@ class be {
|
|
|
1000
1002
|
generateScaleBounceKeyframes(t, i) {
|
|
1001
1003
|
const e = [];
|
|
1002
1004
|
e.push({ time: 0.5, scale: i });
|
|
1003
|
-
let
|
|
1004
|
-
const
|
|
1005
|
+
let n = i;
|
|
1006
|
+
const s = 0.5, a = 0.5 / (t * 2);
|
|
1005
1007
|
let c = 0.5;
|
|
1006
1008
|
for (let l = 0; l < t; l++) {
|
|
1007
|
-
const u = 1 - (
|
|
1008
|
-
c +=
|
|
1009
|
+
const u = 1 - (n - 1) * s;
|
|
1010
|
+
c += a, e.push({ time: c, scale: u }), n = 1 + (n - 1) * s * s, c += a, l < t - 1 && e.push({ time: c, scale: n });
|
|
1009
1011
|
}
|
|
1010
1012
|
return e.push({ time: 1, scale: 1 }), e;
|
|
1011
1013
|
}
|
|
@@ -1024,9 +1026,9 @@ class ve {
|
|
|
1024
1026
|
* Register an image element for idle animation.
|
|
1025
1027
|
* Starts animation after entry duration completes.
|
|
1026
1028
|
*/
|
|
1027
|
-
register(t, i, e,
|
|
1029
|
+
register(t, i, e, n) {
|
|
1028
1030
|
if (this.entries.has(t)) return;
|
|
1029
|
-
const
|
|
1031
|
+
const s = n ?? this.entryDurationMs, r = this.config.startDelay ?? s, a = {
|
|
1030
1032
|
element: t,
|
|
1031
1033
|
index: i,
|
|
1032
1034
|
totalImages: e,
|
|
@@ -1037,8 +1039,8 @@ class ve {
|
|
|
1037
1039
|
stopped: !1,
|
|
1038
1040
|
startTimer: null
|
|
1039
1041
|
};
|
|
1040
|
-
this.entries.set(t,
|
|
1041
|
-
|
|
1042
|
+
this.entries.set(t, a), a.startTimer = setTimeout(() => {
|
|
1043
|
+
a.startTimer = null, !a.stopped && !a.paused && this._startAnimation(a);
|
|
1042
1044
|
}, r);
|
|
1043
1045
|
}
|
|
1044
1046
|
/**
|
|
@@ -1141,28 +1143,28 @@ class ve {
|
|
|
1141
1143
|
});
|
|
1142
1144
|
}
|
|
1143
1145
|
_startBlink(t) {
|
|
1144
|
-
const i = { ...Kt, ...this.config.blink }, e = -(Math.random() * i.speed),
|
|
1145
|
-
let
|
|
1146
|
-
i.style === "fade" ? (
|
|
1147
|
-
{ opacity:
|
|
1146
|
+
const i = { ...Kt, ...this.config.blink }, e = -(Math.random() * i.speed), n = parseFloat(getComputedStyle(t.element).opacity) || 1;
|
|
1147
|
+
let s, r;
|
|
1148
|
+
i.style === "fade" ? (s = [
|
|
1149
|
+
{ opacity: n, offset: 0 },
|
|
1148
1150
|
{ opacity: 0, offset: 0.5 },
|
|
1149
|
-
{ opacity:
|
|
1151
|
+
{ opacity: n, offset: 1 }
|
|
1150
1152
|
], r = {
|
|
1151
1153
|
duration: i.speed,
|
|
1152
1154
|
delay: e,
|
|
1153
1155
|
iterations: 1 / 0,
|
|
1154
1156
|
easing: "ease-in-out"
|
|
1155
|
-
}) : (
|
|
1156
|
-
{ opacity:
|
|
1157
|
-
{ opacity:
|
|
1157
|
+
}) : (s = [
|
|
1158
|
+
{ opacity: n, offset: 0 },
|
|
1159
|
+
{ opacity: n, offset: i.onRatio },
|
|
1158
1160
|
{ opacity: 0, offset: Math.min(i.onRatio + 0.01, 0.99) },
|
|
1159
1161
|
{ opacity: 0, offset: 0.99 },
|
|
1160
|
-
{ opacity:
|
|
1162
|
+
{ opacity: n, offset: 1 }
|
|
1161
1163
|
], r = {
|
|
1162
1164
|
duration: i.speed,
|
|
1163
1165
|
delay: e,
|
|
1164
1166
|
iterations: 1 / 0
|
|
1165
|
-
}), t.blinkAnimation = t.element.animate(
|
|
1167
|
+
}), t.blinkAnimation = t.element.animate(s, r);
|
|
1166
1168
|
}
|
|
1167
1169
|
_startSpin(t) {
|
|
1168
1170
|
const i = { ...Zt, ...this.config.spin }, e = i.direction === "clockwise" ? 360 : -360;
|
|
@@ -1186,8 +1188,8 @@ class ve {
|
|
|
1186
1188
|
if (this.togetherSpeed = t, this.togetherRafId !== null) return;
|
|
1187
1189
|
const i = () => {
|
|
1188
1190
|
const e = performance.now() % this.togetherSpeed;
|
|
1189
|
-
for (const
|
|
1190
|
-
!
|
|
1191
|
+
for (const n of this.entries.values())
|
|
1192
|
+
!n.stopped && !n.paused && n.animation && (n.animation.currentTime = e);
|
|
1191
1193
|
this.togetherRafId = requestAnimationFrame(i);
|
|
1192
1194
|
};
|
|
1193
1195
|
this.togetherRafId = requestAnimationFrame(i);
|
|
@@ -1202,7 +1204,7 @@ class ve {
|
|
|
1202
1204
|
t.animation && (t.animation.cancel(), t.animation = null), t.blinkAnimation && (t.blinkAnimation.cancel(), t.blinkAnimation = null), t.customTeardown && (t.customTeardown(), t.customTeardown = null);
|
|
1203
1205
|
}
|
|
1204
1206
|
}
|
|
1205
|
-
class
|
|
1207
|
+
class Ee {
|
|
1206
1208
|
constructor(t, i = {}) {
|
|
1207
1209
|
this.config = t, this.imageConfig = i;
|
|
1208
1210
|
}
|
|
@@ -1214,19 +1216,19 @@ class we {
|
|
|
1214
1216
|
* @returns Array of layout objects with position, rotation, scale
|
|
1215
1217
|
*/
|
|
1216
1218
|
generate(t, i, e = {}) {
|
|
1217
|
-
const
|
|
1218
|
-
for (let
|
|
1219
|
-
const I = this.random(v,
|
|
1220
|
-
id:
|
|
1219
|
+
const n = [], { width: s, height: r } = i, a = this.config.spacing.padding, c = e.fixedHeight ?? 200, l = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, h = this.imageConfig.rotation?.range?.max ?? 15, d = this.imageConfig.sizing?.variance?.min ?? 1, g = this.imageConfig.sizing?.variance?.max ?? 1, b = d !== 1 || g !== 1, f = c * 1.5 / 2, m = c / 2, y = s - a - f, E = r - a - m, v = a + f, S = a + m;
|
|
1220
|
+
for (let w = 0; w < t; w++) {
|
|
1221
|
+
const I = this.random(v, y), z = this.random(S, E), L = l === "random" ? this.random(u, h) : 0, _ = b ? this.random(d, g) : 1, O = c * _, H = {
|
|
1222
|
+
id: w,
|
|
1221
1223
|
x: I,
|
|
1222
1224
|
y: z,
|
|
1223
1225
|
rotation: L,
|
|
1224
1226
|
scale: _,
|
|
1225
1227
|
baseSize: O
|
|
1226
1228
|
};
|
|
1227
|
-
|
|
1229
|
+
n.push(H);
|
|
1228
1230
|
}
|
|
1229
|
-
return
|
|
1231
|
+
return n;
|
|
1230
1232
|
}
|
|
1231
1233
|
/**
|
|
1232
1234
|
* Utility: Generate random number between min and max
|
|
@@ -1238,7 +1240,7 @@ class we {
|
|
|
1238
1240
|
return Math.random() * (i - t) + t;
|
|
1239
1241
|
}
|
|
1240
1242
|
}
|
|
1241
|
-
class
|
|
1243
|
+
class we {
|
|
1242
1244
|
constructor(t, i = {}) {
|
|
1243
1245
|
this.config = t, this.imageConfig = i;
|
|
1244
1246
|
}
|
|
@@ -1250,19 +1252,19 @@ class xe {
|
|
|
1250
1252
|
* @returns Array of layout objects with position, rotation, scale
|
|
1251
1253
|
*/
|
|
1252
1254
|
generate(t, i, e = {}) {
|
|
1253
|
-
const
|
|
1254
|
-
...
|
|
1255
|
+
const n = [], { width: s, height: r } = i, a = e.fixedHeight ?? 200, c = this.imageConfig.rotation?.mode ?? "none", l = this.imageConfig.rotation?.range?.min ?? -15, u = this.imageConfig.rotation?.range?.max ?? 15, h = this.imageConfig.sizing?.variance?.min ?? 1, d = this.imageConfig.sizing?.variance?.max ?? 1, g = h !== 1 || d !== 1, b = this.config.scaleDecay ?? 0, p = {
|
|
1256
|
+
...jt,
|
|
1255
1257
|
...this.config.radial
|
|
1256
|
-
},
|
|
1257
|
-
m - v -
|
|
1258
|
-
|
|
1258
|
+
}, f = e.fixedHeight ?? a, m = s / 2, y = r / 2, E = Math.ceil(Math.sqrt(t)), v = this.config.spacing.padding ?? 50, S = Math.max(f * 0.8, Math.min(
|
|
1259
|
+
m - v - f / 2,
|
|
1260
|
+
y - v - f / 2
|
|
1259
1261
|
));
|
|
1260
1262
|
if (t > 0) {
|
|
1261
|
-
const z =
|
|
1262
|
-
|
|
1263
|
+
const z = g ? this.random(h, d) : 1, L = f * z;
|
|
1264
|
+
n.push({
|
|
1263
1265
|
id: 0,
|
|
1264
1266
|
x: m,
|
|
1265
|
-
y
|
|
1267
|
+
y,
|
|
1266
1268
|
rotation: c === "random" ? this.random(l * 0.33, u * 0.33) : 0,
|
|
1267
1269
|
// Less rotation for center
|
|
1268
1270
|
scale: z,
|
|
@@ -1271,34 +1273,34 @@ class xe {
|
|
|
1271
1273
|
// Center image is highest
|
|
1272
1274
|
});
|
|
1273
1275
|
}
|
|
1274
|
-
let
|
|
1275
|
-
for (;
|
|
1276
|
-
const z = I /
|
|
1276
|
+
let w = 1, I = 1;
|
|
1277
|
+
for (; w < t; ) {
|
|
1278
|
+
const z = I / E, L = b > 0 ? 1 - z * b * 0.5 : 1, _ = Math.max(f * 0.8, S / E * 1.5 / p.tightness), O = I * _, H = O * 1.5, N = Math.PI * (3 * (H + O) - Math.sqrt((3 * H + O) * (H + 3 * O))), A = this.estimateWidth(f), D = Math.floor(N / (A * 0.7));
|
|
1277
1279
|
if (D === 0) {
|
|
1278
1280
|
I++;
|
|
1279
1281
|
continue;
|
|
1280
1282
|
}
|
|
1281
|
-
const
|
|
1282
|
-
for (let
|
|
1283
|
-
const
|
|
1284
|
-
let $ = m + Math.cos(
|
|
1285
|
-
const P =
|
|
1286
|
-
$ - P < v ? $ = v + P : $ + P >
|
|
1283
|
+
const W = 2 * Math.PI / D, U = I * (20 * Math.PI / 180);
|
|
1284
|
+
for (let F = 0; F < D && w < t; F++) {
|
|
1285
|
+
const C = F * W + U, k = g ? this.random(h, d) : 1, q = L * k, T = f * q;
|
|
1286
|
+
let $ = m + Math.cos(C) * H, M = y + Math.sin(C) * O;
|
|
1287
|
+
const P = T * 1.5 / 2, B = T / 2;
|
|
1288
|
+
$ - P < v ? $ = v + P : $ + P > s - v && ($ = s - v - P), M - B < v ? M = v + B : M + B > r - v && (M = r - v - B);
|
|
1287
1289
|
const Y = c === "random" ? this.random(l, u) : 0;
|
|
1288
|
-
|
|
1289
|
-
id:
|
|
1290
|
+
n.push({
|
|
1291
|
+
id: w,
|
|
1290
1292
|
x: $,
|
|
1291
|
-
y:
|
|
1293
|
+
y: M,
|
|
1292
1294
|
rotation: Y,
|
|
1293
|
-
scale:
|
|
1294
|
-
baseSize:
|
|
1295
|
+
scale: q,
|
|
1296
|
+
baseSize: T,
|
|
1295
1297
|
zIndex: Math.max(1, 100 - I)
|
|
1296
1298
|
// Outer rings have lower z-index
|
|
1297
|
-
}),
|
|
1299
|
+
}), w++;
|
|
1298
1300
|
}
|
|
1299
1301
|
I++;
|
|
1300
1302
|
}
|
|
1301
|
-
return
|
|
1303
|
+
return n;
|
|
1302
1304
|
}
|
|
1303
1305
|
/**
|
|
1304
1306
|
* Estimate image width based on height
|
|
@@ -1319,7 +1321,7 @@ class xe {
|
|
|
1319
1321
|
return Math.random() * (i - t) + t;
|
|
1320
1322
|
}
|
|
1321
1323
|
}
|
|
1322
|
-
const
|
|
1324
|
+
const xe = {
|
|
1323
1325
|
columns: "auto",
|
|
1324
1326
|
rows: "auto",
|
|
1325
1327
|
stagger: "none",
|
|
@@ -1329,7 +1331,7 @@ const Ee = {
|
|
|
1329
1331
|
alignment: "center",
|
|
1330
1332
|
gap: 10,
|
|
1331
1333
|
overflowOffset: 0.25
|
|
1332
|
-
},
|
|
1334
|
+
}, Tt = [
|
|
1333
1335
|
{ x: 1, y: 1 },
|
|
1334
1336
|
// bottom-right
|
|
1335
1337
|
{ x: -1, y: -1 },
|
|
@@ -1359,86 +1361,86 @@ class Se {
|
|
|
1359
1361
|
* @returns Array of layout objects with position, rotation, scale
|
|
1360
1362
|
*/
|
|
1361
1363
|
generate(t, i, e = {}) {
|
|
1362
|
-
const
|
|
1364
|
+
const n = [], { width: s, height: r } = i, a = { ...xe, ...this.config.grid }, c = this.config.spacing.padding, l = e.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", h = this.imageConfig.sizing?.variance?.min ?? 1, d = this.imageConfig.sizing?.variance?.max ?? 1, g = h !== 1 || d !== 1, b = s - 2 * c, p = r - 2 * c, { columns: f, rows: m } = this.calculateGridDimensions(
|
|
1363
1365
|
t,
|
|
1364
|
-
|
|
1366
|
+
b,
|
|
1365
1367
|
p,
|
|
1366
1368
|
l,
|
|
1367
|
-
|
|
1368
|
-
),
|
|
1369
|
+
a
|
|
1370
|
+
), y = a.stagger === "row", E = a.stagger === "column", v = y ? f + 0.5 : f, S = E ? m + 0.5 : m, w = (b - a.gap * (f - 1)) / v, I = (p - a.gap * (m - 1)) / S, z = y ? w / 2 : 0, L = E ? I / 2 : 0, _ = 1 + a.overlap, O = Math.min(w, I) * _, H = e.fixedHeight ? Math.min(e.fixedHeight, O) : O, N = f * w + (f - 1) * a.gap + z, A = m * I + (m - 1) * a.gap + L, D = c + (b - N) / 2, W = c + (p - A) / 2, U = f * m, F = a.columns !== "auto" && a.rows !== "auto", C = F && t > U;
|
|
1369
1371
|
typeof window < "u" && (window.__gridOverflowDebug = {
|
|
1370
|
-
gridConfigColumns:
|
|
1371
|
-
gridConfigRows:
|
|
1372
|
-
columns:
|
|
1372
|
+
gridConfigColumns: a.columns,
|
|
1373
|
+
gridConfigRows: a.rows,
|
|
1374
|
+
columns: f,
|
|
1373
1375
|
rows: m,
|
|
1374
1376
|
cellCount: U,
|
|
1375
|
-
hasFixedGrid:
|
|
1377
|
+
hasFixedGrid: F,
|
|
1376
1378
|
imageCount: t,
|
|
1377
|
-
isOverflowMode:
|
|
1379
|
+
isOverflowMode: C
|
|
1378
1380
|
});
|
|
1379
|
-
const k =
|
|
1380
|
-
for (let
|
|
1381
|
-
let $,
|
|
1382
|
-
if (
|
|
1383
|
-
const
|
|
1384
|
-
X = Math.floor(
|
|
1381
|
+
const k = C ? new Array(U).fill(0) : [], q = Math.min(w, I) * a.overflowOffset;
|
|
1382
|
+
for (let T = 0; T < t; T++) {
|
|
1383
|
+
let $, M, X = 0;
|
|
1384
|
+
if (C && T >= U) {
|
|
1385
|
+
const G = T - U, j = G % U;
|
|
1386
|
+
X = Math.floor(G / U) + 1, k[j]++, a.fillDirection === "row" ? ($ = j % f, M = Math.floor(j / f)) : (M = j % m, $ = Math.floor(j / m));
|
|
1385
1387
|
} else
|
|
1386
|
-
|
|
1387
|
-
let P = D + $ * (
|
|
1388
|
-
if (
|
|
1389
|
-
const
|
|
1390
|
-
P +=
|
|
1388
|
+
a.fillDirection === "row" ? ($ = T % f, M = Math.floor(T / f)) : (M = T % m, $ = Math.floor(T / m));
|
|
1389
|
+
let P = D + $ * (w + a.gap) + w / 2, B = W + M * (I + a.gap) + I / 2;
|
|
1390
|
+
if (a.stagger === "row" && M % 2 === 1 ? P += w / 2 : a.stagger === "column" && $ % 2 === 1 && (B += I / 2), X > 0) {
|
|
1391
|
+
const G = (X - 1) % Tt.length, j = Tt[G];
|
|
1392
|
+
P += j.x * q, B += j.y * q;
|
|
1391
1393
|
}
|
|
1392
|
-
if (
|
|
1393
|
-
const
|
|
1394
|
-
P += this.random(-
|
|
1394
|
+
if (a.jitter > 0) {
|
|
1395
|
+
const G = w / 2 * a.jitter, j = I / 2 * a.jitter;
|
|
1396
|
+
P += this.random(-G, G), B += this.random(-j, j);
|
|
1395
1397
|
}
|
|
1396
|
-
let Y = P, V =
|
|
1397
|
-
if (!
|
|
1398
|
-
const
|
|
1399
|
-
if (
|
|
1400
|
-
const St =
|
|
1398
|
+
let Y = P, V = B;
|
|
1399
|
+
if (!C && a.fillDirection === "row") {
|
|
1400
|
+
const G = t % f || f;
|
|
1401
|
+
if (M === Math.floor((t - 1) / f) && G < f) {
|
|
1402
|
+
const St = G * w + (G - 1) * a.gap;
|
|
1401
1403
|
let gt = 0;
|
|
1402
|
-
|
|
1404
|
+
a.alignment === "center" ? gt = (N - St) / 2 : a.alignment === "end" && (gt = N - St), Y += gt;
|
|
1403
1405
|
}
|
|
1404
1406
|
}
|
|
1405
|
-
const
|
|
1406
|
-
Y = Math.max(
|
|
1407
|
-
let
|
|
1407
|
+
const ct = g ? this.random(h, d) : 1, K = H * ct, nt = K * 1.5 / 2, ot = K / 2, ht = c + nt, dt = s - c - nt, _t = c + ot, Ut = r - c - ot;
|
|
1408
|
+
Y = Math.max(ht, Math.min(Y, dt)), V = Math.max(_t, Math.min(V, Ut));
|
|
1409
|
+
let ut = 0;
|
|
1408
1410
|
if (u === "random") {
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
+
const G = this.imageConfig.rotation?.range?.min ?? -15, j = this.imageConfig.rotation?.range?.max ?? 15;
|
|
1412
|
+
a.jitter > 0 ? ut = this.random(G * a.jitter, j * a.jitter) : ut = this.random(G, j);
|
|
1411
1413
|
}
|
|
1412
|
-
let
|
|
1413
|
-
|
|
1414
|
-
id:
|
|
1414
|
+
let ft;
|
|
1415
|
+
C && X > 0 ? ft = 50 - X : ft = C ? 100 + T : T + 1, n.push({
|
|
1416
|
+
id: T,
|
|
1415
1417
|
x: Y,
|
|
1416
1418
|
y: V,
|
|
1417
|
-
rotation:
|
|
1418
|
-
scale:
|
|
1419
|
+
rotation: ut,
|
|
1420
|
+
scale: ct,
|
|
1419
1421
|
baseSize: K,
|
|
1420
|
-
zIndex:
|
|
1422
|
+
zIndex: ft
|
|
1421
1423
|
});
|
|
1422
1424
|
}
|
|
1423
|
-
return
|
|
1425
|
+
return n;
|
|
1424
1426
|
}
|
|
1425
1427
|
/**
|
|
1426
1428
|
* Calculate optimal grid dimensions based on image count and container
|
|
1427
1429
|
*/
|
|
1428
|
-
calculateGridDimensions(t, i, e,
|
|
1429
|
-
let r,
|
|
1430
|
-
if (
|
|
1431
|
-
r =
|
|
1432
|
-
else if (
|
|
1433
|
-
r =
|
|
1434
|
-
else if (
|
|
1435
|
-
|
|
1430
|
+
calculateGridDimensions(t, i, e, n, s) {
|
|
1431
|
+
let r, a;
|
|
1432
|
+
if (s.columns !== "auto" && s.rows !== "auto")
|
|
1433
|
+
r = s.columns, a = s.rows;
|
|
1434
|
+
else if (s.columns !== "auto")
|
|
1435
|
+
r = s.columns, a = Math.ceil(t / r);
|
|
1436
|
+
else if (s.rows !== "auto")
|
|
1437
|
+
a = s.rows, r = Math.ceil(t / a);
|
|
1436
1438
|
else {
|
|
1437
1439
|
const c = i / e;
|
|
1438
|
-
for (r = Math.max(1, Math.round(Math.sqrt(t * c / 1.4))),
|
|
1440
|
+
for (r = Math.max(1, Math.round(Math.sqrt(t * c / 1.4))), a = Math.ceil(t / r); r > 1 && (r - 1) * a >= t; )
|
|
1439
1441
|
r--;
|
|
1440
1442
|
}
|
|
1441
|
-
return { columns: Math.max(1, r), rows: Math.max(1,
|
|
1443
|
+
return { columns: Math.max(1, r), rows: Math.max(1, a) };
|
|
1442
1444
|
}
|
|
1443
1445
|
/**
|
|
1444
1446
|
* Utility: Generate random number between min and max
|
|
@@ -1454,7 +1456,7 @@ const Ie = Math.PI * (3 - Math.sqrt(5)), Re = {
|
|
|
1454
1456
|
scaleDecay: 0,
|
|
1455
1457
|
startAngle: 0
|
|
1456
1458
|
};
|
|
1457
|
-
class
|
|
1459
|
+
class Ae {
|
|
1458
1460
|
constructor(t, i = {}) {
|
|
1459
1461
|
this.config = t, this.imageConfig = i;
|
|
1460
1462
|
}
|
|
@@ -1466,80 +1468,80 @@ class Te {
|
|
|
1466
1468
|
* @returns Array of layout objects with position, rotation, scale
|
|
1467
1469
|
*/
|
|
1468
1470
|
generate(t, i, e = {}) {
|
|
1469
|
-
const
|
|
1471
|
+
const n = [], { width: s, height: r } = i, a = { ...Re, ...this.config.spiral }, c = this.config.spacing.padding, l = e.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", h = this.imageConfig.rotation?.range?.min ?? -15, d = this.imageConfig.rotation?.range?.max ?? 15, g = this.imageConfig.sizing?.variance?.min ?? 1, b = this.imageConfig.sizing?.variance?.max ?? 1, p = g !== 1 || b !== 1, f = this.config.scaleDecay ?? a.scaleDecay, m = s / 2, y = r / 2, E = Math.min(
|
|
1470
1472
|
m - c - l / 2,
|
|
1471
|
-
|
|
1472
|
-
), v =
|
|
1473
|
+
y - c - l / 2
|
|
1474
|
+
), v = a.direction === "clockwise" ? -1 : 1;
|
|
1473
1475
|
for (let S = 0; S < t; S++) {
|
|
1474
|
-
let
|
|
1475
|
-
if (
|
|
1476
|
-
|
|
1477
|
-
else if (
|
|
1478
|
-
const P = S * 0.5 *
|
|
1479
|
-
|
|
1476
|
+
let w, I;
|
|
1477
|
+
if (a.spiralType === "golden")
|
|
1478
|
+
w = S * Ie * v + a.startAngle, I = this.calculateGoldenRadius(S, t, E, a.tightness);
|
|
1479
|
+
else if (a.spiralType === "archimedean") {
|
|
1480
|
+
const P = S * 0.5 * a.tightness;
|
|
1481
|
+
w = P * v + a.startAngle, I = this.calculateArchimedeanRadius(P, t, E, a.tightness);
|
|
1480
1482
|
} else {
|
|
1481
|
-
const P = S * 0.3 *
|
|
1482
|
-
|
|
1483
|
+
const P = S * 0.3 * a.tightness;
|
|
1484
|
+
w = P * v + a.startAngle, I = this.calculateLogarithmicRadius(P, t, E, a.tightness);
|
|
1483
1485
|
}
|
|
1484
|
-
const z = m + Math.cos(
|
|
1485
|
-
let
|
|
1486
|
+
const z = m + Math.cos(w) * I, L = y + Math.sin(w) * I, _ = I / E, O = f > 0 ? 1 - _ * f * 0.5 : 1, H = p ? this.random(g, b) : 1, N = O * H, A = l * N, W = A * 1.5 / 2, U = A / 2, F = c + W, C = s - c - W, k = c + U, q = r - c - U, T = Math.max(F, Math.min(z, C)), $ = Math.max(k, Math.min(L, q));
|
|
1487
|
+
let M = 0;
|
|
1486
1488
|
if (u === "random") {
|
|
1487
|
-
const P =
|
|
1488
|
-
|
|
1489
|
-
} else u === "tangent" && (
|
|
1489
|
+
const P = w * 180 / Math.PI % 360, B = this.random(h, d);
|
|
1490
|
+
M = a.spiralType === "golden" ? B : P * 0.1 + B * 0.9;
|
|
1491
|
+
} else u === "tangent" && (M = this.calculateSpiralTangent(w, I, a));
|
|
1490
1492
|
const X = t - S;
|
|
1491
|
-
|
|
1493
|
+
n.push({
|
|
1492
1494
|
id: S,
|
|
1493
|
-
x:
|
|
1495
|
+
x: T,
|
|
1494
1496
|
y: $,
|
|
1495
|
-
rotation:
|
|
1497
|
+
rotation: M,
|
|
1496
1498
|
scale: N,
|
|
1497
|
-
baseSize:
|
|
1499
|
+
baseSize: A,
|
|
1498
1500
|
zIndex: X
|
|
1499
1501
|
});
|
|
1500
1502
|
}
|
|
1501
|
-
return
|
|
1503
|
+
return n;
|
|
1502
1504
|
}
|
|
1503
1505
|
/**
|
|
1504
1506
|
* Calculate tangent angle for spiral curve at given position
|
|
1505
1507
|
* This aligns the image along the spiral's direction of travel
|
|
1506
1508
|
*/
|
|
1507
1509
|
calculateSpiralTangent(t, i, e) {
|
|
1508
|
-
let
|
|
1510
|
+
let n;
|
|
1509
1511
|
if (e.spiralType === "golden")
|
|
1510
|
-
|
|
1512
|
+
n = t + Math.PI / 2;
|
|
1511
1513
|
else if (e.spiralType === "archimedean") {
|
|
1512
|
-
const r = 1 / e.tightness,
|
|
1513
|
-
|
|
1514
|
+
const r = 1 / e.tightness, a = Math.atan(i / r);
|
|
1515
|
+
n = t + a;
|
|
1514
1516
|
} else {
|
|
1515
|
-
const r = 0.15 / e.tightness,
|
|
1516
|
-
|
|
1517
|
+
const r = 0.15 / e.tightness, a = Math.atan(1 / r);
|
|
1518
|
+
n = t + a;
|
|
1517
1519
|
}
|
|
1518
|
-
return
|
|
1520
|
+
return n * 180 / Math.PI % 360 - 90;
|
|
1519
1521
|
}
|
|
1520
1522
|
/**
|
|
1521
1523
|
* Calculate radius for golden spiral (Vogel's model)
|
|
1522
1524
|
* Creates even distribution like sunflower seeds
|
|
1523
1525
|
*/
|
|
1524
|
-
calculateGoldenRadius(t, i, e,
|
|
1525
|
-
const r = e / Math.sqrt(i) * Math.sqrt(t) /
|
|
1526
|
+
calculateGoldenRadius(t, i, e, n) {
|
|
1527
|
+
const r = e / Math.sqrt(i) * Math.sqrt(t) / n;
|
|
1526
1528
|
return Math.min(r, e);
|
|
1527
1529
|
}
|
|
1528
1530
|
/**
|
|
1529
1531
|
* Calculate radius for Archimedean spiral
|
|
1530
1532
|
* r = a + b*θ (constant spacing between arms)
|
|
1531
1533
|
*/
|
|
1532
|
-
calculateArchimedeanRadius(t, i, e,
|
|
1533
|
-
const
|
|
1534
|
-
return t /
|
|
1534
|
+
calculateArchimedeanRadius(t, i, e, n) {
|
|
1535
|
+
const s = i * 0.5 * n;
|
|
1536
|
+
return t / s * e;
|
|
1535
1537
|
}
|
|
1536
1538
|
/**
|
|
1537
1539
|
* Calculate radius for logarithmic (equiangular) spiral
|
|
1538
1540
|
* r = a * e^(b*θ)
|
|
1539
1541
|
*/
|
|
1540
|
-
calculateLogarithmicRadius(t, i, e,
|
|
1541
|
-
const
|
|
1542
|
-
return
|
|
1542
|
+
calculateLogarithmicRadius(t, i, e, n) {
|
|
1543
|
+
const s = e * 0.05, r = 0.15 / n, a = s * Math.exp(r * t), c = i * 0.3 * n, l = s * Math.exp(r * c);
|
|
1544
|
+
return a / l * e;
|
|
1543
1545
|
}
|
|
1544
1546
|
/**
|
|
1545
1547
|
* Utility: Generate random number between min and max
|
|
@@ -1548,7 +1550,7 @@ class Te {
|
|
|
1548
1550
|
return Math.random() * (i - t) + t;
|
|
1549
1551
|
}
|
|
1550
1552
|
}
|
|
1551
|
-
const
|
|
1553
|
+
const Ce = {
|
|
1552
1554
|
clusterCount: "auto",
|
|
1553
1555
|
clusterSpread: 150,
|
|
1554
1556
|
clusterSpacing: 200,
|
|
@@ -1556,7 +1558,7 @@ const Ae = {
|
|
|
1556
1558
|
overlap: 0.3,
|
|
1557
1559
|
distribution: "gaussian"
|
|
1558
1560
|
};
|
|
1559
|
-
class
|
|
1561
|
+
class Te {
|
|
1560
1562
|
constructor(t, i = {}) {
|
|
1561
1563
|
this.config = t, this.imageConfig = i;
|
|
1562
1564
|
}
|
|
@@ -1568,85 +1570,85 @@ class Ce {
|
|
|
1568
1570
|
* @returns Array of layout objects with position, rotation, scale
|
|
1569
1571
|
*/
|
|
1570
1572
|
generate(t, i, e = {}) {
|
|
1571
|
-
const
|
|
1573
|
+
const n = [], { width: s, height: r } = i, a = { ...Ce, ...this.config.cluster }, c = this.config.spacing.padding, l = e.fixedHeight ?? 200, u = this.imageConfig.rotation?.mode ?? "none", h = this.imageConfig.rotation?.range?.min ?? -15, d = this.imageConfig.rotation?.range?.max ?? 15, g = this.imageConfig.sizing?.variance?.min ?? 1, b = this.imageConfig.sizing?.variance?.max ?? 1, p = g !== 1 || b !== 1, f = this.calculateClusterCount(
|
|
1572
1574
|
t,
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
+
a.clusterCount,
|
|
1576
|
+
s,
|
|
1575
1577
|
r,
|
|
1576
|
-
|
|
1578
|
+
a.clusterSpacing
|
|
1577
1579
|
), m = this.generateClusterCenters(
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
+
f,
|
|
1581
|
+
s,
|
|
1580
1582
|
r,
|
|
1581
1583
|
c,
|
|
1582
|
-
|
|
1583
|
-
),
|
|
1584
|
+
a
|
|
1585
|
+
), y = new Array(f).fill(0);
|
|
1584
1586
|
for (let v = 0; v < t; v++)
|
|
1585
|
-
|
|
1586
|
-
let
|
|
1587
|
-
for (let v = 0; v <
|
|
1588
|
-
const S = m[v],
|
|
1589
|
-
for (let I = 0; I <
|
|
1587
|
+
y[v % f]++;
|
|
1588
|
+
let E = 0;
|
|
1589
|
+
for (let v = 0; v < f; v++) {
|
|
1590
|
+
const S = m[v], w = y[v];
|
|
1591
|
+
for (let I = 0; I < w; I++) {
|
|
1590
1592
|
let z, L;
|
|
1591
|
-
if (
|
|
1593
|
+
if (a.distribution === "gaussian")
|
|
1592
1594
|
z = this.gaussianRandom() * S.spread, L = this.gaussianRandom() * S.spread;
|
|
1593
1595
|
else {
|
|
1594
|
-
const
|
|
1595
|
-
z = Math.cos(
|
|
1596
|
+
const M = this.random(0, Math.PI * 2), X = this.random(0, S.spread);
|
|
1597
|
+
z = Math.cos(M) * X, L = Math.sin(M) * X;
|
|
1596
1598
|
}
|
|
1597
|
-
const _ = 1 +
|
|
1599
|
+
const _ = 1 + a.overlap * 0.5, O = 1 + a.overlap * 0.3;
|
|
1598
1600
|
z /= _, L /= _;
|
|
1599
|
-
const H = p ? this.random(
|
|
1600
|
-
let D = S.x + z,
|
|
1601
|
-
const
|
|
1602
|
-
D = Math.max(c +
|
|
1603
|
-
const k = u === "random" ? this.random(h, d) : 0,
|
|
1604
|
-
|
|
1605
|
-
id:
|
|
1601
|
+
const H = p ? this.random(g, b) : 1, N = O * H, A = l * N;
|
|
1602
|
+
let D = S.x + z, W = S.y + L;
|
|
1603
|
+
const F = A * 1.5 / 2, C = A / 2;
|
|
1604
|
+
D = Math.max(c + F, Math.min(D, s - c - F)), W = Math.max(c + C, Math.min(W, r - c - C));
|
|
1605
|
+
const k = u === "random" ? this.random(h, d) : 0, T = Math.sqrt(z * z + L * L) / S.spread, $ = Math.round((1 - T) * 50) + 1;
|
|
1606
|
+
n.push({
|
|
1607
|
+
id: E,
|
|
1606
1608
|
x: D,
|
|
1607
|
-
y:
|
|
1609
|
+
y: W,
|
|
1608
1610
|
rotation: k,
|
|
1609
1611
|
scale: N,
|
|
1610
|
-
baseSize:
|
|
1612
|
+
baseSize: A,
|
|
1611
1613
|
zIndex: $
|
|
1612
|
-
}),
|
|
1614
|
+
}), E++;
|
|
1613
1615
|
}
|
|
1614
1616
|
}
|
|
1615
|
-
return
|
|
1617
|
+
return n;
|
|
1616
1618
|
}
|
|
1617
1619
|
/**
|
|
1618
1620
|
* Calculate optimal number of clusters based on image count and container
|
|
1619
1621
|
*/
|
|
1620
|
-
calculateClusterCount(t, i, e,
|
|
1622
|
+
calculateClusterCount(t, i, e, n, s) {
|
|
1621
1623
|
if (i !== "auto")
|
|
1622
1624
|
return Math.max(1, Math.min(i, t));
|
|
1623
|
-
const
|
|
1624
|
-
e /
|
|
1625
|
+
const a = Math.max(1, Math.ceil(t / 8)), c = Math.floor(
|
|
1626
|
+
e / s * (n / s) * 0.6
|
|
1625
1627
|
);
|
|
1626
|
-
return Math.max(1, Math.min(
|
|
1628
|
+
return Math.max(1, Math.min(a, c, 10));
|
|
1627
1629
|
}
|
|
1628
1630
|
/**
|
|
1629
1631
|
* Generate cluster center positions with spacing constraints
|
|
1630
1632
|
*/
|
|
1631
|
-
generateClusterCenters(t, i, e,
|
|
1632
|
-
const r = [], c =
|
|
1633
|
+
generateClusterCenters(t, i, e, n, s) {
|
|
1634
|
+
const r = [], c = n + s.clusterSpread, l = i - n - s.clusterSpread, u = n + s.clusterSpread, h = e - n - s.clusterSpread;
|
|
1633
1635
|
for (let d = 0; d < t; d++) {
|
|
1634
|
-
let
|
|
1636
|
+
let g = null, b = -1;
|
|
1635
1637
|
for (let p = 0; p < 100; p++) {
|
|
1636
|
-
const
|
|
1638
|
+
const f = {
|
|
1637
1639
|
x: this.random(c, l),
|
|
1638
1640
|
y: this.random(u, h),
|
|
1639
|
-
spread: this.calculateClusterSpread(
|
|
1641
|
+
spread: this.calculateClusterSpread(s)
|
|
1640
1642
|
};
|
|
1641
1643
|
let m = 1 / 0;
|
|
1642
|
-
for (const
|
|
1643
|
-
const
|
|
1644
|
+
for (const y of r) {
|
|
1645
|
+
const E = f.x - y.x, v = f.y - y.y, S = Math.sqrt(E * E + v * v);
|
|
1644
1646
|
m = Math.min(m, S);
|
|
1645
1647
|
}
|
|
1646
|
-
if ((r.length === 0 || m >
|
|
1648
|
+
if ((r.length === 0 || m > b) && (g = f, b = m), m >= s.clusterSpacing)
|
|
1647
1649
|
break;
|
|
1648
1650
|
}
|
|
1649
|
-
|
|
1651
|
+
g && r.push(g);
|
|
1650
1652
|
}
|
|
1651
1653
|
return r;
|
|
1652
1654
|
}
|
|
@@ -1686,32 +1688,32 @@ class Le {
|
|
|
1686
1688
|
* @returns Array of layout objects with position, rotation, scale
|
|
1687
1689
|
*/
|
|
1688
1690
|
generate(t, i, e = {}) {
|
|
1689
|
-
const
|
|
1690
|
-
...
|
|
1691
|
+
const n = [], { width: s, height: r } = i, a = e.fixedHeight ?? 200, c = this.config.spacing.padding ?? 50, l = this.imageConfig.rotation?.mode ?? "none", u = this.imageConfig.rotation?.range?.min ?? -15, h = this.imageConfig.rotation?.range?.max ?? 15, d = this.imageConfig.sizing?.variance?.min ?? 1, g = this.imageConfig.sizing?.variance?.max ?? 1, b = d !== 1 || g !== 1, p = e.fixedHeight ?? a, f = {
|
|
1692
|
+
...Wt,
|
|
1691
1693
|
...this.config.wave
|
|
1692
|
-
}, { rows: m, amplitude:
|
|
1693
|
-
let
|
|
1694
|
-
for (let
|
|
1695
|
-
const k = m === 1 ? (
|
|
1696
|
-
let
|
|
1697
|
-
S === "offset" ?
|
|
1698
|
-
for (let
|
|
1699
|
-
const $ =
|
|
1694
|
+
}, { rows: m, amplitude: y, frequency: E, phaseShift: v, synchronization: S } = f, w = Math.ceil(t / m), L = p * 1.5 / 2, _ = c + L, O = s - c - L, H = O - _, N = w > 1 ? H / (w - 1) : 0, A = c + y + p / 2, D = r - c - y - p / 2, W = D - A, U = m > 1 ? W / (m - 1) : 0;
|
|
1695
|
+
let F = 0;
|
|
1696
|
+
for (let C = 0; C < m && F < t; C++) {
|
|
1697
|
+
const k = m === 1 ? (A + D) / 2 : A + C * U;
|
|
1698
|
+
let q = 0;
|
|
1699
|
+
S === "offset" ? q = C * v : S === "alternating" && (q = C * Math.PI);
|
|
1700
|
+
for (let T = 0; T < w && F < t; T++) {
|
|
1701
|
+
const $ = w === 1 ? (_ + O) / 2 : _ + T * N, M = this.calculateWaveY($, s, y, E, q), X = $, P = k + M, B = b ? this.random(d, g) : 1, Y = p * B;
|
|
1700
1702
|
let V = 0;
|
|
1701
|
-
l === "tangent" ? V = this.calculateRotation($,
|
|
1702
|
-
const K = Y * 1.5 / 2,
|
|
1703
|
-
|
|
1704
|
-
id:
|
|
1705
|
-
x: Math.max(
|
|
1706
|
-
y: Math.max(
|
|
1703
|
+
l === "tangent" ? V = this.calculateRotation($, s, y, E, q) : l === "random" && (V = this.random(u, h));
|
|
1704
|
+
const K = Y * 1.5 / 2, lt = Y / 2, nt = c + K, ot = s - c - K, ht = c + lt, dt = r - c - lt;
|
|
1705
|
+
n.push({
|
|
1706
|
+
id: F,
|
|
1707
|
+
x: Math.max(nt, Math.min(X, ot)),
|
|
1708
|
+
y: Math.max(ht, Math.min(P, dt)),
|
|
1707
1709
|
rotation: V,
|
|
1708
|
-
scale:
|
|
1710
|
+
scale: B,
|
|
1709
1711
|
baseSize: Y,
|
|
1710
|
-
zIndex:
|
|
1711
|
-
}),
|
|
1712
|
+
zIndex: F + 1
|
|
1713
|
+
}), F++;
|
|
1712
1714
|
}
|
|
1713
1715
|
}
|
|
1714
|
-
return
|
|
1716
|
+
return n;
|
|
1715
1717
|
}
|
|
1716
1718
|
/**
|
|
1717
1719
|
* Calculate Y position displacement on wave curve
|
|
@@ -1722,9 +1724,9 @@ class Le {
|
|
|
1722
1724
|
* @param phase - Phase offset
|
|
1723
1725
|
* @returns Y displacement from baseline
|
|
1724
1726
|
*/
|
|
1725
|
-
calculateWaveY(t, i, e,
|
|
1727
|
+
calculateWaveY(t, i, e, n, s) {
|
|
1726
1728
|
const r = t / i;
|
|
1727
|
-
return e * Math.sin(
|
|
1729
|
+
return e * Math.sin(n * r * 2 * Math.PI + s);
|
|
1728
1730
|
}
|
|
1729
1731
|
/**
|
|
1730
1732
|
* Calculate rotation based on wave tangent
|
|
@@ -1735,9 +1737,9 @@ class Le {
|
|
|
1735
1737
|
* @param phase - Phase offset
|
|
1736
1738
|
* @returns Rotation angle in degrees
|
|
1737
1739
|
*/
|
|
1738
|
-
calculateRotation(t, i, e,
|
|
1739
|
-
const r = t / i,
|
|
1740
|
-
return Math.atan(
|
|
1740
|
+
calculateRotation(t, i, e, n, s) {
|
|
1741
|
+
const r = t / i, a = e * n * 2 * Math.PI * Math.cos(n * r * 2 * Math.PI + s) / i;
|
|
1742
|
+
return Math.atan(a) * (180 / Math.PI);
|
|
1741
1743
|
}
|
|
1742
1744
|
/**
|
|
1743
1745
|
* Estimate image width based on height
|
|
@@ -1751,7 +1753,7 @@ class Le {
|
|
|
1751
1753
|
return Math.random() * (i - t) + t;
|
|
1752
1754
|
}
|
|
1753
1755
|
}
|
|
1754
|
-
const
|
|
1756
|
+
const wt = 100, Q = 100 / Math.sqrt(3), xt = [
|
|
1755
1757
|
[Q / 2, 0],
|
|
1756
1758
|
// upper-left
|
|
1757
1759
|
[3 * Q / 2, 0],
|
|
@@ -1764,18 +1766,18 @@ const xt = 100, Q = 100 / Math.sqrt(3), Et = [
|
|
|
1764
1766
|
// lower-left
|
|
1765
1767
|
[0, 50]
|
|
1766
1768
|
// left
|
|
1767
|
-
],
|
|
1768
|
-
function ze(
|
|
1769
|
+
], Fe = xt[1][0] / wt, Me = xt[2][1] / wt;
|
|
1770
|
+
function ze(o) {
|
|
1769
1771
|
return {
|
|
1770
|
-
colStep:
|
|
1771
|
-
rowOffset:
|
|
1772
|
+
colStep: Fe * o,
|
|
1773
|
+
rowOffset: Me * o
|
|
1772
1774
|
};
|
|
1773
1775
|
}
|
|
1774
|
-
function Oe(
|
|
1775
|
-
const { colStep: r } = ze(
|
|
1776
|
+
function Oe(o, t, i, e, n, s) {
|
|
1777
|
+
const { colStep: r } = ze(s);
|
|
1776
1778
|
return {
|
|
1777
|
-
px: e + r *
|
|
1778
|
-
py:
|
|
1779
|
+
px: e + r * o,
|
|
1780
|
+
py: n + s * (t + o / 2)
|
|
1779
1781
|
};
|
|
1780
1782
|
}
|
|
1781
1783
|
const De = [
|
|
@@ -1786,13 +1788,13 @@ const De = [
|
|
|
1786
1788
|
[0, -1, 1],
|
|
1787
1789
|
[1, -1, 0]
|
|
1788
1790
|
];
|
|
1789
|
-
function $e(
|
|
1790
|
-
if (
|
|
1791
|
+
function $e(o) {
|
|
1792
|
+
if (o === 0) return [[0, 0, 0]];
|
|
1791
1793
|
const t = [];
|
|
1792
|
-
let [i, e,
|
|
1793
|
-
for (const [
|
|
1794
|
-
for (let c = 0; c <
|
|
1795
|
-
t.push([i, e,
|
|
1794
|
+
let [i, e, n] = [0, -o, o];
|
|
1795
|
+
for (const [s, r, a] of De)
|
|
1796
|
+
for (let c = 0; c < o; c++)
|
|
1797
|
+
t.push([i, e, n]), i += s, e += r, n += a;
|
|
1796
1798
|
return t;
|
|
1797
1799
|
}
|
|
1798
1800
|
class Pe {
|
|
@@ -1802,30 +1804,30 @@ class Pe {
|
|
|
1802
1804
|
this.config = t;
|
|
1803
1805
|
}
|
|
1804
1806
|
generate(t, i, e = {}) {
|
|
1805
|
-
const
|
|
1806
|
-
...
|
|
1807
|
+
const n = [], { width: s, height: r } = i, a = s / 2, c = r / 2, l = e.fixedHeight ?? 200, h = {
|
|
1808
|
+
...Gt,
|
|
1807
1809
|
...this.config.honeycomb
|
|
1808
1810
|
}.spacing ?? 0, d = l + h;
|
|
1809
|
-
let
|
|
1810
|
-
for (;
|
|
1811
|
-
const p = $e(
|
|
1812
|
-
for (const [
|
|
1813
|
-
if (
|
|
1814
|
-
const { px:
|
|
1815
|
-
|
|
1816
|
-
id:
|
|
1817
|
-
x:
|
|
1811
|
+
let g = 0, b = 0;
|
|
1812
|
+
for (; g < t; ) {
|
|
1813
|
+
const p = $e(b);
|
|
1814
|
+
for (const [f, m, y] of p) {
|
|
1815
|
+
if (g >= t) break;
|
|
1816
|
+
const { px: E, py: v } = Oe(f, m, y, a, c, d);
|
|
1817
|
+
n.push({
|
|
1818
|
+
id: g,
|
|
1819
|
+
x: E,
|
|
1818
1820
|
y: v,
|
|
1819
1821
|
rotation: 0,
|
|
1820
1822
|
scale: 1,
|
|
1821
1823
|
baseSize: l,
|
|
1822
1824
|
// Inner rings render above outer rings
|
|
1823
|
-
zIndex: Math.max(1, 100 -
|
|
1824
|
-
}),
|
|
1825
|
+
zIndex: Math.max(1, 100 - b)
|
|
1826
|
+
}), g++;
|
|
1825
1827
|
}
|
|
1826
|
-
|
|
1828
|
+
b++;
|
|
1827
1829
|
}
|
|
1828
|
-
return
|
|
1830
|
+
return n;
|
|
1829
1831
|
}
|
|
1830
1832
|
}
|
|
1831
1833
|
class _e {
|
|
@@ -1839,19 +1841,19 @@ class _e {
|
|
|
1839
1841
|
initLayout() {
|
|
1840
1842
|
switch (this.config.algorithm) {
|
|
1841
1843
|
case "radial":
|
|
1842
|
-
return new
|
|
1844
|
+
return new we(this.config, this.imageConfig);
|
|
1843
1845
|
case "grid":
|
|
1844
1846
|
return new Se(this.config, this.imageConfig);
|
|
1845
1847
|
case "spiral":
|
|
1846
|
-
return new
|
|
1848
|
+
return new Ae(this.config, this.imageConfig);
|
|
1847
1849
|
case "cluster":
|
|
1848
|
-
return new
|
|
1850
|
+
return new Te(this.config, this.imageConfig);
|
|
1849
1851
|
case "wave":
|
|
1850
1852
|
return new Le(this.config, this.imageConfig);
|
|
1851
1853
|
case "honeycomb":
|
|
1852
1854
|
return new Pe(this.config, this.imageConfig);
|
|
1853
1855
|
default:
|
|
1854
|
-
return new
|
|
1856
|
+
return new Ee(this.config, this.imageConfig);
|
|
1855
1857
|
}
|
|
1856
1858
|
}
|
|
1857
1859
|
/**
|
|
@@ -1862,10 +1864,10 @@ class _e {
|
|
|
1862
1864
|
* @returns Array of layout objects with position, rotation, scale
|
|
1863
1865
|
*/
|
|
1864
1866
|
generateLayout(t, i, e = {}) {
|
|
1865
|
-
const
|
|
1866
|
-
return
|
|
1867
|
-
this.layouts.set(
|
|
1868
|
-
}),
|
|
1867
|
+
const n = this.placementLayout.generate(t, i, e);
|
|
1868
|
+
return n.forEach((s) => {
|
|
1869
|
+
this.layouts.set(s.id, s);
|
|
1870
|
+
}), n;
|
|
1869
1871
|
}
|
|
1870
1872
|
/**
|
|
1871
1873
|
* Get the original layout state for an image
|
|
@@ -1918,8 +1920,8 @@ class _e {
|
|
|
1918
1920
|
return;
|
|
1919
1921
|
if (typeof e == "number")
|
|
1920
1922
|
return e;
|
|
1921
|
-
const
|
|
1922
|
-
return
|
|
1923
|
+
const n = e, s = this.resolveBreakpoint(t);
|
|
1924
|
+
return s === "mobile" ? n.mobile ?? n.tablet ?? n.screen : s === "tablet" ? n.tablet ?? n.screen ?? n.mobile : n.screen ?? n.tablet ?? n.mobile;
|
|
1923
1925
|
}
|
|
1924
1926
|
/**
|
|
1925
1927
|
* Calculate adaptive image size based on container dimensions and image count
|
|
@@ -1929,19 +1931,19 @@ class _e {
|
|
|
1929
1931
|
* @param viewportWidth - Current viewport width for baseHeight resolution
|
|
1930
1932
|
* @returns Calculated sizing result with height
|
|
1931
1933
|
*/
|
|
1932
|
-
calculateAdaptiveSize(t, i, e,
|
|
1933
|
-
const
|
|
1934
|
+
calculateAdaptiveSize(t, i, e, n) {
|
|
1935
|
+
const s = this.imageConfig.sizing, r = this.resolveBaseHeight(n);
|
|
1934
1936
|
if (r !== void 0)
|
|
1935
1937
|
return { height: r };
|
|
1936
|
-
const
|
|
1938
|
+
const a = s?.minSize ?? 50, c = s?.maxSize ?? 400, l = this.config.targetCoverage ?? 0.6, u = this.config.densityFactor ?? 1, { width: h, height: d } = t, p = h * d * l / i;
|
|
1937
1939
|
let m = Math.sqrt(p / 1.4);
|
|
1938
1940
|
m *= u, m = Math.min(m, e);
|
|
1939
|
-
let
|
|
1940
|
-
if (
|
|
1941
|
-
const
|
|
1942
|
-
|
|
1941
|
+
let y = this.clamp(m, a, c);
|
|
1942
|
+
if (y === a && m < a) {
|
|
1943
|
+
const E = Math.max(a * 0.05, 20);
|
|
1944
|
+
y = Math.max(E, m);
|
|
1943
1945
|
}
|
|
1944
|
-
return this.config.algorithm === "honeycomb" && (
|
|
1946
|
+
return this.config.algorithm === "honeycomb" && (y = Math.min(y, this.honeycombMaxImageHeight(i, t))), { height: y };
|
|
1945
1947
|
}
|
|
1946
1948
|
/**
|
|
1947
1949
|
* Returns the largest image height at which all honeycomb rings fit within the container.
|
|
@@ -1950,10 +1952,10 @@ class _e {
|
|
|
1950
1952
|
*/
|
|
1951
1953
|
honeycombMaxImageHeight(t, i) {
|
|
1952
1954
|
if (t <= 1) return 1 / 0;
|
|
1953
|
-
let e = 0,
|
|
1954
|
-
for (;
|
|
1955
|
-
e++,
|
|
1956
|
-
const
|
|
1955
|
+
let e = 0, n = 1;
|
|
1956
|
+
for (; n < t; )
|
|
1957
|
+
e++, n += 6 * e;
|
|
1958
|
+
const s = this.config.spacing?.padding ?? 50, r = this.config.honeycomb?.spacing ?? 0, a = i.width / 2, c = i.height / 2, l = Math.sqrt(3) / 2, u = 1 / Math.sqrt(3), h = (c - s - r * e) / (e + 0.5), d = (a - s - l * r * e) / (l * e + u);
|
|
1957
1959
|
return Math.max(10, Math.min(h, d));
|
|
1958
1960
|
}
|
|
1959
1961
|
/**
|
|
@@ -1963,7 +1965,7 @@ class _e {
|
|
|
1963
1965
|
return Math.max(i, Math.min(e, t));
|
|
1964
1966
|
}
|
|
1965
1967
|
}
|
|
1966
|
-
var
|
|
1968
|
+
var x = /* @__PURE__ */ ((o) => (o.IDLE = "idle", o.FOCUSING = "focusing", o.FOCUSED = "focused", o.UNFOCUSING = "unfocusing", o.CROSS_ANIMATING = "cross_animating", o))(x || {});
|
|
1967
1969
|
const Lt = {
|
|
1968
1970
|
// Geometric shapes - uses percentages for responsive sizing
|
|
1969
1971
|
circle: "circle(50%)",
|
|
@@ -1997,8 +1999,8 @@ const Lt = {
|
|
|
1997
1999
|
},
|
|
1998
2000
|
// Hexagon - regular hexagon (reference points imported from hexagonGeometry)
|
|
1999
2001
|
hexagon: {
|
|
2000
|
-
refHeight:
|
|
2001
|
-
points:
|
|
2002
|
+
refHeight: wt,
|
|
2003
|
+
points: xt
|
|
2002
2004
|
},
|
|
2003
2005
|
// Octagon - regular octagon
|
|
2004
2006
|
octagon: {
|
|
@@ -2011,105 +2013,105 @@ const Lt = {
|
|
|
2011
2013
|
points: [[50, 0], [100, 50], [50, 100], [0, 50]]
|
|
2012
2014
|
}
|
|
2013
2015
|
};
|
|
2014
|
-
function He(
|
|
2015
|
-
if (
|
|
2016
|
-
return
|
|
2016
|
+
function He(o) {
|
|
2017
|
+
if (o)
|
|
2018
|
+
return o in Lt ? Lt[o] : o;
|
|
2017
2019
|
}
|
|
2018
|
-
function Ne(
|
|
2019
|
-
const e = Ue[
|
|
2020
|
+
function Ne(o, t, i) {
|
|
2021
|
+
const e = Ue[o];
|
|
2020
2022
|
if (!e) return "";
|
|
2021
|
-
const
|
|
2022
|
-
if (
|
|
2023
|
-
return `circle(${Math.round(50 *
|
|
2024
|
-
const
|
|
2025
|
-
return `polygon(${e.points.map(([p,
|
|
2026
|
-
const m = Math.round((p *
|
|
2027
|
-
return `${m}px ${
|
|
2023
|
+
const n = t / e.refHeight;
|
|
2024
|
+
if (o === "circle")
|
|
2025
|
+
return `circle(${Math.round(50 * n * 100) / 100}px)`;
|
|
2026
|
+
const s = e.points.map(([p]) => p), r = e.points.map(([, p]) => p), a = (Math.min(...s) + Math.max(...s)) / 2 * n, c = (Math.min(...r) + Math.max(...r)) / 2 * n, l = (Math.max(...s) - Math.min(...s)) * n, u = (i ?? l) / 2, h = t / 2, d = u - a, g = h - c;
|
|
2027
|
+
return `polygon(${e.points.map(([p, f]) => {
|
|
2028
|
+
const m = Math.round((p * n + d) * 100) / 100, y = Math.round((f * n + g) * 100) / 100;
|
|
2029
|
+
return `${m}px ${y}px`;
|
|
2028
2030
|
}).join(", ")})`;
|
|
2029
2031
|
}
|
|
2030
|
-
function ke(
|
|
2031
|
-
return
|
|
2032
|
+
function ke(o) {
|
|
2033
|
+
return o in mt;
|
|
2032
2034
|
}
|
|
2033
|
-
function
|
|
2034
|
-
return
|
|
2035
|
+
function Be(o) {
|
|
2036
|
+
return o ? ke(o) ? mt[o] : o : mt.md;
|
|
2035
2037
|
}
|
|
2036
|
-
function
|
|
2037
|
-
if (!
|
|
2038
|
+
function je(o) {
|
|
2039
|
+
if (!o) return "";
|
|
2038
2040
|
const t = [];
|
|
2039
|
-
if (
|
|
2040
|
-
if (typeof
|
|
2041
|
-
t.push(`drop-shadow(${
|
|
2041
|
+
if (o.grayscale !== void 0 && t.push(`grayscale(${o.grayscale})`), o.blur !== void 0 && t.push(`blur(${o.blur}px)`), o.brightness !== void 0 && t.push(`brightness(${o.brightness})`), o.contrast !== void 0 && t.push(`contrast(${o.contrast})`), o.saturate !== void 0 && t.push(`saturate(${o.saturate})`), o.opacity !== void 0 && t.push(`opacity(${o.opacity})`), o.sepia !== void 0 && t.push(`sepia(${o.sepia})`), o.hueRotate !== void 0 && t.push(`hue-rotate(${o.hueRotate}deg)`), o.invert !== void 0 && t.push(`invert(${o.invert})`), o.dropShadow !== void 0)
|
|
2042
|
+
if (typeof o.dropShadow == "string")
|
|
2043
|
+
t.push(`drop-shadow(${o.dropShadow})`);
|
|
2042
2044
|
else {
|
|
2043
|
-
const i =
|
|
2045
|
+
const i = o.dropShadow;
|
|
2044
2046
|
t.push(`drop-shadow(${i.x}px ${i.y}px ${i.blur}px ${i.color})`);
|
|
2045
2047
|
}
|
|
2046
2048
|
return t.join(" ");
|
|
2047
2049
|
}
|
|
2048
|
-
function tt(
|
|
2049
|
-
if (!
|
|
2050
|
+
function tt(o) {
|
|
2051
|
+
if (!o || o.style === "none" || o.width === 0)
|
|
2050
2052
|
return "none";
|
|
2051
|
-
const t =
|
|
2053
|
+
const t = o.width ?? 0, i = o.style ?? "solid", e = o.color ?? "#000000";
|
|
2052
2054
|
return `${t}px ${i} ${e}`;
|
|
2053
2055
|
}
|
|
2054
|
-
function
|
|
2055
|
-
if (!
|
|
2056
|
+
function it(o, t, i) {
|
|
2057
|
+
if (!o) return {};
|
|
2056
2058
|
const e = {};
|
|
2057
|
-
if (
|
|
2058
|
-
const
|
|
2059
|
-
|
|
2060
|
-
} else
|
|
2061
|
-
if (
|
|
2062
|
-
const
|
|
2059
|
+
if (o.borderRadiusTopLeft !== void 0 || o.borderRadiusTopRight !== void 0 || o.borderRadiusBottomRight !== void 0 || o.borderRadiusBottomLeft !== void 0) {
|
|
2060
|
+
const a = o.border?.radius ?? 0;
|
|
2061
|
+
o.borderRadiusTopLeft !== void 0 ? e.borderTopLeftRadius = `${o.borderRadiusTopLeft}px` : a && (e.borderTopLeftRadius = `${a}px`), o.borderRadiusTopRight !== void 0 ? e.borderTopRightRadius = `${o.borderRadiusTopRight}px` : a && (e.borderTopRightRadius = `${a}px`), o.borderRadiusBottomRight !== void 0 ? e.borderBottomRightRadius = `${o.borderRadiusBottomRight}px` : a && (e.borderBottomRightRadius = `${a}px`), o.borderRadiusBottomLeft !== void 0 ? e.borderBottomLeftRadius = `${o.borderRadiusBottomLeft}px` : a && (e.borderBottomLeftRadius = `${a}px`);
|
|
2062
|
+
} else o.border?.radius !== void 0 && (e.borderRadius = `${o.border.radius}px`);
|
|
2063
|
+
if (o.borderTop || o.borderRight || o.borderBottom || o.borderLeft) {
|
|
2064
|
+
const a = o.border || {}, c = { ...a, ...o.borderTop }, l = { ...a, ...o.borderRight }, u = { ...a, ...o.borderBottom }, h = { ...a, ...o.borderLeft };
|
|
2063
2065
|
e.borderTop = tt(c), e.borderRight = tt(l), e.borderBottom = tt(u), e.borderLeft = tt(h);
|
|
2064
|
-
} else
|
|
2065
|
-
|
|
2066
|
-
const r =
|
|
2067
|
-
if (e.filter = r || "none",
|
|
2068
|
-
const
|
|
2069
|
-
e.outline = `${
|
|
2070
|
-
}
|
|
2071
|
-
if (
|
|
2072
|
-
let
|
|
2073
|
-
const c = typeof
|
|
2066
|
+
} else o.border && (e.border = tt(o.border));
|
|
2067
|
+
o.shadow !== void 0 && (e.boxShadow = Be(o.shadow));
|
|
2068
|
+
const r = je(o.filter);
|
|
2069
|
+
if (e.filter = r || "none", o.opacity !== void 0 && (e.opacity = String(o.opacity)), o.cursor !== void 0 && (e.cursor = o.cursor), o.outline && o.outline.style !== "none" && (o.outline.width ?? 0) > 0) {
|
|
2070
|
+
const a = o.outline.width ?? 0, c = o.outline.style ?? "solid", l = o.outline.color ?? "#000000";
|
|
2071
|
+
e.outline = `${a}px ${c} ${l}`, o.outline.offset !== void 0 && (e.outlineOffset = `${o.outline.offset}px`);
|
|
2072
|
+
}
|
|
2073
|
+
if (o.objectFit !== void 0 && (e.objectFit = o.objectFit), o.aspectRatio !== void 0 && (e.aspectRatio = o.aspectRatio), o.clipPath !== void 0) {
|
|
2074
|
+
let a;
|
|
2075
|
+
const c = typeof o.clipPath == "object" && o.clipPath !== null && "shape" in o.clipPath, l = c ? o.clipPath : void 0;
|
|
2074
2076
|
if (l?.mode === "height-relative" && t)
|
|
2075
|
-
|
|
2077
|
+
a = Ne(l.shape, t, i);
|
|
2076
2078
|
else {
|
|
2077
|
-
const u = c && l ? l.shape :
|
|
2078
|
-
|
|
2079
|
+
const u = c && l ? l.shape : o.clipPath;
|
|
2080
|
+
a = He(u);
|
|
2079
2081
|
}
|
|
2080
|
-
|
|
2082
|
+
a && (a === "none" ? e.clipPath = "unset" : (e.clipPath = a, e.overflow = "hidden"));
|
|
2081
2083
|
}
|
|
2082
2084
|
return e;
|
|
2083
2085
|
}
|
|
2084
|
-
function
|
|
2085
|
-
t.borderRadius !== void 0 && (
|
|
2086
|
+
function We(o, t) {
|
|
2087
|
+
t.borderRadius !== void 0 && (o.style.borderRadius = t.borderRadius), t.borderTopLeftRadius !== void 0 && (o.style.borderTopLeftRadius = t.borderTopLeftRadius), t.borderTopRightRadius !== void 0 && (o.style.borderTopRightRadius = t.borderTopRightRadius), t.borderBottomRightRadius !== void 0 && (o.style.borderBottomRightRadius = t.borderBottomRightRadius), t.borderBottomLeftRadius !== void 0 && (o.style.borderBottomLeftRadius = t.borderBottomLeftRadius), t.border !== void 0 && (o.style.border = t.border), t.borderTop !== void 0 && (o.style.borderTop = t.borderTop), t.borderRight !== void 0 && (o.style.borderRight = t.borderRight), t.borderBottom !== void 0 && (o.style.borderBottom = t.borderBottom), t.borderLeft !== void 0 && (o.style.borderLeft = t.borderLeft), t.boxShadow !== void 0 && (o.style.boxShadow = t.boxShadow), t.filter !== void 0 && (o.style.filter = t.filter), t.opacity !== void 0 && (o.style.opacity = t.opacity), t.cursor !== void 0 && (o.style.cursor = t.cursor), t.outline !== void 0 && (o.style.outline = t.outline), t.outlineOffset !== void 0 && (o.style.outlineOffset = t.outlineOffset), t.objectFit !== void 0 && (o.style.objectFit = t.objectFit), t.aspectRatio !== void 0 && (o.style.aspectRatio = t.aspectRatio), t.clipPath !== void 0 && (o.style.clipPath = t.clipPath), t.overflow !== void 0 && (o.style.overflow = t.overflow);
|
|
2086
2088
|
}
|
|
2087
|
-
function
|
|
2088
|
-
const
|
|
2089
|
-
|
|
2089
|
+
function st(o, t, i, e) {
|
|
2090
|
+
const n = it(t, i, e);
|
|
2091
|
+
We(o, n);
|
|
2090
2092
|
}
|
|
2091
|
-
function Pt(
|
|
2092
|
-
return
|
|
2093
|
+
function Pt(o) {
|
|
2094
|
+
return o ? Array.isArray(o) ? o.join(" ") : o : "";
|
|
2093
2095
|
}
|
|
2094
|
-
function
|
|
2096
|
+
function et(o, t) {
|
|
2095
2097
|
const i = Pt(t);
|
|
2096
2098
|
i && i.split(" ").forEach((e) => {
|
|
2097
|
-
e.trim() &&
|
|
2099
|
+
e.trim() && o.classList.add(e.trim());
|
|
2098
2100
|
});
|
|
2099
2101
|
}
|
|
2100
|
-
function pt(
|
|
2102
|
+
function pt(o, t) {
|
|
2101
2103
|
const i = Pt(t);
|
|
2102
2104
|
i && i.split(" ").forEach((e) => {
|
|
2103
|
-
e.trim() &&
|
|
2105
|
+
e.trim() && o.classList.remove(e.trim());
|
|
2104
2106
|
});
|
|
2105
2107
|
}
|
|
2106
|
-
const
|
|
2108
|
+
const Ft = {
|
|
2107
2109
|
UNFOCUSING: 999,
|
|
2108
2110
|
FOCUSING: 1e3
|
|
2109
2111
|
};
|
|
2110
|
-
class
|
|
2112
|
+
class Ge {
|
|
2111
2113
|
constructor(t, i, e) {
|
|
2112
|
-
this.state =
|
|
2114
|
+
this.state = x.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null, this.focusGeneration = 0, this.onUnfocusComplete = null, this.config = t, this.animationEngine = i, this.styling = e, this.focusedClassName = e?.focused?.className;
|
|
2113
2115
|
}
|
|
2114
2116
|
/**
|
|
2115
2117
|
* Set callback to be fired when an unfocus animation fully completes.
|
|
@@ -2127,7 +2129,7 @@ class qe {
|
|
|
2127
2129
|
* Check if any animation is in progress
|
|
2128
2130
|
*/
|
|
2129
2131
|
isAnimating() {
|
|
2130
|
-
return this.state !==
|
|
2132
|
+
return this.state !== x.IDLE && this.state !== x.FOCUSED;
|
|
2131
2133
|
}
|
|
2132
2134
|
/**
|
|
2133
2135
|
* Normalize scalePercent value
|
|
@@ -2140,19 +2142,19 @@ class qe {
|
|
|
2140
2142
|
* Returns actual pixel dimensions instead of scale factor for sharper rendering
|
|
2141
2143
|
*/
|
|
2142
2144
|
calculateFocusDimensions(t, i, e) {
|
|
2143
|
-
const
|
|
2144
|
-
let
|
|
2145
|
-
const l = e.width *
|
|
2146
|
-
return c > l && (c = l,
|
|
2145
|
+
const n = this.normalizeScalePercent(this.config.scalePercent), s = e.height * n, r = t / i;
|
|
2146
|
+
let a = s, c = a * r;
|
|
2147
|
+
const l = e.width * n;
|
|
2148
|
+
return c > l && (c = l, a = c / r), { width: c, height: a };
|
|
2147
2149
|
}
|
|
2148
2150
|
/**
|
|
2149
2151
|
* Calculate the transform needed to center an image (position only, no scale)
|
|
2150
2152
|
* Scale is handled by animating actual dimensions for sharper rendering
|
|
2151
2153
|
*/
|
|
2152
2154
|
calculateFocusTransform(t, i) {
|
|
2153
|
-
const e = t.width / 2,
|
|
2155
|
+
const e = t.width / 2, n = t.height / 2, s = e - i.x, r = n - i.y;
|
|
2154
2156
|
return {
|
|
2155
|
-
x:
|
|
2157
|
+
x: s,
|
|
2156
2158
|
y: r,
|
|
2157
2159
|
rotation: 0,
|
|
2158
2160
|
scale: 1
|
|
@@ -2165,8 +2167,8 @@ class qe {
|
|
|
2165
2167
|
buildDimensionZoomTransform(t) {
|
|
2166
2168
|
const i = ["translate(-50%, -50%)"];
|
|
2167
2169
|
if (t.x !== void 0 || t.y !== void 0) {
|
|
2168
|
-
const e = t.x ?? 0,
|
|
2169
|
-
i.push(`translate(${e}px, ${
|
|
2170
|
+
const e = t.x ?? 0, n = t.y ?? 0;
|
|
2171
|
+
i.push(`translate(${e}px, ${n}px)`);
|
|
2170
2172
|
}
|
|
2171
2173
|
return t.rotation !== void 0 && i.push(`rotate(${t.rotation}deg)`), i.join(" ");
|
|
2172
2174
|
}
|
|
@@ -2174,19 +2176,19 @@ class qe {
|
|
|
2174
2176
|
* Create a Web Animation that animates both transform (position) and dimensions
|
|
2175
2177
|
* This provides sharper zoom by re-rendering at target size instead of scaling pixels
|
|
2176
2178
|
*/
|
|
2177
|
-
animateWithDimensions(t, i, e,
|
|
2179
|
+
animateWithDimensions(t, i, e, n, s, r, a, c) {
|
|
2178
2180
|
const l = this.buildDimensionZoomTransform(i), u = this.buildDimensionZoomTransform(e);
|
|
2179
2181
|
return t.style.transition = "none", t.animate(
|
|
2180
2182
|
[
|
|
2181
2183
|
{
|
|
2182
2184
|
transform: l,
|
|
2183
|
-
width: `${
|
|
2184
|
-
height: `${
|
|
2185
|
+
width: `${n}px`,
|
|
2186
|
+
height: `${s}px`
|
|
2185
2187
|
},
|
|
2186
2188
|
{
|
|
2187
2189
|
transform: u,
|
|
2188
2190
|
width: `${r}px`,
|
|
2189
|
-
height: `${
|
|
2191
|
+
height: `${a}px`
|
|
2190
2192
|
}
|
|
2191
2193
|
],
|
|
2192
2194
|
{
|
|
@@ -2201,8 +2203,8 @@ class qe {
|
|
|
2201
2203
|
* Applies all focused styling properties, classes, and z-index
|
|
2202
2204
|
*/
|
|
2203
2205
|
applyFocusedStyling(t, i) {
|
|
2204
|
-
if (t.style.zIndex = String(i), t.classList.add("fbn-ic-focused"),
|
|
2205
|
-
const e =
|
|
2206
|
+
if (t.style.zIndex = String(i), t.classList.add("fbn-ic-focused"), et(t, this.focusedClassName), this.styling?.focused) {
|
|
2207
|
+
const e = it(this.styling.focused, t.offsetHeight, t.offsetWidth);
|
|
2206
2208
|
e.borderRadius !== void 0 && (t.style.borderRadius = e.borderRadius), e.borderTopLeftRadius !== void 0 && (t.style.borderTopLeftRadius = e.borderTopLeftRadius), e.borderTopRightRadius !== void 0 && (t.style.borderTopRightRadius = e.borderTopRightRadius), e.borderBottomRightRadius !== void 0 && (t.style.borderBottomRightRadius = e.borderBottomRightRadius), e.borderBottomLeftRadius !== void 0 && (t.style.borderBottomLeftRadius = e.borderBottomLeftRadius), e.border !== void 0 && (t.style.border = e.border), e.borderTop !== void 0 && (t.style.borderTop = e.borderTop), e.borderRight !== void 0 && (t.style.borderRight = e.borderRight), e.borderBottom !== void 0 && (t.style.borderBottom = e.borderBottom), e.borderLeft !== void 0 && (t.style.borderLeft = e.borderLeft), e.boxShadow !== void 0 && (t.style.boxShadow = e.boxShadow), e.filter !== void 0 && (t.style.filter = e.filter), e.opacity !== void 0 && (t.style.opacity = e.opacity), e.cursor !== void 0 && (t.style.cursor = e.cursor), e.outline !== void 0 && (t.style.outline = e.outline), e.outlineOffset !== void 0 && (t.style.outlineOffset = e.outlineOffset), e.objectFit !== void 0 && (t.style.objectFit = e.objectFit), e.aspectRatio !== void 0 && (t.style.aspectRatio = e.aspectRatio);
|
|
2207
2209
|
}
|
|
2208
2210
|
}
|
|
@@ -2212,7 +2214,7 @@ class qe {
|
|
|
2212
2214
|
*/
|
|
2213
2215
|
removeFocusedStyling(t, i) {
|
|
2214
2216
|
if (t.style.zIndex = i, t.classList.remove("fbn-ic-focused"), pt(t, this.focusedClassName), this.styling?.default) {
|
|
2215
|
-
const e =
|
|
2217
|
+
const e = it(this.styling.default, t.offsetHeight, t.offsetWidth);
|
|
2216
2218
|
e.borderRadius !== void 0 && (t.style.borderRadius = e.borderRadius), e.borderTopLeftRadius !== void 0 && (t.style.borderTopLeftRadius = e.borderTopLeftRadius), e.borderTopRightRadius !== void 0 && (t.style.borderTopRightRadius = e.borderTopRightRadius), e.borderBottomRightRadius !== void 0 && (t.style.borderBottomRightRadius = e.borderBottomRightRadius), e.borderBottomLeftRadius !== void 0 && (t.style.borderBottomLeftRadius = e.borderBottomLeftRadius), e.border !== void 0 && (t.style.border = e.border), e.borderTop !== void 0 && (t.style.borderTop = e.borderTop), e.borderRight !== void 0 && (t.style.borderRight = e.borderRight), e.borderBottom !== void 0 && (t.style.borderBottom = e.borderBottom), e.borderLeft !== void 0 && (t.style.borderLeft = e.borderLeft), e.boxShadow !== void 0 && (t.style.boxShadow = e.boxShadow), e.filter !== void 0 && (t.style.filter = e.filter), e.opacity !== void 0 && (t.style.opacity = e.opacity), e.cursor !== void 0 && (t.style.cursor = e.cursor), e.outline !== void 0 && (t.style.outline = e.outline), e.outlineOffset !== void 0 && (t.style.outlineOffset = e.outlineOffset), e.objectFit !== void 0 && (t.style.objectFit = e.objectFit), e.aspectRatio !== void 0 && (t.style.aspectRatio = e.aspectRatio);
|
|
2217
2219
|
}
|
|
2218
2220
|
}
|
|
@@ -2221,13 +2223,13 @@ class qe {
|
|
|
2221
2223
|
* This ensures clip-path changes smoothly as width/height animate
|
|
2222
2224
|
*/
|
|
2223
2225
|
startClipPathAnimation(t, i, e) {
|
|
2224
|
-
let
|
|
2225
|
-
e && this.styling?.focused && this.styling.focused.clipPath === void 0 && (
|
|
2226
|
-
const
|
|
2227
|
-
const r = t.offsetHeight,
|
|
2228
|
-
c.clipPath !== void 0 ? t.style.clipPath = c.clipPath : t.style.clipPath = "unset", c.overflow !== void 0 && (t.style.overflow = c.overflow), i.animation.playState === "running" && requestAnimationFrame(
|
|
2226
|
+
let n = e ? this.styling?.focused ?? this.styling?.default : this.styling?.default;
|
|
2227
|
+
e && this.styling?.focused && this.styling.focused.clipPath === void 0 && (n = { ...n, clipPath: void 0 });
|
|
2228
|
+
const s = () => {
|
|
2229
|
+
const r = t.offsetHeight, a = t.offsetWidth, c = it(n, r, a);
|
|
2230
|
+
c.clipPath !== void 0 ? t.style.clipPath = c.clipPath : t.style.clipPath = "unset", c.overflow !== void 0 && (t.style.overflow = c.overflow), i.animation.playState === "running" && requestAnimationFrame(s);
|
|
2229
2231
|
};
|
|
2230
|
-
requestAnimationFrame(
|
|
2232
|
+
requestAnimationFrame(s);
|
|
2231
2233
|
}
|
|
2232
2234
|
/**
|
|
2233
2235
|
* Start focus animation for an image using dimension-based zoom
|
|
@@ -2235,27 +2237,27 @@ class qe {
|
|
|
2235
2237
|
* @param fromTransform - Optional starting transform (for mid-animation reversals)
|
|
2236
2238
|
* @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
|
|
2237
2239
|
*/
|
|
2238
|
-
startFocusAnimation(t, i, e,
|
|
2239
|
-
const r = t.style.zIndex || "",
|
|
2240
|
+
startFocusAnimation(t, i, e, n, s) {
|
|
2241
|
+
const r = t.style.zIndex || "", a = t.offsetWidth, c = t.offsetHeight, l = this.calculateFocusDimensions(a, c, i), u = this.calculateFocusTransform(i, e);
|
|
2240
2242
|
this.animationEngine.cancelAllAnimations(t);
|
|
2241
2243
|
const h = this.config.animationDuration ?? 600;
|
|
2242
|
-
this.applyFocusedStyling(t,
|
|
2243
|
-
const d =
|
|
2244
|
+
this.applyFocusedStyling(t, Ft.FOCUSING);
|
|
2245
|
+
const d = n ?? {
|
|
2244
2246
|
x: 0,
|
|
2245
2247
|
y: 0,
|
|
2246
2248
|
rotation: e.rotation,
|
|
2247
2249
|
scale: 1
|
|
2248
2250
|
// No scale - using dimensions
|
|
2249
|
-
},
|
|
2251
|
+
}, g = s?.width ?? a, b = s?.height ?? c, p = this.animateWithDimensions(
|
|
2250
2252
|
t,
|
|
2251
2253
|
d,
|
|
2252
2254
|
u,
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
+
g,
|
|
2256
|
+
b,
|
|
2255
2257
|
l.width,
|
|
2256
2258
|
l.height,
|
|
2257
2259
|
h
|
|
2258
|
-
),
|
|
2260
|
+
), f = {
|
|
2259
2261
|
id: `focus-${Date.now()}`,
|
|
2260
2262
|
element: t,
|
|
2261
2263
|
animation: p,
|
|
@@ -2269,16 +2271,16 @@ class qe {
|
|
|
2269
2271
|
originalState: e,
|
|
2270
2272
|
focusTransform: u,
|
|
2271
2273
|
originalZIndex: r,
|
|
2272
|
-
originalWidth:
|
|
2274
|
+
originalWidth: a,
|
|
2273
2275
|
originalHeight: c,
|
|
2274
2276
|
focusWidth: l.width,
|
|
2275
2277
|
focusHeight: l.height
|
|
2276
|
-
}, this.startClipPathAnimation(t,
|
|
2278
|
+
}, this.startClipPathAnimation(t, f, !0), {
|
|
2277
2279
|
element: t,
|
|
2278
2280
|
originalState: e,
|
|
2279
|
-
animationHandle:
|
|
2281
|
+
animationHandle: f,
|
|
2280
2282
|
direction: "in",
|
|
2281
|
-
originalWidth:
|
|
2283
|
+
originalWidth: a,
|
|
2282
2284
|
originalHeight: c
|
|
2283
2285
|
};
|
|
2284
2286
|
}
|
|
@@ -2287,11 +2289,11 @@ class qe {
|
|
|
2287
2289
|
* Animates back to original dimensions for consistent behavior
|
|
2288
2290
|
* @param fromDimensions - Optional starting dimensions (for mid-animation reversals)
|
|
2289
2291
|
*/
|
|
2290
|
-
startUnfocusAnimation(t, i, e,
|
|
2291
|
-
t.style.zIndex = String(
|
|
2292
|
-
const
|
|
2292
|
+
startUnfocusAnimation(t, i, e, n) {
|
|
2293
|
+
t.style.zIndex = String(Ft.UNFOCUSING), this.animationEngine.cancelAllAnimations(t);
|
|
2294
|
+
const s = this.config.animationDuration ?? 600;
|
|
2293
2295
|
t.classList.remove("fbn-ic-focused"), pt(t, this.focusedClassName);
|
|
2294
|
-
const r = e ?? this.focusData?.focusTransform ?? { x: 0, y: 0, rotation: 0, scale: 1 },
|
|
2296
|
+
const r = e ?? this.focusData?.focusTransform ?? { x: 0, y: 0, rotation: 0, scale: 1 }, a = n?.width ?? this.focusData?.focusWidth ?? t.offsetWidth, c = n?.height ?? this.focusData?.focusHeight ?? t.offsetHeight, l = {
|
|
2295
2297
|
x: 0,
|
|
2296
2298
|
y: 0,
|
|
2297
2299
|
rotation: i.rotation,
|
|
@@ -2301,24 +2303,24 @@ class qe {
|
|
|
2301
2303
|
t,
|
|
2302
2304
|
r,
|
|
2303
2305
|
l,
|
|
2304
|
-
|
|
2306
|
+
a,
|
|
2305
2307
|
c,
|
|
2306
2308
|
u,
|
|
2307
2309
|
h,
|
|
2308
|
-
|
|
2309
|
-
),
|
|
2310
|
+
s
|
|
2311
|
+
), g = {
|
|
2310
2312
|
id: `unfocus-${Date.now()}`,
|
|
2311
2313
|
element: t,
|
|
2312
2314
|
animation: d,
|
|
2313
2315
|
fromState: r,
|
|
2314
2316
|
toState: l,
|
|
2315
2317
|
startTime: performance.now(),
|
|
2316
|
-
duration:
|
|
2318
|
+
duration: s
|
|
2317
2319
|
};
|
|
2318
|
-
return this.startClipPathAnimation(t,
|
|
2320
|
+
return this.startClipPathAnimation(t, g, !1), {
|
|
2319
2321
|
element: t,
|
|
2320
2322
|
originalState: i,
|
|
2321
|
-
animationHandle:
|
|
2323
|
+
animationHandle: g,
|
|
2322
2324
|
direction: "out",
|
|
2323
2325
|
originalWidth: u,
|
|
2324
2326
|
originalHeight: h
|
|
@@ -2339,10 +2341,10 @@ class qe {
|
|
|
2339
2341
|
* Caller is responsible for calling animationEngine.cancelAllAnimations() afterwards.
|
|
2340
2342
|
*/
|
|
2341
2343
|
captureMidAnimationState(t) {
|
|
2342
|
-
const i = getComputedStyle(t), e = new DOMMatrix(i.transform),
|
|
2343
|
-
return t.style.width = `${
|
|
2344
|
-
transform: { x: r, y:
|
|
2345
|
-
dimensions: { width:
|
|
2344
|
+
const i = getComputedStyle(t), e = new DOMMatrix(i.transform), n = t.offsetWidth, s = t.offsetHeight, r = e.e + n * 0.5, a = e.f + s * 0.5, c = Math.atan2(e.b, e.a) * (180 / Math.PI);
|
|
2345
|
+
return t.style.width = `${n}px`, t.style.height = `${s}px`, t.style.transform = `translate(-50%, -50%) translate(${r}px, ${a}px) rotate(${c}deg)`, t.style.transition = "none", {
|
|
2346
|
+
transform: { x: r, y: a, rotation: c, scale: 1 },
|
|
2347
|
+
dimensions: { width: n, height: s }
|
|
2346
2348
|
};
|
|
2347
2349
|
}
|
|
2348
2350
|
/**
|
|
@@ -2357,94 +2359,94 @@ class qe {
|
|
|
2357
2359
|
/**
|
|
2358
2360
|
* Reset an element instantly to its original position and dimensions (no animation)
|
|
2359
2361
|
*/
|
|
2360
|
-
resetElementInstantly(t, i, e,
|
|
2362
|
+
resetElementInstantly(t, i, e, n, s) {
|
|
2361
2363
|
this.animationEngine.cancelAllAnimations(t);
|
|
2362
2364
|
const r = ["translate(-50%, -50%)"];
|
|
2363
|
-
r.push("translate(0px, 0px)"), r.push(`rotate(${i.rotation}deg)`), t.style.transition = "none", t.style.transform = r.join(" "),
|
|
2365
|
+
r.push("translate(0px, 0px)"), r.push(`rotate(${i.rotation}deg)`), t.style.transition = "none", t.style.transform = r.join(" "), n !== void 0 && s !== void 0 && (t.style.width = `${n}px`, t.style.height = `${s}px`), this.removeFocusedStyling(t, e);
|
|
2364
2366
|
}
|
|
2365
2367
|
/**
|
|
2366
2368
|
* Focus (zoom) an image to center of container
|
|
2367
2369
|
* Implements cross-animation when swapping focus
|
|
2368
2370
|
*/
|
|
2369
2371
|
async focusImage(t, i, e) {
|
|
2370
|
-
if (this.currentFocus === t && this.state ===
|
|
2372
|
+
if (this.currentFocus === t && this.state === x.FOCUSED)
|
|
2371
2373
|
return this.unfocusImage();
|
|
2372
|
-
if (this.incoming?.element === t && this.state ===
|
|
2373
|
-
const { transform:
|
|
2374
|
+
if (this.incoming?.element === t && this.state === x.FOCUSING) {
|
|
2375
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(t);
|
|
2374
2376
|
this.animationEngine.cancelAllAnimations(t), this.outgoing = this.startUnfocusAnimation(
|
|
2375
2377
|
t,
|
|
2376
2378
|
this.incoming.originalState,
|
|
2377
|
-
|
|
2379
|
+
s,
|
|
2378
2380
|
r
|
|
2379
|
-
), this.incoming = null, this.state =
|
|
2381
|
+
), this.incoming = null, this.state = x.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 = x.IDLE;
|
|
2380
2382
|
return;
|
|
2381
2383
|
}
|
|
2382
|
-
const
|
|
2384
|
+
const n = ++this.focusGeneration;
|
|
2383
2385
|
switch (this.state) {
|
|
2384
|
-
case
|
|
2385
|
-
if (this.state =
|
|
2386
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2386
|
+
case x.IDLE:
|
|
2387
|
+
if (this.state = x.FOCUSING, this.incoming = this.startFocusAnimation(t, i, e), await this.waitForAnimation(this.incoming.animationHandle), this.focusGeneration !== n) return;
|
|
2388
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2387
2389
|
break;
|
|
2388
|
-
case
|
|
2389
|
-
if (this.state =
|
|
2390
|
+
case x.FOCUSED:
|
|
2391
|
+
if (this.state = x.CROSS_ANIMATING, this.currentFocus && this.focusData && (this.outgoing = this.startUnfocusAnimation(
|
|
2390
2392
|
this.currentFocus,
|
|
2391
2393
|
this.focusData.originalState
|
|
2392
2394
|
)), this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2393
2395
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2394
2396
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2395
|
-
]), this.focusGeneration !==
|
|
2397
|
+
]), this.focusGeneration !== n)
|
|
2396
2398
|
return;
|
|
2397
2399
|
if (this.outgoing) {
|
|
2398
|
-
const
|
|
2399
|
-
this.removeFocusedStyling(
|
|
2400
|
+
const s = this.outgoing.element;
|
|
2401
|
+
this.removeFocusedStyling(s, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null, this.onUnfocusComplete?.(s);
|
|
2400
2402
|
}
|
|
2401
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2403
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2402
2404
|
break;
|
|
2403
|
-
case
|
|
2405
|
+
case x.FOCUSING:
|
|
2404
2406
|
if (this.incoming && (this.animationEngine.cancelAnimation(this.incoming.animationHandle, !1), this.resetElementInstantly(
|
|
2405
2407
|
this.incoming.element,
|
|
2406
2408
|
this.incoming.originalState,
|
|
2407
2409
|
this.focusData?.originalZIndex || "",
|
|
2408
2410
|
this.focusData?.originalWidth,
|
|
2409
2411
|
this.focusData?.originalHeight
|
|
2410
|
-
), this.incoming = null), this.incoming = this.startFocusAnimation(t, i, e), await this.waitForAnimation(this.incoming.animationHandle), this.focusGeneration !==
|
|
2411
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2412
|
+
), this.incoming = null), this.incoming = this.startFocusAnimation(t, i, e), await this.waitForAnimation(this.incoming.animationHandle), this.focusGeneration !== n) return;
|
|
2413
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2412
2414
|
break;
|
|
2413
|
-
case
|
|
2414
|
-
if (this.state =
|
|
2415
|
+
case x.UNFOCUSING:
|
|
2416
|
+
if (this.state = x.CROSS_ANIMATING, this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2415
2417
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2416
2418
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2417
|
-
]), this.focusGeneration !==
|
|
2419
|
+
]), this.focusGeneration !== n) return;
|
|
2418
2420
|
if (this.outgoing) {
|
|
2419
|
-
const
|
|
2420
|
-
this.removeFocusedStyling(
|
|
2421
|
+
const s = this.outgoing.element;
|
|
2422
|
+
this.removeFocusedStyling(s, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null, this.onUnfocusComplete?.(s);
|
|
2421
2423
|
}
|
|
2422
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2424
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2423
2425
|
break;
|
|
2424
|
-
case
|
|
2426
|
+
case x.CROSS_ANIMATING:
|
|
2425
2427
|
if (this.incoming?.element === t)
|
|
2426
2428
|
return;
|
|
2427
2429
|
if (this.outgoing?.element === t) {
|
|
2428
|
-
const { transform:
|
|
2430
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(t);
|
|
2429
2431
|
if (this.animationEngine.cancelAllAnimations(t), this.incoming) {
|
|
2430
|
-
const { transform:
|
|
2432
|
+
const { transform: a, dimensions: c } = this.captureMidAnimationState(this.incoming.element);
|
|
2431
2433
|
this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2432
2434
|
this.incoming.element,
|
|
2433
2435
|
this.incoming.originalState,
|
|
2434
|
-
|
|
2436
|
+
a,
|
|
2435
2437
|
c
|
|
2436
2438
|
);
|
|
2437
2439
|
} else
|
|
2438
2440
|
this.outgoing = null;
|
|
2439
|
-
if (this.incoming = this.startFocusAnimation(t, i, e,
|
|
2441
|
+
if (this.incoming = this.startFocusAnimation(t, i, e, s, r), await Promise.all([
|
|
2440
2442
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2441
2443
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2442
|
-
]), this.focusGeneration !==
|
|
2444
|
+
]), this.focusGeneration !== n) return;
|
|
2443
2445
|
if (this.outgoing) {
|
|
2444
|
-
const
|
|
2445
|
-
this.removeFocusedStyling(
|
|
2446
|
+
const a = this.outgoing.element;
|
|
2447
|
+
this.removeFocusedStyling(a, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null, this.onUnfocusComplete?.(a);
|
|
2446
2448
|
}
|
|
2447
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2449
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2448
2450
|
return;
|
|
2449
2451
|
}
|
|
2450
2452
|
if (this.outgoing && (this.animationEngine.cancelAnimation(this.outgoing.animationHandle, !1), this.resetElementInstantly(
|
|
@@ -2454,23 +2456,23 @@ class qe {
|
|
|
2454
2456
|
this.outgoing.originalWidth,
|
|
2455
2457
|
this.outgoing.originalHeight
|
|
2456
2458
|
), this.outgoing = null), this.incoming) {
|
|
2457
|
-
const { transform:
|
|
2459
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2458
2460
|
this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2459
2461
|
this.incoming.element,
|
|
2460
2462
|
this.incoming.originalState,
|
|
2461
|
-
|
|
2463
|
+
s,
|
|
2462
2464
|
r
|
|
2463
2465
|
);
|
|
2464
2466
|
}
|
|
2465
2467
|
if (this.incoming = this.startFocusAnimation(t, i, e), await Promise.all([
|
|
2466
2468
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2467
2469
|
this.waitForAnimation(this.incoming.animationHandle)
|
|
2468
|
-
]), this.focusGeneration !==
|
|
2470
|
+
]), this.focusGeneration !== n) return;
|
|
2469
2471
|
if (this.outgoing) {
|
|
2470
|
-
const
|
|
2471
|
-
this.removeFocusedStyling(
|
|
2472
|
+
const s = this.outgoing.element;
|
|
2473
|
+
this.removeFocusedStyling(s, this.outgoing.originalState.zIndex?.toString() || ""), this.outgoing = null, this.onUnfocusComplete?.(s);
|
|
2472
2474
|
}
|
|
2473
|
-
this.currentFocus = t, this.incoming = null, this.state =
|
|
2475
|
+
this.currentFocus = t, this.incoming = null, this.state = x.FOCUSED;
|
|
2474
2476
|
break;
|
|
2475
2477
|
}
|
|
2476
2478
|
}
|
|
@@ -2478,45 +2480,45 @@ class qe {
|
|
|
2478
2480
|
* Unfocus current image, returning it to original position
|
|
2479
2481
|
*/
|
|
2480
2482
|
async unfocusImage() {
|
|
2481
|
-
if (this.state ===
|
|
2483
|
+
if (this.state === x.UNFOCUSING)
|
|
2482
2484
|
return;
|
|
2483
2485
|
const t = ++this.focusGeneration;
|
|
2484
2486
|
if (!this.currentFocus || !this.focusData) {
|
|
2485
|
-
if (this.incoming && this.state ===
|
|
2486
|
-
const { transform:
|
|
2487
|
+
if (this.incoming && this.state === x.FOCUSING) {
|
|
2488
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2487
2489
|
if (this.animationEngine.cancelAllAnimations(this.incoming.element), this.outgoing = this.startUnfocusAnimation(
|
|
2488
2490
|
this.incoming.element,
|
|
2489
2491
|
this.incoming.originalState,
|
|
2490
|
-
|
|
2492
|
+
s,
|
|
2491
2493
|
r
|
|
2492
|
-
), this.incoming = null, this.state =
|
|
2493
|
-
const
|
|
2494
|
-
this.removeFocusedStyling(
|
|
2494
|
+
), this.incoming = null, this.state = x.UNFOCUSING, await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration !== t) return;
|
|
2495
|
+
const a = this.outgoing.element;
|
|
2496
|
+
this.removeFocusedStyling(a, this.focusData?.originalZIndex || ""), this.outgoing = null, this.focusData = null, this.state = x.IDLE, this.onUnfocusComplete?.(a);
|
|
2495
2497
|
}
|
|
2496
2498
|
return;
|
|
2497
2499
|
}
|
|
2498
|
-
if (this.state ===
|
|
2499
|
-
const { transform:
|
|
2500
|
+
if (this.state === x.CROSS_ANIMATING && this.incoming) {
|
|
2501
|
+
const { transform: s, dimensions: r } = this.captureMidAnimationState(this.incoming.element);
|
|
2500
2502
|
this.animationEngine.cancelAllAnimations(this.incoming.element);
|
|
2501
|
-
const
|
|
2503
|
+
const a = this.startUnfocusAnimation(
|
|
2502
2504
|
this.incoming.element,
|
|
2503
2505
|
this.incoming.originalState,
|
|
2504
|
-
|
|
2506
|
+
s,
|
|
2505
2507
|
r
|
|
2506
2508
|
);
|
|
2507
2509
|
if (await Promise.all([
|
|
2508
2510
|
this.outgoing ? this.waitForAnimation(this.outgoing.animationHandle) : Promise.resolve(),
|
|
2509
|
-
this.waitForAnimation(
|
|
2511
|
+
this.waitForAnimation(a.animationHandle)
|
|
2510
2512
|
]), this.focusGeneration !== t) return;
|
|
2511
2513
|
let c = null;
|
|
2512
2514
|
this.outgoing && (c = this.outgoing.element, this.removeFocusedStyling(c, this.outgoing.originalState.zIndex?.toString() || ""));
|
|
2513
|
-
const l =
|
|
2514
|
-
this.removeFocusedStyling(l, this.incoming.originalState.zIndex?.toString() || ""), this.outgoing = null, this.incoming = null, this.currentFocus = null, this.focusData = null, this.state =
|
|
2515
|
+
const l = a.element;
|
|
2516
|
+
this.removeFocusedStyling(l, this.incoming.originalState.zIndex?.toString() || ""), this.outgoing = null, this.incoming = null, this.currentFocus = null, this.focusData = null, this.state = x.IDLE, c && this.onUnfocusComplete?.(c), this.onUnfocusComplete?.(l);
|
|
2515
2517
|
return;
|
|
2516
2518
|
}
|
|
2517
|
-
this.state =
|
|
2518
|
-
const i = this.currentFocus, e = this.focusData.originalState,
|
|
2519
|
-
this.outgoing = this.startUnfocusAnimation(i, e), await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration === t && (this.removeFocusedStyling(i,
|
|
2519
|
+
this.state = x.UNFOCUSING;
|
|
2520
|
+
const i = this.currentFocus, e = this.focusData.originalState, n = this.focusData.originalZIndex;
|
|
2521
|
+
this.outgoing = this.startUnfocusAnimation(i, e), await this.waitForAnimation(this.outgoing.animationHandle), this.focusGeneration === t && (this.removeFocusedStyling(i, n), this.outgoing = null, this.currentFocus = null, this.focusData = null, this.state = x.IDLE, this.onUnfocusComplete?.(i));
|
|
2520
2522
|
}
|
|
2521
2523
|
/**
|
|
2522
2524
|
* Swap focus from current image to a new one (alias for focusImage with cross-animation)
|
|
@@ -2534,7 +2536,7 @@ class qe {
|
|
|
2534
2536
|
* Check if an image is currently focused (stable state)
|
|
2535
2537
|
*/
|
|
2536
2538
|
isFocused(t) {
|
|
2537
|
-
return this.currentFocus === t && this.state ===
|
|
2539
|
+
return this.currentFocus === t && this.state === x.FOCUSED;
|
|
2538
2540
|
}
|
|
2539
2541
|
/**
|
|
2540
2542
|
* Check if an image is the target of current focus animation
|
|
@@ -2555,9 +2557,9 @@ class qe {
|
|
|
2555
2557
|
* Used during swipe gestures for visual feedback
|
|
2556
2558
|
*/
|
|
2557
2559
|
setDragOffset(t) {
|
|
2558
|
-
if (!this.currentFocus || !this.focusData || this.state !==
|
|
2559
|
-
const i = this.currentFocus, e = this.focusData.focusTransform,
|
|
2560
|
-
|
|
2560
|
+
if (!this.currentFocus || !this.focusData || this.state !== x.FOCUSED) return;
|
|
2561
|
+
const i = this.currentFocus, e = this.focusData.focusTransform, n = ["translate(-50%, -50%)"], s = (e.x ?? 0) + t, r = e.y ?? 0;
|
|
2562
|
+
n.push(`translate(${s}px, ${r}px)`), e.rotation !== void 0 && n.push(`rotate(${e.rotation}deg)`), i.style.transition = "none", i.style.transform = n.join(" ");
|
|
2561
2563
|
}
|
|
2562
2564
|
/**
|
|
2563
2565
|
* Clear the drag offset, optionally animating back to center
|
|
@@ -2565,10 +2567,10 @@ class qe {
|
|
|
2565
2567
|
* @param duration - Animation duration in ms (default 150)
|
|
2566
2568
|
*/
|
|
2567
2569
|
clearDragOffset(t, i = 150) {
|
|
2568
|
-
if (!this.currentFocus || !this.focusData || this.state !==
|
|
2569
|
-
const e = this.currentFocus,
|
|
2570
|
-
|
|
2571
|
-
const c =
|
|
2570
|
+
if (!this.currentFocus || !this.focusData || this.state !== x.FOCUSED) return;
|
|
2571
|
+
const e = this.currentFocus, n = this.focusData.focusTransform, s = ["translate(-50%, -50%)"], r = n.x ?? 0, a = n.y ?? 0;
|
|
2572
|
+
s.push(`translate(${r}px, ${a}px)`), n.rotation !== void 0 && s.push(`rotate(${n.rotation}deg)`);
|
|
2573
|
+
const c = s.join(" ");
|
|
2572
2574
|
t ? (e.style.transition = `transform ${i}ms ease-out`, e.style.transform = c, setTimeout(() => {
|
|
2573
2575
|
this.currentFocus === e && (e.style.transition = "none");
|
|
2574
2576
|
}, i)) : (e.style.transition = "none", e.style.transform = c);
|
|
@@ -2595,10 +2597,10 @@ class qe {
|
|
|
2595
2597
|
this.focusData.originalZIndex,
|
|
2596
2598
|
this.focusData.originalWidth,
|
|
2597
2599
|
this.focusData.originalHeight
|
|
2598
|
-
), this.state =
|
|
2600
|
+
), this.state = x.IDLE, this.currentFocus = null, this.focusData = null, this.outgoing = null, this.incoming = null;
|
|
2599
2601
|
}
|
|
2600
2602
|
}
|
|
2601
|
-
const
|
|
2603
|
+
const qe = 50, Xe = 0.5, Ye = 20, Ve = 0.3, Je = 150, Ke = 30, rt = class rt {
|
|
2602
2604
|
constructor(t, i) {
|
|
2603
2605
|
this.enabled = !1, this.touchState = null, this.recentTouchTimestamp = 0, this.container = t, this.callbacks = i, this.boundTouchStart = this.handleTouchStart.bind(this), this.boundTouchMove = this.handleTouchMove.bind(this), this.boundTouchEnd = this.handleTouchEnd.bind(this), this.boundTouchCancel = this.handleTouchCancel.bind(this);
|
|
2604
2606
|
}
|
|
@@ -2625,7 +2627,7 @@ const Be = 50, Xe = 0.5, Ye = 20, Ve = 0.3, Je = 150, Ke = 30, at = class at {
|
|
|
2625
2627
|
* Used to prevent click-outside from unfocusing immediately after touch
|
|
2626
2628
|
*/
|
|
2627
2629
|
hadRecentTouch() {
|
|
2628
|
-
return Date.now() - this.recentTouchTimestamp <
|
|
2630
|
+
return Date.now() - this.recentTouchTimestamp < rt.TOUCH_CLICK_DELAY;
|
|
2629
2631
|
}
|
|
2630
2632
|
handleTouchStart(t) {
|
|
2631
2633
|
if (t.touches.length !== 1) return;
|
|
@@ -2642,30 +2644,30 @@ const Be = 50, Xe = 0.5, Ye = 20, Ve = 0.3, Je = 150, Ke = 30, at = class at {
|
|
|
2642
2644
|
}
|
|
2643
2645
|
handleTouchMove(t) {
|
|
2644
2646
|
if (!this.touchState || t.touches.length !== 1) return;
|
|
2645
|
-
const i = t.touches[0], e = i.clientX - this.touchState.startX,
|
|
2646
|
-
if (this.touchState.isHorizontalSwipe === null && Math.sqrt(e * e +
|
|
2647
|
-
const
|
|
2648
|
-
this.touchState.isHorizontalSwipe =
|
|
2647
|
+
const i = t.touches[0], e = i.clientX - this.touchState.startX, n = i.clientY - this.touchState.startY;
|
|
2648
|
+
if (this.touchState.isHorizontalSwipe === null && Math.sqrt(e * e + n * n) > 10) {
|
|
2649
|
+
const a = Math.atan2(Math.abs(n), Math.abs(e)) * (180 / Math.PI);
|
|
2650
|
+
this.touchState.isHorizontalSwipe = a <= Ke;
|
|
2649
2651
|
}
|
|
2650
2652
|
if (this.touchState.isHorizontalSwipe !== !1 && this.touchState.isHorizontalSwipe === !0) {
|
|
2651
2653
|
t.preventDefault(), this.touchState.isDragging = !0, this.touchState.currentX = i.clientX;
|
|
2652
|
-
const
|
|
2653
|
-
this.callbacks.onDragOffset(
|
|
2654
|
+
const s = e * Ve;
|
|
2655
|
+
this.callbacks.onDragOffset(s);
|
|
2654
2656
|
}
|
|
2655
2657
|
}
|
|
2656
2658
|
handleTouchEnd(t) {
|
|
2657
2659
|
if (!this.touchState) return;
|
|
2658
2660
|
this.recentTouchTimestamp = Date.now();
|
|
2659
|
-
const i = this.touchState.currentX - this.touchState.startX, e = performance.now() - this.touchState.startTime,
|
|
2661
|
+
const i = this.touchState.currentX - this.touchState.startX, e = performance.now() - this.touchState.startTime, n = Math.abs(i) / e, s = Math.abs(i);
|
|
2660
2662
|
let r = !1;
|
|
2661
|
-
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (
|
|
2663
|
+
this.touchState.isHorizontalSwipe === !0 && this.touchState.isDragging && (s >= qe || n >= Xe && s >= Ye) && (r = !0, i < 0 ? this.callbacks.onNext() : this.callbacks.onPrev()), this.touchState.isDragging && this.callbacks.onDragEnd(r), this.touchState = null;
|
|
2662
2664
|
}
|
|
2663
2665
|
handleTouchCancel(t) {
|
|
2664
2666
|
this.touchState?.isDragging && this.callbacks.onDragEnd(!1), this.touchState = null;
|
|
2665
2667
|
}
|
|
2666
2668
|
};
|
|
2667
|
-
|
|
2668
|
-
let
|
|
2669
|
+
rt.TOUCH_CLICK_DELAY = 300;
|
|
2670
|
+
let bt = rt;
|
|
2669
2671
|
class Ze {
|
|
2670
2672
|
constructor(t) {
|
|
2671
2673
|
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)
|
|
@@ -2680,8 +2682,8 @@ class Ze {
|
|
|
2680
2682
|
for (const i of this.sources)
|
|
2681
2683
|
if ("folders" in i)
|
|
2682
2684
|
for (const e of i.folders) {
|
|
2683
|
-
const
|
|
2684
|
-
this._discoveredUrls.push(...
|
|
2685
|
+
const n = i.recursive !== void 0 ? i.recursive : !0, s = await this.loadFromFolder(e, t, n);
|
|
2686
|
+
this._discoveredUrls.push(...s);
|
|
2685
2687
|
}
|
|
2686
2688
|
else if ("files" in i) {
|
|
2687
2689
|
const e = await this.loadFiles(i.files, t);
|
|
@@ -2726,9 +2728,9 @@ class Ze {
|
|
|
2726
2728
|
// Alternative format
|
|
2727
2729
|
];
|
|
2728
2730
|
for (const e of i) {
|
|
2729
|
-
const
|
|
2730
|
-
if (
|
|
2731
|
-
return
|
|
2731
|
+
const n = t.match(e);
|
|
2732
|
+
if (n && n[1])
|
|
2733
|
+
return n[1];
|
|
2732
2734
|
}
|
|
2733
2735
|
return null;
|
|
2734
2736
|
}
|
|
@@ -2740,15 +2742,15 @@ class Ze {
|
|
|
2740
2742
|
* @returns Promise resolving to array of image URLs
|
|
2741
2743
|
*/
|
|
2742
2744
|
async loadFromFolder(t, i, e = !0) {
|
|
2743
|
-
const
|
|
2744
|
-
if (!
|
|
2745
|
+
const n = this.extractFolderId(t);
|
|
2746
|
+
if (!n)
|
|
2745
2747
|
throw new Error("Invalid Google Drive folder URL. Please check the URL format.");
|
|
2746
2748
|
if (!this.apiKey || this.apiKey === "YOUR_API_KEY_HERE")
|
|
2747
|
-
return this.loadImagesDirectly(
|
|
2749
|
+
return this.loadImagesDirectly(n, i);
|
|
2748
2750
|
try {
|
|
2749
|
-
return e ? await this.loadImagesRecursively(
|
|
2750
|
-
} catch (
|
|
2751
|
-
return console.error("Error loading from Google Drive API:",
|
|
2751
|
+
return e ? await this.loadImagesRecursively(n, i) : await this.loadImagesFromSingleFolder(n, i);
|
|
2752
|
+
} catch (s) {
|
|
2753
|
+
return console.error("Error loading from Google Drive API:", s), this.loadImagesDirectly(n, i);
|
|
2752
2754
|
}
|
|
2753
2755
|
}
|
|
2754
2756
|
/**
|
|
@@ -2758,10 +2760,10 @@ class Ze {
|
|
|
2758
2760
|
* @returns Promise resolving to array of image URLs
|
|
2759
2761
|
*/
|
|
2760
2762
|
async loadImagesFromSingleFolder(t, i) {
|
|
2761
|
-
const e = [],
|
|
2762
|
-
if (!
|
|
2763
|
-
throw new Error(`API request failed: ${
|
|
2764
|
-
const l = (await
|
|
2763
|
+
const e = [], n = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(n)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
|
|
2764
|
+
if (!a.ok)
|
|
2765
|
+
throw new Error(`API request failed: ${a.status} ${a.statusText}`);
|
|
2766
|
+
const l = (await a.json()).files.filter(
|
|
2765
2767
|
(u) => u.mimeType.startsWith("image/") && i.isAllowed(u.name)
|
|
2766
2768
|
);
|
|
2767
2769
|
return this.log(`Found ${l.length} images in folder ${t} (non-recursive)`), l.forEach((u) => {
|
|
@@ -2776,25 +2778,25 @@ class Ze {
|
|
|
2776
2778
|
*/
|
|
2777
2779
|
async loadFiles(t, i) {
|
|
2778
2780
|
const e = [];
|
|
2779
|
-
for (const
|
|
2780
|
-
const
|
|
2781
|
-
if (!
|
|
2782
|
-
this.log(`Skipping invalid file URL: ${
|
|
2781
|
+
for (const n of t) {
|
|
2782
|
+
const s = this.extractFileId(n);
|
|
2783
|
+
if (!s) {
|
|
2784
|
+
this.log(`Skipping invalid file URL: ${n}`);
|
|
2783
2785
|
continue;
|
|
2784
2786
|
}
|
|
2785
2787
|
if (this.apiKey && this.apiKey !== "YOUR_API_KEY_HERE")
|
|
2786
2788
|
try {
|
|
2787
|
-
const r = `${this.apiEndpoint}/${
|
|
2788
|
-
if (
|
|
2789
|
-
const c = await
|
|
2790
|
-
c.mimeType.startsWith("image/") && i.isAllowed(c.name) ? (e.push(`https://lh3.googleusercontent.com/d/${
|
|
2789
|
+
const r = `${this.apiEndpoint}/${s}?fields=name,mimeType&key=${this.apiKey}`, a = await fetch(r);
|
|
2790
|
+
if (a.ok) {
|
|
2791
|
+
const c = await a.json();
|
|
2792
|
+
c.mimeType.startsWith("image/") && i.isAllowed(c.name) ? (e.push(`https://lh3.googleusercontent.com/d/${s}=s1600`), this.log(`Added file: ${c.name}`)) : this.log(`Skipping non-image file: ${c.name} (${c.mimeType})`);
|
|
2791
2793
|
} else
|
|
2792
|
-
this.log(`Failed to fetch metadata for file ${
|
|
2794
|
+
this.log(`Failed to fetch metadata for file ${s}: ${a.status}`);
|
|
2793
2795
|
} catch (r) {
|
|
2794
|
-
this.log(`Error fetching metadata for file ${
|
|
2796
|
+
this.log(`Error fetching metadata for file ${s}:`, r);
|
|
2795
2797
|
}
|
|
2796
2798
|
else
|
|
2797
|
-
e.push(`https://lh3.googleusercontent.com/d/${
|
|
2799
|
+
e.push(`https://lh3.googleusercontent.com/d/${s}=s1600`);
|
|
2798
2800
|
}
|
|
2799
2801
|
return e;
|
|
2800
2802
|
}
|
|
@@ -2815,9 +2817,9 @@ class Ze {
|
|
|
2815
2817
|
// Generic id parameter
|
|
2816
2818
|
];
|
|
2817
2819
|
for (const e of i) {
|
|
2818
|
-
const
|
|
2819
|
-
if (
|
|
2820
|
-
return
|
|
2820
|
+
const n = t.match(e);
|
|
2821
|
+
if (n && n[1])
|
|
2822
|
+
return n[1];
|
|
2821
2823
|
}
|
|
2822
2824
|
return null;
|
|
2823
2825
|
}
|
|
@@ -2828,10 +2830,10 @@ class Ze {
|
|
|
2828
2830
|
* @returns Promise resolving to array of image URLs
|
|
2829
2831
|
*/
|
|
2830
2832
|
async loadImagesRecursively(t, i) {
|
|
2831
|
-
const e = [],
|
|
2832
|
-
if (!
|
|
2833
|
-
throw new Error(`API request failed: ${
|
|
2834
|
-
const c = await
|
|
2833
|
+
const e = [], n = `'${t}' in parents and trashed=false`, r = `${this.apiEndpoint}?q=${encodeURIComponent(n)}&fields=files(id,name,mimeType,thumbnailLink)&key=${this.apiKey}`, a = await fetch(r);
|
|
2834
|
+
if (!a.ok)
|
|
2835
|
+
throw new Error(`API request failed: ${a.status} ${a.statusText}`);
|
|
2836
|
+
const c = await a.json(), l = c.files.filter(
|
|
2835
2837
|
(h) => h.mimeType.startsWith("image/") && i.isAllowed(h.name)
|
|
2836
2838
|
), u = c.files.filter(
|
|
2837
2839
|
(h) => h.mimeType === "application/vnd.google-apps.folder"
|
|
@@ -2855,11 +2857,11 @@ class Ze {
|
|
|
2855
2857
|
*/
|
|
2856
2858
|
async loadImagesDirectly(t, i) {
|
|
2857
2859
|
try {
|
|
2858
|
-
const e = `https://drive.google.com/embeddedfolderview?id=${t}`,
|
|
2859
|
-
if (!
|
|
2860
|
+
const e = `https://drive.google.com/embeddedfolderview?id=${t}`, n = await fetch(e, { mode: "cors" });
|
|
2861
|
+
if (!n.ok)
|
|
2860
2862
|
throw new Error("Cannot access folder directly (CORS or permissions issue)");
|
|
2861
|
-
const
|
|
2862
|
-
return [...new Set(
|
|
2863
|
+
const s = await n.text(), r = /\/file\/d\/([a-zA-Z0-9_-]+)/g, a = [...s.matchAll(r)];
|
|
2864
|
+
return [...new Set(a.map((u) => u[1]))].map(
|
|
2863
2865
|
(u) => `https://drive.google.com/uc?export=view&id=${u}`
|
|
2864
2866
|
);
|
|
2865
2867
|
} catch (e) {
|
|
@@ -2951,13 +2953,13 @@ class Qe {
|
|
|
2951
2953
|
if (!Array.isArray(t))
|
|
2952
2954
|
return console.warn("URLs must be an array:", t), [];
|
|
2953
2955
|
const e = [];
|
|
2954
|
-
for (const
|
|
2955
|
-
const
|
|
2956
|
-
if (!i.isAllowed(
|
|
2957
|
-
this.log(`Skipping filtered URL: ${
|
|
2956
|
+
for (const n of t) {
|
|
2957
|
+
const s = n.split("/").pop() || n;
|
|
2958
|
+
if (!i.isAllowed(s)) {
|
|
2959
|
+
this.log(`Skipping filtered URL: ${n}`);
|
|
2958
2960
|
continue;
|
|
2959
2961
|
}
|
|
2960
|
-
this.validateUrls ? await this.validateUrl(
|
|
2962
|
+
this.validateUrls ? await this.validateUrl(n) ? e.push(n) : console.warn(`Skipping invalid/missing URL: ${n}`) : e.push(n);
|
|
2961
2963
|
}
|
|
2962
2964
|
return e;
|
|
2963
2965
|
}
|
|
@@ -2971,16 +2973,16 @@ class Qe {
|
|
|
2971
2973
|
async processPath(t, i, e) {
|
|
2972
2974
|
if (!Array.isArray(i))
|
|
2973
2975
|
return console.warn("files must be an array:", i), [];
|
|
2974
|
-
const
|
|
2975
|
-
for (const
|
|
2976
|
-
if (!e.isAllowed(
|
|
2977
|
-
this.log(`Skipping filtered file: ${
|
|
2976
|
+
const n = [];
|
|
2977
|
+
for (const s of i) {
|
|
2978
|
+
if (!e.isAllowed(s)) {
|
|
2979
|
+
this.log(`Skipping filtered file: ${s}`);
|
|
2978
2980
|
continue;
|
|
2979
2981
|
}
|
|
2980
|
-
const r = this.constructUrl(t,
|
|
2981
|
-
this.validateUrls ? await this.validateUrl(r) ?
|
|
2982
|
+
const r = this.constructUrl(t, s);
|
|
2983
|
+
this.validateUrls ? await this.validateUrl(r) ? n.push(r) : console.warn(`Skipping invalid/missing file: ${r}`) : n.push(r);
|
|
2982
2984
|
}
|
|
2983
|
-
return
|
|
2985
|
+
return n;
|
|
2984
2986
|
}
|
|
2985
2987
|
/**
|
|
2986
2988
|
* Process a JSON endpoint source
|
|
@@ -2991,17 +2993,17 @@ class Qe {
|
|
|
2991
2993
|
*/
|
|
2992
2994
|
async processJson(t, i) {
|
|
2993
2995
|
this.log(`Fetching JSON endpoint: ${t}`);
|
|
2994
|
-
const e = new AbortController(),
|
|
2996
|
+
const e = new AbortController(), n = setTimeout(() => e.abort(), 1e4);
|
|
2995
2997
|
try {
|
|
2996
|
-
const
|
|
2997
|
-
if (clearTimeout(
|
|
2998
|
-
throw new Error(`HTTP ${
|
|
2999
|
-
const r = await
|
|
2998
|
+
const s = await fetch(t, { signal: e.signal });
|
|
2999
|
+
if (clearTimeout(n), !s.ok)
|
|
3000
|
+
throw new Error(`HTTP ${s.status} fetching ${t}`);
|
|
3001
|
+
const r = await s.json();
|
|
3000
3002
|
if (!r || !Array.isArray(r.images))
|
|
3001
3003
|
throw new Error('JSON source must return JSON with shape { "images": ["url1", "url2", ...] }');
|
|
3002
3004
|
return this.log(`JSON endpoint returned ${r.images.length} image(s)`), await this.processUrls(r.images, i);
|
|
3003
|
-
} catch (
|
|
3004
|
-
throw clearTimeout(
|
|
3005
|
+
} catch (s) {
|
|
3006
|
+
throw clearTimeout(n), s instanceof Error && s.name === "AbortError" ? new Error(`Timeout fetching JSON endpoint: ${t}`) : s;
|
|
3005
3007
|
}
|
|
3006
3008
|
}
|
|
3007
3009
|
/**
|
|
@@ -3023,11 +3025,11 @@ class Qe {
|
|
|
3023
3025
|
if (!(t.startsWith(window.location.origin) || t.startsWith("/")))
|
|
3024
3026
|
return this.log(`Skipping validation for cross-origin URL: ${t}`), !0;
|
|
3025
3027
|
try {
|
|
3026
|
-
const e = new AbortController(),
|
|
3028
|
+
const e = new AbortController(), n = setTimeout(() => e.abort(), this.validationTimeout), s = await fetch(t, {
|
|
3027
3029
|
method: "HEAD",
|
|
3028
3030
|
signal: e.signal
|
|
3029
3031
|
});
|
|
3030
|
-
return clearTimeout(
|
|
3032
|
+
return clearTimeout(n), s.ok ? !0 : (this.log(`Validation failed for ${t}: HTTP ${s.status}`), !1);
|
|
3031
3033
|
} catch (e) {
|
|
3032
3034
|
return e instanceof Error && (e.name === "AbortError" ? this.log(`Validation timeout for ${t}`) : this.log(`Validation failed for ${t}:`, e.message)), !1;
|
|
3033
3035
|
}
|
|
@@ -3044,8 +3046,8 @@ class Qe {
|
|
|
3044
3046
|
return `${e}/${i}`;
|
|
3045
3047
|
if (typeof window > "u")
|
|
3046
3048
|
return `${e}/${i}`;
|
|
3047
|
-
const
|
|
3048
|
-
return `${
|
|
3049
|
+
const n = window.location.origin, r = (t.startsWith("/") ? t : "/" + t).replace(/\/$/, "");
|
|
3050
|
+
return `${n}${r}/${i}`;
|
|
3049
3051
|
}
|
|
3050
3052
|
/**
|
|
3051
3053
|
* Check if URL is absolute (contains protocol)
|
|
@@ -3079,16 +3081,16 @@ class ti {
|
|
|
3079
3081
|
*/
|
|
3080
3082
|
async prepare(t) {
|
|
3081
3083
|
this._discoveredUrls = [], this.log(`Preparing ${this.loaders.length} loader(s) in parallel`);
|
|
3082
|
-
const i = this.loaders.map((e,
|
|
3083
|
-
this.log(`Loader ${
|
|
3084
|
-
}).catch((
|
|
3085
|
-
console.warn(`Loader ${
|
|
3084
|
+
const i = this.loaders.map((e, n) => e.prepare(t).then(() => {
|
|
3085
|
+
this.log(`Loader ${n} prepared with ${e.imagesLength()} images`);
|
|
3086
|
+
}).catch((s) => {
|
|
3087
|
+
console.warn(`Loader ${n} failed to prepare:`, s);
|
|
3086
3088
|
}));
|
|
3087
3089
|
await Promise.all(i);
|
|
3088
3090
|
for (const e of this.loaders)
|
|
3089
3091
|
if (e.isPrepared()) {
|
|
3090
|
-
const
|
|
3091
|
-
this._discoveredUrls.push(...
|
|
3092
|
+
const n = e.imageURLs();
|
|
3093
|
+
this._discoveredUrls.push(...n);
|
|
3092
3094
|
}
|
|
3093
3095
|
this._prepared = !0, this.log(`CompositeLoader prepared with ${this._discoveredUrls.length} total images`);
|
|
3094
3096
|
}
|
|
@@ -3207,25 +3209,56 @@ const ii = `
|
|
|
3207
3209
|
pointer-events: none;
|
|
3208
3210
|
}
|
|
3209
3211
|
|
|
3212
|
+
.fbn-ic-gallery:focus,
|
|
3213
|
+
.fbn-ic-gallery.fbn-ic-has-focus {
|
|
3214
|
+
outline: 2px solid rgba(147, 197, 253, 0.8);
|
|
3215
|
+
outline-offset: -4px;
|
|
3216
|
+
}
|
|
3217
|
+
.fbn-ic-gallery.fbn-ic-suppress-outline:focus {
|
|
3218
|
+
outline: none;
|
|
3219
|
+
}
|
|
3220
|
+
.fbn-ic-gallery.fbn-ic-suppress-outline.fbn-ic-has-focus {
|
|
3221
|
+
outline: 2px solid rgba(99, 102, 241, 0.6);
|
|
3222
|
+
outline-offset: -4px;
|
|
3223
|
+
}
|
|
3224
|
+
|
|
3225
|
+
.fbn-ic-nav-btn {
|
|
3226
|
+
position: absolute;
|
|
3227
|
+
top: 50%;
|
|
3228
|
+
transform: translateY(-50%);
|
|
3229
|
+
z-index: 10001;
|
|
3230
|
+
cursor: pointer;
|
|
3231
|
+
border: none;
|
|
3232
|
+
background: none;
|
|
3233
|
+
padding: 0;
|
|
3234
|
+
line-height: 1;
|
|
3235
|
+
}
|
|
3236
|
+
.fbn-ic-nav-btn-prev {
|
|
3237
|
+
left: 12px;
|
|
3238
|
+
}
|
|
3239
|
+
.fbn-ic-nav-btn-next {
|
|
3240
|
+
right: 12px;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3210
3243
|
.fbn-ic-hidden {
|
|
3211
3244
|
display: none !important;
|
|
3212
3245
|
}
|
|
3213
3246
|
`;
|
|
3214
|
-
function
|
|
3247
|
+
function ni() {
|
|
3215
3248
|
if (typeof document > "u") return;
|
|
3216
|
-
const
|
|
3217
|
-
if (document.getElementById(
|
|
3249
|
+
const o = "fbn-ic-functional-styles";
|
|
3250
|
+
if (document.getElementById(o)) return;
|
|
3218
3251
|
const t = document.createElement("style");
|
|
3219
|
-
t.id =
|
|
3252
|
+
t.id = o, t.textContent = ii, document.head.appendChild(t);
|
|
3220
3253
|
}
|
|
3221
|
-
let
|
|
3254
|
+
let oi = class {
|
|
3222
3255
|
constructor(t = {}) {
|
|
3223
|
-
this.fullConfig =
|
|
3256
|
+
this.fullConfig = ne(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.prevButtonEl = null, this.nextButtonEl = null, this.prevButtonElAutoCreated = !1, this.nextButtonElAutoCreated = !1, this.animationEngine = new re(this.fullConfig.animation), this.layoutEngine = new _e({
|
|
3224
3257
|
layout: this.fullConfig.layout,
|
|
3225
3258
|
image: this.fullConfig.image
|
|
3226
|
-
}), this.zoomEngine = new
|
|
3259
|
+
}), this.zoomEngine = new Ge(this.fullConfig.interaction.focus, this.animationEngine, this.fullConfig.styling), this.defaultStyles = it(this.fullConfig.styling?.default), this.defaultClassName = this.fullConfig.styling?.default?.className, this.hoverClassName = this.fullConfig.styling?.hover?.className;
|
|
3227
3260
|
const i = this.fullConfig.animation.entry || R.animation.entry;
|
|
3228
|
-
this.entryAnimationEngine = new
|
|
3261
|
+
this.entryAnimationEngine = new ye(
|
|
3229
3262
|
i,
|
|
3230
3263
|
this.fullConfig.layout.algorithm
|
|
3231
3264
|
);
|
|
@@ -3233,8 +3266,18 @@ let ni = class {
|
|
|
3233
3266
|
e && e.type !== "none" ? this.idleAnimationEngine = new ve(
|
|
3234
3267
|
e,
|
|
3235
3268
|
i.timing?.duration ?? 600
|
|
3236
|
-
) : this.idleAnimationEngine = null, this.zoomEngine.setOnUnfocusCompleteCallback((
|
|
3237
|
-
this.idleAnimationEngine?.resumeForImage(
|
|
3269
|
+
) : this.idleAnimationEngine = null, this.zoomEngine.setOnUnfocusCompleteCallback((n) => {
|
|
3270
|
+
this.idleAnimationEngine?.resumeForImage(n);
|
|
3271
|
+
const s = n;
|
|
3272
|
+
requestAnimationFrame(() => {
|
|
3273
|
+
if (s.matches(":hover") && this.fullConfig.styling?.hover) {
|
|
3274
|
+
const r = this.imageElements.indexOf(s);
|
|
3275
|
+
if (r !== -1) {
|
|
3276
|
+
const a = s.offsetHeight, c = s.cachedRenderedWidth;
|
|
3277
|
+
st(s, this.fullConfig.styling.hover, a, c), et(s, this.hoverClassName), this.hoveredImage = { element: s, layout: this.imageLayouts[r] };
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
});
|
|
3238
3281
|
}), this.swipeEngine = null, this.imageFilter = this.createImageFilter(), this.imageLoader = this.createLoader(), this.containerEl = null, this.loadingEl = null, this.errorEl = null;
|
|
3239
3282
|
}
|
|
3240
3283
|
/**
|
|
@@ -3252,7 +3295,7 @@ let ni = class {
|
|
|
3252
3295
|
const t = this.fullConfig.loaders, i = this.fullConfig.config.loaders ?? {};
|
|
3253
3296
|
if (!t || t.length === 0)
|
|
3254
3297
|
throw new Error("No loaders configured. Provide `images`, `loaders`, or both.");
|
|
3255
|
-
const e = t.map((
|
|
3298
|
+
const e = t.map((n) => this.createLoaderFromEntry(n, i));
|
|
3256
3299
|
return e.length === 1 ? e[0] : new ti({
|
|
3257
3300
|
loaders: e,
|
|
3258
3301
|
debugLogging: this.fullConfig.config.debug?.loaders
|
|
@@ -3263,7 +3306,7 @@ let ni = class {
|
|
|
3263
3306
|
*/
|
|
3264
3307
|
createLoaderFromEntry(t, i) {
|
|
3265
3308
|
if ("static" in t) {
|
|
3266
|
-
const e = t.static,
|
|
3309
|
+
const e = t.static, n = {
|
|
3267
3310
|
...e,
|
|
3268
3311
|
validateUrls: e.validateUrls ?? i.validateUrls,
|
|
3269
3312
|
validationTimeout: e.validationTimeout ?? i.validationTimeout,
|
|
@@ -3271,14 +3314,14 @@ let ni = class {
|
|
|
3271
3314
|
allowedExtensions: e.allowedExtensions ?? i.allowedExtensions,
|
|
3272
3315
|
debugLogging: e.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
3273
3316
|
};
|
|
3274
|
-
return new Qe(
|
|
3317
|
+
return new Qe(n);
|
|
3275
3318
|
} else if ("googleDrive" in t) {
|
|
3276
|
-
const e = t.googleDrive,
|
|
3319
|
+
const e = t.googleDrive, n = {
|
|
3277
3320
|
...e,
|
|
3278
3321
|
allowedExtensions: e.allowedExtensions ?? i.allowedExtensions,
|
|
3279
3322
|
debugLogging: e.debugLogging ?? this.fullConfig.config.debug?.loaders
|
|
3280
3323
|
};
|
|
3281
|
-
return new Ze(
|
|
3324
|
+
return new Ze(n);
|
|
3282
3325
|
} else
|
|
3283
3326
|
throw new Error(`Unknown loader entry: ${JSON.stringify(t)}`);
|
|
3284
3327
|
}
|
|
@@ -3287,11 +3330,11 @@ let ni = class {
|
|
|
3287
3330
|
*/
|
|
3288
3331
|
async init() {
|
|
3289
3332
|
try {
|
|
3290
|
-
if (
|
|
3333
|
+
if (ni(), this.containerRef)
|
|
3291
3334
|
this.containerEl = this.containerRef;
|
|
3292
3335
|
else if (this.containerEl = document.getElementById(this.containerId), !this.containerEl)
|
|
3293
3336
|
throw new Error(`Container #${this.containerId} not found`);
|
|
3294
|
-
this.containerEl.classList.add("fbn-ic-gallery"), this.containerEl.setAttribute("tabindex", "0"), this.fullConfig.interaction.navigation?.swipe !== !1 && (this.swipeEngine = new
|
|
3337
|
+
this.containerEl.classList.add("fbn-ic-gallery"), this.containerEl.setAttribute("tabindex", "0"), this.fullConfig.interaction.navigation?.swipe !== !1 && (this.swipeEngine = new bt(this.containerEl, {
|
|
3295
3338
|
onNext: () => this.navigateToNextImage(),
|
|
3296
3339
|
onPrev: () => this.navigateToPreviousImage(),
|
|
3297
3340
|
onDragOffset: (t) => this.zoomEngine.setDragOffset(t),
|
|
@@ -3305,7 +3348,11 @@ let ni = class {
|
|
|
3305
3348
|
}
|
|
3306
3349
|
setupUI() {
|
|
3307
3350
|
const t = this.fullConfig.ui;
|
|
3308
|
-
t.showLoadingSpinner && (t.loadingElement ? (this.loadingEl = this.resolveElement(t.loadingElement), this.loadingElAutoCreated = !1) : (this.loadingEl = this.createDefaultLoadingElement(), this.loadingElAutoCreated = !0)), t.errorElement ? (this.errorEl = this.resolveElement(t.errorElement), this.errorElAutoCreated = !1) : (this.errorEl = this.createDefaultErrorElement(), this.errorElAutoCreated = !0), t.showImageCounter && (t.counterElement ? (this.counterEl = this.resolveElement(t.counterElement), this.counterElAutoCreated = !1) : (this.counterEl = this.createDefaultCounterElement(), this.counterElAutoCreated = !0))
|
|
3351
|
+
t.showFocusOutline ? this.containerEl?.classList.remove("fbn-ic-suppress-outline") : this.containerEl?.classList.add("fbn-ic-suppress-outline"), t.showLoadingSpinner && (t.loadingElement ? (this.loadingEl = this.resolveElement(t.loadingElement), this.loadingElAutoCreated = !1) : (this.loadingEl = this.createDefaultLoadingElement(), this.loadingElAutoCreated = !0)), t.errorElement ? (this.errorEl = this.resolveElement(t.errorElement), this.errorElAutoCreated = !1) : (this.errorEl = this.createDefaultErrorElement(), this.errorElAutoCreated = !0), t.showImageCounter && (t.counterElement ? (this.counterEl = this.resolveElement(t.counterElement), this.counterElAutoCreated = !1) : (this.counterEl = this.createDefaultCounterElement(), this.counterElAutoCreated = !0)), t.showNavButtons && (t.prevButtonElement ? (this.prevButtonEl = this.resolveElement(t.prevButtonElement), this.prevButtonElAutoCreated = !1) : (this.prevButtonEl = this.createDefaultPrevButtonElement(), this.prevButtonElAutoCreated = !0), t.nextButtonElement ? (this.nextButtonEl = this.resolveElement(t.nextButtonElement), this.nextButtonElAutoCreated = !1) : (this.nextButtonEl = this.createDefaultNextButtonElement(), this.nextButtonElAutoCreated = !0), this.prevButtonEl?.addEventListener("click", (i) => {
|
|
3352
|
+
i.stopPropagation(), this.navigateToPreviousImage();
|
|
3353
|
+
}), this.nextButtonEl?.addEventListener("click", (i) => {
|
|
3354
|
+
i.stopPropagation(), this.navigateToNextImage();
|
|
3355
|
+
}));
|
|
3309
3356
|
}
|
|
3310
3357
|
resolveElement(t) {
|
|
3311
3358
|
return t instanceof HTMLElement ? t : document.getElementById(t);
|
|
@@ -3326,11 +3373,19 @@ let ni = class {
|
|
|
3326
3373
|
const t = document.createElement("div");
|
|
3327
3374
|
return t.className = "fbn-ic-counter fbn-ic-hidden", this.containerEl.appendChild(t), t;
|
|
3328
3375
|
}
|
|
3376
|
+
createDefaultPrevButtonElement() {
|
|
3377
|
+
const t = document.createElement("button");
|
|
3378
|
+
return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-prev fbn-ic-hidden", t.textContent = "‹", t.setAttribute("aria-label", "Previous image"), t.setAttribute("tabindex", "-1"), this.containerEl.appendChild(t), t;
|
|
3379
|
+
}
|
|
3380
|
+
createDefaultNextButtonElement() {
|
|
3381
|
+
const t = document.createElement("button");
|
|
3382
|
+
return t.className = "fbn-ic-nav-btn fbn-ic-nav-btn-next fbn-ic-hidden", t.textContent = "›", t.setAttribute("aria-label", "Next image"), t.setAttribute("tabindex", "-1"), this.containerEl.appendChild(t), t;
|
|
3383
|
+
}
|
|
3329
3384
|
setupEventListeners() {
|
|
3330
3385
|
this.fullConfig.interaction.navigation?.keyboard !== !1 && this.containerEl.addEventListener("keydown", (t) => {
|
|
3331
|
-
t.key === "Escape" ? (this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter()) : t.key === "ArrowRight" ? this.navigateToNextImage() : t.key === "ArrowLeft" ? this.navigateToPreviousImage() : (t.key === "Enter" || t.key === " ") && this.hoveredImage && (this.handleImageClick(this.hoveredImage.element, this.hoveredImage.layout), t.preventDefault());
|
|
3386
|
+
t.key === "Escape" ? (this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter(), this.hideNavButtons(), this.hideFocusIndicator()) : t.key === "ArrowRight" ? this.navigateToNextImage() : t.key === "ArrowLeft" ? this.navigateToPreviousImage() : (t.key === "Enter" || t.key === " ") && this.hoveredImage && (this.handleImageClick(this.hoveredImage.element, this.hoveredImage.layout), t.preventDefault());
|
|
3332
3387
|
}), document.addEventListener("click", (t) => {
|
|
3333
|
-
this.swipeEngine?.hadRecentTouch() || t.target.closest(".fbn-ic-image")
|
|
3388
|
+
this.swipeEngine?.hadRecentTouch() || !t.target.closest(".fbn-ic-image") && !t.target.closest(".fbn-ic-nav-btn") && (this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter(), this.hideNavButtons(), this.hideFocusIndicator());
|
|
3334
3389
|
}), window.addEventListener("resize", () => this.handleResize());
|
|
3335
3390
|
}
|
|
3336
3391
|
/**
|
|
@@ -3339,11 +3394,11 @@ let ni = class {
|
|
|
3339
3394
|
navigateToNextImage() {
|
|
3340
3395
|
if (this.currentFocusIndex === null || this.imageElements.length === 0) return;
|
|
3341
3396
|
const t = (this.currentFocusIndex + 1) % this.imageLayouts.length, i = this.imageElements.find(
|
|
3342
|
-
(
|
|
3397
|
+
(n) => n.dataset.imageId === String(t)
|
|
3343
3398
|
);
|
|
3344
3399
|
if (!i) return;
|
|
3345
3400
|
const e = this.imageLayouts[t];
|
|
3346
|
-
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t));
|
|
3401
|
+
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t), this.showNavButtons(), this.showFocusIndicator());
|
|
3347
3402
|
}
|
|
3348
3403
|
/**
|
|
3349
3404
|
* Navigate to the previous image (Left arrow)
|
|
@@ -3351,11 +3406,11 @@ let ni = class {
|
|
|
3351
3406
|
navigateToPreviousImage() {
|
|
3352
3407
|
if (this.currentFocusIndex === null || this.imageElements.length === 0) return;
|
|
3353
3408
|
const t = (this.currentFocusIndex - 1 + this.imageLayouts.length) % this.imageLayouts.length, i = this.imageElements.find(
|
|
3354
|
-
(
|
|
3409
|
+
(n) => n.dataset.imageId === String(t)
|
|
3355
3410
|
);
|
|
3356
3411
|
if (!i) return;
|
|
3357
3412
|
const e = this.imageLayouts[t];
|
|
3358
|
-
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t));
|
|
3413
|
+
e && (this.currentFocusIndex = t, this.handleImageClick(i, e), this.updateCounter(t), this.showNavButtons(), this.showFocusIndicator());
|
|
3359
3414
|
}
|
|
3360
3415
|
/**
|
|
3361
3416
|
* Navigate to a specific image by index
|
|
@@ -3367,8 +3422,8 @@ let ni = class {
|
|
|
3367
3422
|
}, 500));
|
|
3368
3423
|
}
|
|
3369
3424
|
getImageHeight() {
|
|
3370
|
-
const t = window.innerWidth, i = this.fullConfig.layout.responsive,
|
|
3371
|
-
return i ? t <= i.mobile.maxWidth ? Math.min(100,
|
|
3425
|
+
const t = window.innerWidth, i = this.fullConfig.layout.responsive, n = this.fullConfig.image.sizing?.maxSize ?? 400;
|
|
3426
|
+
return i ? t <= i.mobile.maxWidth ? Math.min(100, n) : t <= i.tablet.maxWidth ? Math.min(180, n) : Math.min(225, n) : t <= 767 ? Math.min(100, n) : t <= 1199 ? Math.min(180, n) : Math.min(225, n);
|
|
3372
3427
|
}
|
|
3373
3428
|
/**
|
|
3374
3429
|
* Get container bounds for layout calculations
|
|
@@ -3391,13 +3446,13 @@ let ni = class {
|
|
|
3391
3446
|
this.showError("No images found."), this.showLoading(!1);
|
|
3392
3447
|
return;
|
|
3393
3448
|
}
|
|
3394
|
-
const e = this.getContainerBounds(),
|
|
3395
|
-
this.logDebug(`Adaptive sizing input: container=${e.width}x${e.height}px, images=${t}, responsiveMax=${
|
|
3449
|
+
const e = this.getContainerBounds(), n = this.getImageHeight(), s = window.innerWidth;
|
|
3450
|
+
this.logDebug(`Adaptive sizing input: container=${e.width}x${e.height}px, images=${t}, responsiveMax=${n}px`);
|
|
3396
3451
|
const r = this.layoutEngine.calculateAdaptiveSize(
|
|
3397
3452
|
e,
|
|
3398
3453
|
t,
|
|
3399
|
-
|
|
3400
|
-
|
|
3454
|
+
n,
|
|
3455
|
+
s
|
|
3401
3456
|
);
|
|
3402
3457
|
this.logDebug(`Adaptive sizing result: height=${r.height}px`), await this.createImageCloud(i, r.height), this.showLoading(!1), this.imagesLoaded = !0;
|
|
3403
3458
|
} catch (t) {
|
|
@@ -3414,33 +3469,33 @@ let ni = class {
|
|
|
3414
3469
|
if (!this.containerEl) return;
|
|
3415
3470
|
const e = this.getContainerBounds();
|
|
3416
3471
|
this.currentImageHeight = i;
|
|
3417
|
-
const
|
|
3418
|
-
this.imageLayouts =
|
|
3472
|
+
const n = this.loadGeneration, s = this.layoutEngine.generateLayout(t.length, e, { fixedHeight: i });
|
|
3473
|
+
this.imageLayouts = s, this.displayQueue = [];
|
|
3419
3474
|
let r = 0;
|
|
3420
|
-
const
|
|
3475
|
+
const a = (l) => {
|
|
3421
3476
|
this.containerEl && (this.containerEl.appendChild(l), this.imageElements.push(l), requestAnimationFrame(() => {
|
|
3422
3477
|
if (l.offsetWidth, l.style.opacity = this.defaultStyles.opacity ?? "1", l.dataset.startX && (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() || l.dataset.startRotation !== l.dataset.rotation || l.dataset.startScale !== l.dataset.scale)) {
|
|
3423
3478
|
const d = {
|
|
3424
3479
|
x: parseFloat(l.dataset.startX),
|
|
3425
3480
|
y: parseFloat(l.dataset.startY)
|
|
3426
|
-
},
|
|
3481
|
+
}, g = {
|
|
3427
3482
|
x: parseFloat(l.dataset.endX),
|
|
3428
3483
|
y: parseFloat(l.dataset.endY)
|
|
3429
|
-
},
|
|
3484
|
+
}, b = parseFloat(l.dataset.imageWidth), p = parseFloat(l.dataset.imageHeight), f = parseFloat(l.dataset.rotation), m = parseFloat(l.dataset.scale), y = l.dataset.startRotation ? parseFloat(l.dataset.startRotation) : f, E = l.dataset.startScale ? parseFloat(l.dataset.startScale) : m, v = this.entryAnimationEngine.getTiming();
|
|
3430
3485
|
me({
|
|
3431
3486
|
element: l,
|
|
3432
3487
|
startPosition: d,
|
|
3433
|
-
endPosition:
|
|
3488
|
+
endPosition: g,
|
|
3434
3489
|
pathConfig: this.entryAnimationEngine.getPathConfig(),
|
|
3435
3490
|
duration: v.duration,
|
|
3436
|
-
imageWidth:
|
|
3491
|
+
imageWidth: b,
|
|
3437
3492
|
imageHeight: p,
|
|
3438
|
-
rotation:
|
|
3493
|
+
rotation: f,
|
|
3439
3494
|
scale: m,
|
|
3440
3495
|
rotationConfig: this.entryAnimationEngine.getRotationConfig(),
|
|
3441
|
-
startRotation:
|
|
3496
|
+
startRotation: y,
|
|
3442
3497
|
scaleConfig: this.entryAnimationEngine.getScaleConfig(),
|
|
3443
|
-
startScale:
|
|
3498
|
+
startScale: E
|
|
3444
3499
|
});
|
|
3445
3500
|
} else {
|
|
3446
3501
|
const d = l.dataset.finalTransform || "";
|
|
@@ -3469,18 +3524,18 @@ let ni = class {
|
|
|
3469
3524
|
if (this.logDebug("Starting queue processing, enabled:", this.fullConfig.animation.queue.enabled), !this.fullConfig.animation.queue.enabled) {
|
|
3470
3525
|
for (; this.displayQueue.length > 0; ) {
|
|
3471
3526
|
const l = this.displayQueue.shift();
|
|
3472
|
-
l &&
|
|
3527
|
+
l && a(l);
|
|
3473
3528
|
}
|
|
3474
3529
|
return;
|
|
3475
3530
|
}
|
|
3476
3531
|
this.queueInterval !== null && clearInterval(this.queueInterval), this.queueInterval = window.setInterval(() => {
|
|
3477
|
-
if (
|
|
3532
|
+
if (n !== this.loadGeneration) {
|
|
3478
3533
|
this.queueInterval !== null && (clearInterval(this.queueInterval), this.queueInterval = null);
|
|
3479
3534
|
return;
|
|
3480
3535
|
}
|
|
3481
3536
|
if (this.displayQueue.length > 0) {
|
|
3482
3537
|
const l = this.displayQueue.shift();
|
|
3483
|
-
l &&
|
|
3538
|
+
l && a(l);
|
|
3484
3539
|
}
|
|
3485
3540
|
r >= t.length && this.displayQueue.length === 0 && this.queueInterval !== null && (clearInterval(this.queueInterval), this.queueInterval = null);
|
|
3486
3541
|
}, this.fullConfig.animation.queue.interval);
|
|
@@ -3494,84 +3549,84 @@ let ni = class {
|
|
|
3494
3549
|
l.observe(this.containerEl);
|
|
3495
3550
|
} else
|
|
3496
3551
|
c();
|
|
3497
|
-
this.fullConfig.config.debug?.centers && this.containerEl && (this.containerEl.querySelectorAll(".fbn-ic-debug-center").forEach((l) => l.remove()),
|
|
3552
|
+
this.fullConfig.config.debug?.centers && this.containerEl && (this.containerEl.querySelectorAll(".fbn-ic-debug-center").forEach((l) => l.remove()), s.forEach((l, u) => {
|
|
3498
3553
|
const h = document.createElement("div");
|
|
3499
3554
|
h.className = "fbn-ic-debug-center", h.style.position = "absolute", h.style.width = "12px", h.style.height = "12px", h.style.borderRadius = "50%", h.style.backgroundColor = "red", h.style.border = "2px solid yellow", h.style.zIndex = "9999", h.style.pointerEvents = "none";
|
|
3500
|
-
const d = l.x,
|
|
3501
|
-
h.style.left = `${d - 6}px`, h.style.top = `${
|
|
3555
|
+
const d = l.x, g = l.y;
|
|
3556
|
+
h.style.left = `${d - 6}px`, h.style.top = `${g - 6}px`, h.title = `Image ${u}: center (${Math.round(d)}, ${Math.round(g)})`, this.containerEl.appendChild(h);
|
|
3502
3557
|
})), t.forEach((l, u) => {
|
|
3503
3558
|
const h = document.createElement("img");
|
|
3504
3559
|
h.referrerPolicy = "no-referrer", h.classList.add("fbn-ic-image"), this.fullConfig.interaction.dragging === !1 && (h.draggable = !1), h.dataset.imageId = String(u), h.dataset.createdFlag = "true";
|
|
3505
|
-
const d =
|
|
3506
|
-
h.style.position = "absolute", h.style.width = "auto", h.style.height = `${i}px`, h.style.left = `${d.x}px`, h.style.top = `${d.y}px`, d.zIndex && (h.style.zIndex = String(d.zIndex)),
|
|
3560
|
+
const d = s[u];
|
|
3561
|
+
h.style.position = "absolute", h.style.width = "auto", h.style.height = `${i}px`, h.style.left = `${d.x}px`, h.style.top = `${d.y}px`, d.zIndex && (h.style.zIndex = String(d.zIndex)), et(h, this.defaultClassName), h.addEventListener("mouseenter", () => {
|
|
3507
3562
|
if (this.hoveredImage = { element: h, layout: d }, !this.zoomEngine.isInvolved(h)) {
|
|
3508
|
-
const
|
|
3509
|
-
|
|
3563
|
+
const g = h.cachedRenderedWidth;
|
|
3564
|
+
st(h, this.fullConfig.styling?.hover, i, g), et(h, this.hoverClassName);
|
|
3510
3565
|
}
|
|
3511
3566
|
}), h.addEventListener("mouseleave", () => {
|
|
3512
3567
|
if (this.hoveredImage = null, !this.zoomEngine.isInvolved(h)) {
|
|
3513
|
-
const
|
|
3514
|
-
|
|
3568
|
+
const g = h.cachedRenderedWidth;
|
|
3569
|
+
st(h, this.fullConfig.styling?.default, i, g), pt(h, this.hoverClassName), et(h, this.defaultClassName);
|
|
3515
3570
|
}
|
|
3516
|
-
}), h.addEventListener("click", (
|
|
3517
|
-
|
|
3571
|
+
}), h.addEventListener("click", (g) => {
|
|
3572
|
+
g.stopPropagation(), this.handleImageClick(h, d);
|
|
3518
3573
|
}), h.style.opacity = "0", h.style.transition = this.entryAnimationEngine.getTransitionCSS(), h.onload = () => {
|
|
3519
|
-
if (
|
|
3574
|
+
if (n !== this.loadGeneration)
|
|
3520
3575
|
return;
|
|
3521
|
-
const
|
|
3522
|
-
h.dataset.onloadCalled = "true", window.DEBUG_CLIPPATH && console.log(`[onload #${u}] Called with imageHeight=${i}, renderedWidth=${
|
|
3523
|
-
const p = { x: d.x, y: d.y },
|
|
3576
|
+
const g = h.naturalWidth / h.naturalHeight, b = i * g;
|
|
3577
|
+
h.dataset.onloadCalled = "true", window.DEBUG_CLIPPATH && console.log(`[onload #${u}] Called with imageHeight=${i}, renderedWidth=${b}`), h.style.width = `${b}px`, h.cachedRenderedWidth = b, h.aspectRatio = g, st(h, this.fullConfig.styling?.default, i, b);
|
|
3578
|
+
const p = { x: d.x, y: d.y }, f = { width: b, height: i }, m = this.entryAnimationEngine.calculateStartPosition(
|
|
3524
3579
|
p,
|
|
3525
|
-
|
|
3580
|
+
f,
|
|
3526
3581
|
e,
|
|
3527
3582
|
u,
|
|
3528
3583
|
t.length
|
|
3529
|
-
),
|
|
3584
|
+
), y = this.entryAnimationEngine.calculateStartRotation(d.rotation), E = this.entryAnimationEngine.calculateStartScale(d.scale), v = this.entryAnimationEngine.buildFinalTransform(
|
|
3530
3585
|
d.rotation,
|
|
3531
3586
|
d.scale,
|
|
3532
|
-
|
|
3587
|
+
b,
|
|
3533
3588
|
i
|
|
3534
3589
|
), S = this.entryAnimationEngine.buildStartTransform(
|
|
3535
3590
|
m,
|
|
3536
3591
|
p,
|
|
3537
3592
|
d.rotation,
|
|
3538
3593
|
d.scale,
|
|
3539
|
-
y,
|
|
3540
|
-
i,
|
|
3541
3594
|
b,
|
|
3542
|
-
|
|
3595
|
+
i,
|
|
3596
|
+
y,
|
|
3597
|
+
E
|
|
3543
3598
|
);
|
|
3544
3599
|
this.fullConfig.config.debug?.enabled && u < 3 && console.log(`Image ${u}:`, {
|
|
3545
3600
|
finalPosition: p,
|
|
3546
|
-
imageSize:
|
|
3601
|
+
imageSize: f,
|
|
3547
3602
|
left: d.x,
|
|
3548
3603
|
top: d.y,
|
|
3549
3604
|
finalTransform: v,
|
|
3550
|
-
renderedWidth:
|
|
3605
|
+
renderedWidth: b,
|
|
3551
3606
|
renderedHeight: i
|
|
3552
|
-
}), h.style.transform = S, h.dataset.finalTransform = v, (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() ||
|
|
3607
|
+
}), h.style.transform = S, h.dataset.finalTransform = v, (this.entryAnimationEngine.requiresJSAnimation() || this.entryAnimationEngine.requiresJSRotation() || this.entryAnimationEngine.requiresJSScale() || y !== d.rotation || E !== d.scale) && (h.dataset.startX = String(m.x), h.dataset.startY = String(m.y), h.dataset.endX = String(p.x), h.dataset.endY = String(p.y), h.dataset.imageWidth = String(b), h.dataset.imageHeight = String(i), h.dataset.rotation = String(d.rotation), h.dataset.scale = String(d.scale), h.dataset.startRotation = String(y), h.dataset.startScale = String(E)), this.displayQueue.push(h);
|
|
3553
3608
|
}, h.onerror = () => r++, h.src = l;
|
|
3554
3609
|
});
|
|
3555
3610
|
}
|
|
3556
3611
|
async handleImageClick(t, i) {
|
|
3557
3612
|
if (!this.containerEl) return;
|
|
3558
|
-
const e = this.zoomEngine.isFocused(t),
|
|
3613
|
+
const e = this.zoomEngine.isFocused(t), n = {
|
|
3559
3614
|
width: this.containerEl.offsetWidth,
|
|
3560
3615
|
height: this.containerEl.offsetHeight
|
|
3561
3616
|
};
|
|
3562
3617
|
if (e)
|
|
3563
|
-
await this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter();
|
|
3618
|
+
await this.zoomEngine.unfocusImage(), this.currentFocusIndex = null, this.swipeEngine?.disable(), this.hideCounter(), this.hideNavButtons(), this.hideFocusIndicator();
|
|
3564
3619
|
else {
|
|
3565
3620
|
this.idleAnimationEngine?.pauseForImage(t);
|
|
3566
|
-
const
|
|
3567
|
-
this.currentFocusIndex =
|
|
3621
|
+
const s = t.dataset.imageId;
|
|
3622
|
+
this.currentFocusIndex = s !== void 0 ? parseInt(s, 10) : null, this.swipeEngine?.enable(), this.containerEl?.focus({ preventScroll: !0 }), await this.zoomEngine.focusImage(t, n, i), this.currentFocusIndex !== null && this.updateCounter(this.currentFocusIndex), this.showNavButtons(), this.showFocusIndicator();
|
|
3568
3623
|
}
|
|
3569
3624
|
}
|
|
3570
3625
|
/**
|
|
3571
3626
|
* Clear the image cloud and reset state
|
|
3572
3627
|
*/
|
|
3573
3628
|
clearImageCloud() {
|
|
3574
|
-
this.queueInterval !== null && (clearInterval(this.queueInterval), this.queueInterval = null), this.loadGeneration++, this.displayQueue = [], this.containerEl && this.containerEl.querySelectorAll(".fbn-ic-image, .fbn-ic-debug-center").forEach((t) => t.remove()), this.imageElements = [], this.imageLayouts = [], this.currentFocusIndex = null, this.hoveredImage = null, this.layoutEngine.reset(), this.zoomEngine.reset(), this.idleAnimationEngine?.stopAll(), this.imagesLoaded = !1;
|
|
3629
|
+
this.queueInterval !== null && (clearInterval(this.queueInterval), this.queueInterval = null), this.loadGeneration++, this.displayQueue = [], this.hideFocusIndicator(), this.containerEl && this.containerEl.querySelectorAll(".fbn-ic-image, .fbn-ic-debug-center").forEach((t) => t.remove()), this.imageElements = [], this.imageLayouts = [], this.currentFocusIndex = null, this.hoveredImage = null, this.layoutEngine.reset(), this.zoomEngine.reset(), this.idleAnimationEngine?.stopAll(), this.imagesLoaded = !1;
|
|
3575
3630
|
}
|
|
3576
3631
|
showLoading(t) {
|
|
3577
3632
|
!this.fullConfig.ui.showLoadingSpinner || !this.loadingEl || (t ? this.loadingEl.classList.remove("fbn-ic-hidden") : this.loadingEl.classList.add("fbn-ic-hidden"));
|
|
@@ -3588,32 +3643,44 @@ let ni = class {
|
|
|
3588
3643
|
hideCounter() {
|
|
3589
3644
|
this.counterEl && this.counterEl.classList.add("fbn-ic-hidden");
|
|
3590
3645
|
}
|
|
3646
|
+
showFocusIndicator() {
|
|
3647
|
+
this.containerEl?.classList.add("fbn-ic-has-focus");
|
|
3648
|
+
}
|
|
3649
|
+
hideFocusIndicator() {
|
|
3650
|
+
this.containerEl?.classList.remove("fbn-ic-has-focus");
|
|
3651
|
+
}
|
|
3652
|
+
showNavButtons() {
|
|
3653
|
+
this.prevButtonEl?.classList.remove("fbn-ic-hidden"), this.nextButtonEl?.classList.remove("fbn-ic-hidden");
|
|
3654
|
+
}
|
|
3655
|
+
hideNavButtons() {
|
|
3656
|
+
this.prevButtonEl?.classList.add("fbn-ic-hidden"), this.nextButtonEl?.classList.add("fbn-ic-hidden");
|
|
3657
|
+
}
|
|
3591
3658
|
/**
|
|
3592
3659
|
* Destroy the gallery and clean up resources
|
|
3593
3660
|
*/
|
|
3594
3661
|
destroy() {
|
|
3595
|
-
this.clearImageCloud(), this.loadingElAutoCreated && this.loadingEl && (this.loadingEl.remove(), this.loadingEl = null), this.errorElAutoCreated && this.errorEl && (this.errorEl.remove(), this.errorEl = null), this.counterElAutoCreated && this.counterEl && (this.counterEl.remove(), this.counterEl = null), this.resizeTimeout !== null && clearTimeout(this.resizeTimeout), this.swipeEngine?.destroy(), this.idleAnimationEngine?.stopAll(), this.idleAnimationEngine = null;
|
|
3662
|
+
this.clearImageCloud(), this.loadingElAutoCreated && this.loadingEl && (this.loadingEl.remove(), this.loadingEl = null), this.errorElAutoCreated && this.errorEl && (this.errorEl.remove(), this.errorEl = null), this.counterElAutoCreated && this.counterEl && (this.counterEl.remove(), this.counterEl = null), this.prevButtonElAutoCreated && this.prevButtonEl && (this.prevButtonEl.remove(), this.prevButtonEl = null), this.nextButtonElAutoCreated && this.nextButtonEl && (this.nextButtonEl.remove(), this.nextButtonEl = null), this.resizeTimeout !== null && clearTimeout(this.resizeTimeout), this.swipeEngine?.destroy(), this.idleAnimationEngine?.stopAll(), this.idleAnimationEngine = null;
|
|
3596
3663
|
}
|
|
3597
3664
|
};
|
|
3598
3665
|
const ci = Nt(
|
|
3599
|
-
function({ className: t, style: i, ...e },
|
|
3600
|
-
const
|
|
3601
|
-
return kt(
|
|
3666
|
+
function({ className: t, style: i, ...e }, n) {
|
|
3667
|
+
const s = It(null), r = It(null);
|
|
3668
|
+
return kt(n, () => ({
|
|
3602
3669
|
get instance() {
|
|
3603
3670
|
return r.current;
|
|
3604
3671
|
}
|
|
3605
|
-
})),
|
|
3606
|
-
if (!
|
|
3607
|
-
const
|
|
3608
|
-
container:
|
|
3672
|
+
})), Bt(() => {
|
|
3673
|
+
if (!s.current) return;
|
|
3674
|
+
const a = new oi({
|
|
3675
|
+
container: s.current,
|
|
3609
3676
|
...e
|
|
3610
3677
|
});
|
|
3611
|
-
return r.current =
|
|
3678
|
+
return r.current = a, a.init().catch((c) => {
|
|
3612
3679
|
console.error("ImageCloud init failed:", c);
|
|
3613
3680
|
}), () => {
|
|
3614
|
-
|
|
3681
|
+
a.destroy(), r.current = null;
|
|
3615
3682
|
};
|
|
3616
|
-
}, [JSON.stringify(e)]), /* @__PURE__ */ Ht("div", { ref:
|
|
3683
|
+
}, [JSON.stringify(e)]), /* @__PURE__ */ Ht("div", { ref: s, className: t, style: i });
|
|
3617
3684
|
}
|
|
3618
3685
|
);
|
|
3619
3686
|
export {
|