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