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