vistaview 0.2.0 → 0.3.2

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/vistaview.js CHANGED
@@ -1,2 +1,680 @@
1
- import { n as DefaultOptions, r as getDownloadButton, t as vistaView } from "./vistaview-D-ZOkDpV.js";
2
- export { DefaultOptions, getDownloadButton, vistaView };
1
+ var k = Object.defineProperty;
2
+ var O = (s, t, e) => t in s ? k(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var f = (s, t, e) => O(s, typeof t != "symbol" ? t + "" : t, e);
4
+ function Z(s) {
5
+ const t = getComputedStyle(s), e = s.getBoundingClientRect();
6
+ return {
7
+ objectFit: t.objectFit,
8
+ borderRadius: t.borderRadius,
9
+ objectPosition: t.objectPosition,
10
+ overflow: t.overflow,
11
+ top: e.top,
12
+ left: e.left,
13
+ width: e.width,
14
+ height: e.height,
15
+ naturalWidth: s.naturalWidth,
16
+ naturalHeight: s.naturalHeight
17
+ };
18
+ }
19
+ let D = null;
20
+ function X() {
21
+ return D || (window.trustedTypes || (window.trustedTypes = {
22
+ createPolicy: (s, t) => t
23
+ }), D = window.trustedTypes.createPolicy("vistaView-policy", {
24
+ createHTML: (s) => s,
25
+ // HTML is generated by us, not user input
26
+ createScript: () => {
27
+ throw new Error("Not implemented");
28
+ },
29
+ createScriptURL: () => {
30
+ throw new Error("Not implemented");
31
+ }
32
+ }), D);
33
+ }
34
+ function T(s) {
35
+ const e = X().createHTML(s), n = document.createElement("template");
36
+ n.innerHTML = e;
37
+ const i = n.content;
38
+ return n.remove(), i;
39
+ }
40
+ function z(s) {
41
+ return s && !/^0(px|%|r?em|vw|vh|vmin|vmax|cm|mm|in|pt|pc|ex|ch)?$/i.test(s.trim()) && s;
42
+ }
43
+ function A(s) {
44
+ const e = window.getComputedStyle(s).objectFit || "", { width: n, height: i } = s.getBoundingClientRect(), o = s.naturalWidth, l = s.naturalHeight;
45
+ if (!e)
46
+ return { width: n, height: i };
47
+ if (!o || !l)
48
+ return { width: n, height: i };
49
+ const a = o / l, r = n / i;
50
+ switch (e) {
51
+ case "fill":
52
+ return { width: n, height: i };
53
+ case "none":
54
+ return { width: o, height: l };
55
+ case "contain":
56
+ return a > r ? { width: n, height: n / a } : { width: i * a, height: i };
57
+ case "cover":
58
+ return a < r ? { width: n, height: n / a } : { width: i * a, height: i };
59
+ case "scale-down": {
60
+ const h = { width: o, height: l }, c = a > r ? { width: n, height: n / a } : { width: i * a, height: i };
61
+ return c.width <= h.width && c.height <= h.height ? c : h;
62
+ }
63
+ }
64
+ return { width: n, height: i };
65
+ }
66
+ function P(s) {
67
+ const t = window.innerWidth, e = window.innerHeight, n = s.naturalWidth, i = s.naturalHeight;
68
+ if (!n || !i)
69
+ throw console.error("Error", s), new Error("Image natural dimensions are zero");
70
+ if (n < t && i < e)
71
+ return {
72
+ width: n,
73
+ height: i
74
+ };
75
+ const o = n / i, l = t / e;
76
+ let a, r;
77
+ return o > l ? (a = t, r = t / o) : (r = e, a = e * o), {
78
+ width: a,
79
+ height: r
80
+ };
81
+ }
82
+ function R(s, t) {
83
+ const e = window.innerHeight, n = window.innerWidth, i = s, o = t, l = Math.max(0, (i - n) / 2) + n / 2, a = Math.max(0, (o - e) / 2) + e / 2, r = -l, h = -a;
84
+ return {
85
+ maxDiffX: l,
86
+ minDiffY: h,
87
+ maxDiffY: a,
88
+ minDiffX: r
89
+ };
90
+ }
91
+ const _ = '<svg viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></svg>', B = '<svg viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></svg>', F = '<svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="11" x2="11" y1="8" y2="14"/><line x1="8" x2="14" y1="11" y2="11"/></svg>', V = '<svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" x2="16.65" y1="21" y2="16.65"/><line x1="8" x2="14" y1="11" y2="11"/></svg>', Y = '<svg viewBox="0 0 24 24"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>', U = '<svg viewBox="0 0 24 24"><path d="M12 15V3"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="m7 10 5 5 5-5"/></svg>';
92
+ function N() {
93
+ return {
94
+ name: "download",
95
+ icon: U,
96
+ onClick: async (s) => {
97
+ var o;
98
+ const t = await fetch(s.src), e = await t.blob(), n = t.url, i = document.createElement("a");
99
+ i.href = URL.createObjectURL(e), i.download = ((o = n.split("/").pop()) == null ? void 0 : o.split("?")[0].split("#")[0]) || "download", document.body.appendChild(i), i.click(), document.body.removeChild(i);
100
+ }
101
+ };
102
+ }
103
+ function j(s) {
104
+ if (typeof s == "string")
105
+ switch (s) {
106
+ case "zoomIn":
107
+ return `<button class="vistaview-zoom-in-btn">${F}</button>`;
108
+ case "zoomOut":
109
+ return `<button disabled class="vistaview-zoom-out-btn">${V}</button>`;
110
+ case "close":
111
+ return `<button class="vistaview-close-btn">${Y}</button>`;
112
+ case "indexDisplay":
113
+ return '<div class="vistaview-index-display"></div>';
114
+ case "description":
115
+ return '<div class="vistaview-description"></div>';
116
+ default:
117
+ return "";
118
+ }
119
+ return `<button data-vistaview-custom-control="${s.name}">${s.icon}</button>`;
120
+ }
121
+ function H(s, t) {
122
+ var c, d;
123
+ const e = s.imageElm ? getComputedStyle(s.imageElm) : null, n = (e == null ? void 0 : e.objectFit) || "", i = ((c = s.imageElm) == null ? void 0 : c.naturalWidth) || "", o = ((d = s.imageElm) == null ? void 0 : d.naturalHeight) || "", l = (e == null ? void 0 : e.width) || "", a = (e == null ? void 0 : e.height) || "", r = document.createElement("div");
124
+ r.className = "vistaview-item", r.dataset.vistaviewPos = `${t !== void 0 ? t : ""}`, r.dataset.vistaviewIndex = s.index.toString();
125
+ const h = T(`<img class="vistaview-image-lowres"
126
+ style="${n ? `object-fit:${n};` : ""}${l ? `width:${l};` : ""}${a ? `height:${a};` : ""}"
127
+ src="${s.thumb || s.src}"
128
+ alt="${s.alt || ""}"
129
+ ${i ? `width="${i}"` : ""}
130
+ ${o ? `height="${o}"` : ""}
131
+ />
132
+ <img class="vistaview-image-highres" src="${s.src}" alt="${s.alt || ""}" />`);
133
+ return r.appendChild(h), r;
134
+ }
135
+ function K({
136
+ controls: s,
137
+ isReducedMotion: t
138
+ }) {
139
+ const e = (i) => i ? i.map(j).join("") : "";
140
+ return T(
141
+ `<div class="vistaview-root${t ? " vistaview--reduced-motion" : ""}" id="vistaview-root">
142
+ <div class="vistaview-container">
143
+ <div class="vistaview-image-container"></div>
144
+ <div class="vistaview-top-bar vistaview-ui"><div>${e(s == null ? void 0 : s.topLeft)}</div><div>${e(s == null ? void 0 : s.topCenter)}</div><div>${e(s == null ? void 0 : s.topRight)}</div></div>
145
+ <div class="vistaview-bottom-bar vistaview-ui"><div>${e(s == null ? void 0 : s.bottomLeft)}</div><div>${e(s == null ? void 0 : s.bottomCenter)}</div><div>${e(s == null ? void 0 : s.bottomRight)}</div></div>
146
+ <div class="vistaview-prev-btn vistaview-ui"><button>${_}</button></div>
147
+ <div class="vistaview-next-btn vistaview-ui"><button>${B}</button></div>
148
+ </div>
149
+ </div>`
150
+ );
151
+ }
152
+ let $ = null, S = null, M = null;
153
+ function G(s) {
154
+ q(s);
155
+ const t = s.imageContainerElm, e = s.elements.length;
156
+ if (!t) return;
157
+ let n = 0, i = 0, o = 0, l = 0, a = !1;
158
+ $ = (r) => {
159
+ r.preventDefault(), r.stopPropagation(), s.isZoomed === !1 && (a = !0, n = r.pageX, i = r.pageY, o = r.pageX, l = Date.now());
160
+ }, S = (r) => {
161
+ if (r.preventDefault(), r.stopPropagation(), s.isZoomed !== !1 || !a) return;
162
+ const h = r.pageX - n, c = r.pageY - i;
163
+ o = r.pageX, t.style.setProperty("--vistaview-pointer-diff-x", `${h}px`), t.style.setProperty("--vistaview-pointer-diff-y", `${c}px`);
164
+ }, M = (r) => {
165
+ if (r.preventDefault(), r.stopPropagation(), s.isZoomed !== !1 || !a) return;
166
+ a = !1;
167
+ const h = Array.from(t.querySelectorAll(".vistaview-item")), c = o - n, d = Date.now() - l, v = c / d, u = s.options.touchSpeedThreshold || 0.7, g = h.find(
168
+ (p) => p.dataset.vistaviewPos === "0"
169
+ ), m = Number(g.dataset.vistaviewIndex), E = s.isReducedMotion;
170
+ function w() {
171
+ h[0].removeEventListener("transitionend", w), t.style.removeProperty("--vistaview-pointer-diff-x"), t.style.removeProperty("--vistaview-pointer-diff-y"), h.forEach((p) => {
172
+ p.style.transition = "", p.style.translate = "";
173
+ });
174
+ }
175
+ function y(p) {
176
+ h.forEach((x) => {
177
+ x.style.transition = `translate ${s.options.animationDurationBase * 0.5}ms ease-out`, x.style.translate = p;
178
+ });
179
+ }
180
+ v < -u || v > u ? (h[0].addEventListener("transitionend", () => {
181
+ s.isReducedMotion = !0, w(), s.view(
182
+ v < -u ? (m + 1) % e : (m - 1 + e) % e,
183
+ {
184
+ next: v < -u,
185
+ prev: v > u
186
+ }
187
+ ), s.isReducedMotion = E;
188
+ }), y(v < -u ? "-100%" : "100%")) : (h[0].addEventListener("transitionend", w), y("0%"));
189
+ }, t.addEventListener("pointermove", S), t.addEventListener("pointerup", M), t.addEventListener("pointerdown", $);
190
+ }
191
+ function q(s) {
192
+ const t = s.imageContainerElm;
193
+ t && (S && t.removeEventListener("pointermove", S), M && t.removeEventListener("pointerup", M), $ && t.removeEventListener("pointerdown", $));
194
+ }
195
+ const J = (s) => {
196
+ G(s);
197
+ }, Q = ({
198
+ htmlElements: { to: s },
199
+ index: { to: t },
200
+ elements: e
201
+ }) => {
202
+ e instanceof NodeList && t !== null && (e.forEach((n) => n.style.opacity = "1"), e[t].style.opacity = "0"), s && s.forEach((n) => {
203
+ const i = Number(n.dataset.vistaviewPos);
204
+ i !== 0 ? (n.style.zIndex = "1", n.style.left = 100 * i + "%") : n.style.zIndex = "2";
205
+ });
206
+ }, tt = async ({
207
+ htmlElements: { from: s, to: t },
208
+ images: { to: e },
209
+ via: { next: n, prev: i },
210
+ container: o,
211
+ options: l,
212
+ isReducedMotion: a
213
+ // index: { from: fromIndex, to: toIndex },
214
+ }) => {
215
+ if (!e) throw new Error("VistaView: images is null in defaultTransition()");
216
+ if (a)
217
+ return o.innerHTML = "", t.forEach((h) => {
218
+ o.appendChild(h);
219
+ }), e[e.length === 1 ? 0 : Math.floor(e.length / 2)];
220
+ const r = s.filter((h) => h.dataset.vistaviewPos === "0" || (n ? h.dataset.vistaviewPos === "1" : h.dataset.vistaviewPos === "-1"));
221
+ return await new Promise((h) => {
222
+ function c() {
223
+ o.innerHTML = "", t.forEach((d) => {
224
+ o.appendChild(d);
225
+ }), h(0);
226
+ }
227
+ r[r.length - 1].addEventListener("transitionend", c), r.forEach((d) => {
228
+ d.style.transition = `translate ${l.animationDurationBase * 0.5}ms ease-out`, d.style.translate = n ? "-100%" : i ? "100%" : "0%";
229
+ });
230
+ }), e[e.length === 1 ? 0 : Math.floor(e.length / 2)];
231
+ }, et = (s) => {
232
+ s.elements instanceof NodeList && s.elements.forEach((t) => t.style.opacity = "1"), q(s);
233
+ }, W = {
234
+ detectReducedMotion: !0,
235
+ // debug, don't remove
236
+ // animationDurationBase: 1000,
237
+ animationDurationBase: 333,
238
+ zoomStep: 500,
239
+ maxZoomLevel: 2,
240
+ touchSpeedThreshold: 0.7,
241
+ preloads: 1,
242
+ keyboardListeners: !0,
243
+ controls: {
244
+ topLeft: ["indexDisplay"],
245
+ topRight: ["zoomIn", "zoomOut", N(), "close"],
246
+ bottomCenter: ["description"]
247
+ }
248
+ }, b = {
249
+ somethingOpened: null
250
+ };
251
+ class it {
252
+ constructor(t, e) {
253
+ f(this, "options");
254
+ f(this, "elements");
255
+ f(this, "isReducedMotion");
256
+ f(this, "currentIndex", {
257
+ _value: null,
258
+ _vistaView: null,
259
+ _via: { next: !1, prev: !1 },
260
+ set value(t) {
261
+ var n;
262
+ const e = this._value;
263
+ this._value = t, (n = this._vistaView) == null || n.swap(e, this._value);
264
+ },
265
+ get value() {
266
+ return this._value;
267
+ },
268
+ get via() {
269
+ return this._via;
270
+ },
271
+ set via(t) {
272
+ this._via = t;
273
+ }
274
+ });
275
+ f(this, "rootElm", null);
276
+ f(this, "imageContainerElm", null);
277
+ f(this, "customControls", {});
278
+ f(this, "currentImages", null);
279
+ f(this, "currentItems", null);
280
+ f(this, "navActive", !0);
281
+ f(this, "isZoomed", !1);
282
+ f(this, "onClickElements", []);
283
+ f(this, "onResizeHandler", null);
284
+ f(this, "onKeyDown", null);
285
+ f(this, "userSetup", Q);
286
+ f(this, "userTransition", tt);
287
+ f(this, "userClose", et);
288
+ f(this, "userInit", J);
289
+ f(this, "onZoomedPointerDown", null);
290
+ f(this, "onZoomedPointerMove", null);
291
+ f(this, "onZoomedPointerUp", null);
292
+ this.elements = t, this.currentIndex._vistaView = this, this.options = {
293
+ ...W,
294
+ ...e || {},
295
+ controls: {
296
+ ...W.controls,
297
+ ...(e == null ? void 0 : e.controls) || {}
298
+ }
299
+ }, this.options.initFunction && (this.userInit = this.options.initFunction), this.options.transitionFunction && (this.userTransition = this.options.transitionFunction), this.options.closeFunction && (this.userClose = this.options.closeFunction), this.options.initFunction && (this.userInit = this.options.initFunction), this.isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches, this.elements instanceof NodeList && this.elements.forEach((n, i) => {
300
+ this.onClickElements.push((o) => {
301
+ o.preventDefault(), this.open(i);
302
+ }), n.addEventListener("click", this.onClickElements[i]);
303
+ });
304
+ }
305
+ async swap(t, e) {
306
+ var h, c;
307
+ if (!b.somethingOpened || t === e || t === null || this.elements.length === 1) return;
308
+ if (!this.imageContainerElm)
309
+ throw new Error("VistaView: imageContainerElm is null in swap()");
310
+ this.setIndexDisplay(), this.clearZoom();
311
+ const { images: n, positions: i } = this.getCurrentIndexes(e), o = this.getImages(n), l = o.map((d, v) => H(d, i[v]));
312
+ l.forEach((d, v) => {
313
+ var m, E;
314
+ const u = d.querySelector(".vistaview-image-highres"), g = o[v].imageElm;
315
+ if (u.complete && u.naturalWidth > 0) {
316
+ const { width: w, height: y } = A(g);
317
+ w && y && (u.style.setProperty("--vistaview-fitted-width", `${w}px`), u.style.setProperty("--vistaview-fitted-height", `${y}px`)), u.classList.add("vistaview-image-loaded"), (m = d.querySelector(".vistaview-image-lowres")) == null || m.classList.add("vistaview-image--hidden");
318
+ const { width: p, height: x } = P(u);
319
+ u.style.width = `${p}px`, u.style.height = `${x}px`, u.width = u.naturalWidth, u.height = u.naturalHeight, (E = u.parentElement) != null && E.matches('[data-vistaview-pos="0"]') && this.updateZoomButtonsVisibility();
320
+ }
321
+ }), this.navActive = !1;
322
+ const a = {
323
+ htmlElements: { from: this.currentItems, to: l },
324
+ images: { from: this.currentImages, to: o },
325
+ index: { from: t, to: e },
326
+ via: this.currentIndex.via,
327
+ container: this.imageContainerElm,
328
+ elements: this.elements,
329
+ isReducedMotion: this.isReducedMotion,
330
+ navActive: this.navActive,
331
+ isZoomed: this.isZoomed,
332
+ options: this.options
333
+ };
334
+ this.userSetup(a);
335
+ const r = await this.userTransition(a);
336
+ this.navActive = !0, this.setInitialDimPos(r), this.currentImages = o, this.currentItems = l, this.loadImages(), this.setCurrentDescription(), (c = (h = this.options).onImageView) == null || c.call(h, a);
337
+ }
338
+ //
339
+ setZoomed(t) {
340
+ var e, n, i, o, l, a;
341
+ if (this.isZoomed !== t) {
342
+ if (this.isZoomed) {
343
+ let r = this.isZoomed;
344
+ if (r.classList.remove("vistaview-image--zooming"), this.onZoomedPointerDown && ((e = r.parentElement) == null || e.removeEventListener("pointerdown", this.onZoomedPointerDown), this.onZoomedPointerDown = null), this.onZoomedPointerMove && ((n = r.parentElement) == null || n.removeEventListener("pointermove", this.onZoomedPointerMove), this.onZoomedPointerMove = null), this.onZoomedPointerUp && ((i = r.parentElement) == null || i.removeEventListener("pointerup", this.onZoomedPointerUp), this.onZoomedPointerUp = null), r == null || r.style.removeProperty("--pointer-diff-x"), r == null || r.style.removeProperty("--pointer-diff-y"), setTimeout(() => {
345
+ r == null || r.classList.remove("vistaview-image--zooming");
346
+ }, 500), this.isZoomed = !1, !t) return;
347
+ }
348
+ if (t) {
349
+ this.isZoomed = t, t.classList.add("vistaview-image--zooming"), t == null || t.style.setProperty("--pointer-diff-x", "0px"), t == null || t.style.setProperty("--pointer-diff-y", "0px");
350
+ let r = !1, h = 0, c = 0, d = 0, v = 0, u = 0, g = 0;
351
+ this.onZoomedPointerDown = (m) => {
352
+ m.preventDefault(), m.stopPropagation(), r = !0, h = m.pageX, c = m.pageY, t.setPointerCapture(m.pointerId);
353
+ }, this.onZoomedPointerMove = (m) => {
354
+ if (!r) return;
355
+ m.preventDefault(), u = m.pageX - h, g = m.pageY - c;
356
+ const E = parseInt((t == null ? void 0 : t.dataset.vistaviewCurrentWidth) || "0"), w = parseInt((t == null ? void 0 : t.dataset.vistaviewCurrentHeight) || "0"), { maxDiffX: y, minDiffY: p, maxDiffY: x, minDiffX: I } = R(
357
+ E,
358
+ w
359
+ ), L = Math.min(y, Math.max(I, d + u)), C = Math.min(x, Math.max(p, v + g));
360
+ u = L - d, g = C - v, t == null || t.style.setProperty("--pointer-diff-x", `${L}px`), t == null || t.style.setProperty("--pointer-diff-y", `${C}px`);
361
+ }, this.onZoomedPointerUp = (m) => {
362
+ r = !1, t.releasePointerCapture(m.pointerId), d += u, v += g, u = 0, g = 0;
363
+ }, (o = t == null ? void 0 : t.parentElement) == null || o.addEventListener("pointerdown", this.onZoomedPointerDown), (l = t == null ? void 0 : t.parentElement) == null || l.addEventListener("pointermove", this.onZoomedPointerMove), (a = t == null ? void 0 : t.parentElement) == null || a.addEventListener("pointerup", this.onZoomedPointerUp);
364
+ return;
365
+ }
366
+ }
367
+ }
368
+ zoomIn() {
369
+ var o, l, a, r, h;
370
+ const t = (o = this.rootElm) == null ? void 0 : o.querySelector(
371
+ '[data-vistaview-pos="0"] .vistaview-image-highres'
372
+ ), e = t.width, n = t.height;
373
+ t.dataset.vistaviewInitialWidth || (t.dataset.vistaviewInitialWidth = e.toString()), t.dataset.vistaviewInitialHeight || (t.dataset.vistaviewInitialHeight = n.toString()), this.setZoomed(t);
374
+ const i = (t.naturalWidth || 0) * this.options.maxZoomLevel;
375
+ if (e && i && e < i) {
376
+ const c = Math.min(e + this.options.zoomStep, i);
377
+ t.style.width = `${c}px`;
378
+ const d = c / e * n;
379
+ t.style.height = `${d}px`, (a = (l = this.rootElm) == null ? void 0 : l.querySelector("button.vistaview-zoom-out-btn")) == null || a.removeAttribute("disabled"), t.dataset.vistaviewCurrentWidth = c.toString(), t.dataset.vistaviewCurrentHeight = d.toString(), c === i && ((h = (r = this.rootElm) == null ? void 0 : r.querySelector("button.vistaview-zoom-in-btn")) == null || h.setAttribute("disabled", "true"));
380
+ }
381
+ }
382
+ zoomOut() {
383
+ var l, a, r, h, c;
384
+ const t = (l = this.rootElm) == null ? void 0 : l.querySelector(
385
+ '[data-vistaview-pos="0"] .vistaview-image-highres'
386
+ ), e = t.width, n = t.height, i = t.dataset.vistaviewInitialWidth ? parseInt(t.dataset.vistaviewInitialWidth) : 0, o = (d) => {
387
+ d.target === t && (t.classList.remove("vistaview-image--zooming-out"), t.removeEventListener("transitionend", o));
388
+ };
389
+ if (t.addEventListener("transitionend", o), t.classList.add("vistaview-image--zooming-out"), e && i && e > i) {
390
+ const d = Math.max(e - this.options.zoomStep, i);
391
+ t.style.width = `${d}px`;
392
+ const v = d / e * n;
393
+ t.style.height = `${v}px`, (r = (a = this.rootElm) == null ? void 0 : a.querySelector("button.vistaview-zoom-in-btn")) == null || r.removeAttribute("disabled"), t.dataset.vistaviewCurrentWidth = d.toString(), t.dataset.vistaviewCurrentHeight = v.toString();
394
+ const { maxDiffX: u, minDiffY: g, maxDiffY: m, minDiffX: E } = R(d, v);
395
+ let w = parseInt(
396
+ (t == null ? void 0 : t.style.getPropertyValue("--pointer-diff-x").replace("px", "")) || "0"
397
+ ), y = parseInt(
398
+ (t == null ? void 0 : t.style.getPropertyValue("--pointer-diff-y").replace("px", "")) || "0"
399
+ );
400
+ w = Math.min(u, Math.max(E, w)), y = Math.min(m, Math.max(g, y)), t == null || t.style.setProperty("--pointer-diff-x", `${w}px`), t == null || t.style.setProperty("--pointer-diff-y", `${y}px`), d === i && ((c = (h = this.rootElm) == null ? void 0 : h.querySelector("button.vistaview-zoom-out-btn")) == null || c.setAttribute("disabled", "true"), t.removeAttribute("data-vistaview-current-width"), t.removeAttribute("data-vistaview-current-height"), t.removeAttribute("data-vistaview-initial-width"), t.removeAttribute("data-vistaview-initial-height"), this.setZoomed(!1));
401
+ }
402
+ }
403
+ clearZoom() {
404
+ }
405
+ getImages(t) {
406
+ return t.map((e, n) => {
407
+ const i = this.elements[e];
408
+ if (i instanceof HTMLElement) {
409
+ const o = i.querySelector("img"), l = i.getAttribute("href") || "", a = i.getAttribute("src") || "", r = i.dataset.vistaviewSrc || l || a || (o == null ? void 0 : o.src) || "", h = i.dataset.vistaviewAlt || i.getAttribute("alt") || (o == null ? void 0 : o.alt) || "", c = i.dataset.vistaviewThumb || (o == null ? void 0 : o.src) || l || a || "";
410
+ return {
411
+ index: t[n],
412
+ src: r,
413
+ alt: h,
414
+ thumb: c,
415
+ imageElm: i instanceof HTMLImageElement ? i : o,
416
+ anchorElm: i instanceof HTMLAnchorElement ? i : void 0
417
+ };
418
+ } else
419
+ return { index: t[n], ...i };
420
+ });
421
+ }
422
+ setInitialDimPos(t) {
423
+ if (!this.rootElm) return;
424
+ const e = t.imageElm ? Z(t.imageElm) : void 0, n = t.anchorElm ? Z(t.anchorElm) : void 0, i = (n == null ? void 0 : n.width) || (e == null ? void 0 : e.width) || 0, o = (n == null ? void 0 : n.height) || (e == null ? void 0 : e.height) || 0, l = ((n == null ? void 0 : n.left) || (e == null ? void 0 : e.left) || 0) + i / 2, a = ((n == null ? void 0 : n.top) || (e == null ? void 0 : e.top) || 0) + o / 2;
425
+ this.rootElm.style.setProperty("--vistaview-container-initial-width", i + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-height", o + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-top", a + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-left", l + "px"), this.rootElm.style.setProperty(
426
+ "--vistaview-image-border-radius",
427
+ z(n == null ? void 0 : n.borderRadius) || z(e == null ? void 0 : e.borderRadius) || "0px"
428
+ );
429
+ }
430
+ updateZoomButtonsVisibility() {
431
+ var i;
432
+ const t = (i = this.rootElm) == null ? void 0 : i.querySelector(
433
+ '[data-vistaview-pos="0"] img.vistaview-image-highres'
434
+ );
435
+ if (!t) return;
436
+ const e = this;
437
+ function n() {
438
+ var c, d;
439
+ const o = (c = e.rootElm) == null ? void 0 : c.querySelector(
440
+ "button.vistaview-zoom-in-btn"
441
+ ), l = (d = e.rootElm) == null ? void 0 : d.querySelector(
442
+ "button.vistaview-zoom-out-btn"
443
+ ), a = parseInt(t.style.width) || t.width, r = t.naturalWidth * e.options.maxZoomLevel, h = a < r && r > 0;
444
+ o && (o.style.display = h ? "" : "none"), l && (l.style.display = h ? "" : "none");
445
+ }
446
+ t.complete && t.naturalWidth > 0 ? n() : t.addEventListener("load", n);
447
+ }
448
+ loadImages() {
449
+ if (!this.rootElm) return;
450
+ this.rootElm.querySelectorAll(
451
+ ".vistaview-image-highres:not(.vistaview-image-loaded)"
452
+ ).forEach((e, n) => {
453
+ const i = e, l = this.currentImages[n].imageElm, a = { w: 0, h: 0 };
454
+ if (l) {
455
+ const { width: h, height: c } = A(l);
456
+ a.w = Math.min(l.width, h), a.h = Math.min(l.height, c);
457
+ }
458
+ const r = (h = !1) => () => {
459
+ var c;
460
+ if (a.w && a.h && (i.style.width = `${a.w}px`, i.style.height = `${a.h}px`, i.style.setProperty("--vistaview-fitted-width", `${a.w}px`), i.style.setProperty("--vistaview-fitted-height", `${a.h}px`)), i.classList.add("vistaview-image-loaded"), i.width = i.naturalWidth, i.height = i.naturalHeight, h) {
461
+ const { width: d, height: v } = P(i);
462
+ i.style.width = `${d}px`, i.style.height = `${v}px`;
463
+ } else
464
+ setTimeout(() => {
465
+ const { width: d, height: v } = P(i);
466
+ i.style.width = `${d}px`, i.style.height = `${v}px`;
467
+ }, 333);
468
+ setTimeout(() => {
469
+ var d, v;
470
+ (v = (d = i.parentElement) == null ? void 0 : d.querySelector(".vistaview-image-lowres")) == null || v.classList.add("vistaview-image--hidden");
471
+ }, 500), (c = e.parentElement) != null && c.matches('[data-vistaview-pos="0"]') && this.updateZoomButtonsVisibility();
472
+ };
473
+ i.complete && i.naturalWidth > 0 ? r(!0)() : i.onload = r(!1);
474
+ });
475
+ }
476
+ setIndexDisplay() {
477
+ this.elements.length !== 1 && (this.rootElm.querySelector(".vistaview-index-display").textContent = `${this.currentIndex.value + 1} / ${this.elements.length}`);
478
+ }
479
+ setCurrentDescription() {
480
+ this.rootElm.querySelector(".vistaview-description").textContent = (this.currentImages[1] || this.currentImages[0]).alt || "";
481
+ }
482
+ getCurrentIndexes(t) {
483
+ const e = this.options.preloads, n = this.elements.length, i = n < 1 || !e ? [t] : [
484
+ .../* @__PURE__ */ new Set([
485
+ ...Array.from(
486
+ { length: e },
487
+ (l, a) => ((t - e + a) % n + n) % n
488
+ ),
489
+ t,
490
+ ...Array.from({ length: e }, (l, a) => (t + 1 + a) % n)
491
+ ])
492
+ ], o = n < 1 || !e ? [0] : i.map((l, a) => a - Math.floor(i.length / 2));
493
+ return {
494
+ images: i,
495
+ positions: o
496
+ };
497
+ }
498
+ setKeyboardListeners() {
499
+ this.onKeyDown = (t) => {
500
+ switch (t.key) {
501
+ case "ArrowLeft":
502
+ t.preventDefault(), this.prev();
503
+ break;
504
+ case "ArrowRight":
505
+ t.preventDefault(), this.next();
506
+ break;
507
+ case "ArrowUp":
508
+ t.preventDefault(), this.zoomIn();
509
+ break;
510
+ case "ArrowDown":
511
+ t.preventDefault(), this.zoomOut();
512
+ break;
513
+ case "Escape":
514
+ t.preventDefault(), this.close();
515
+ break;
516
+ }
517
+ }, window.addEventListener("keydown", this.onKeyDown);
518
+ }
519
+ setResizeListeners() {
520
+ this.onResizeHandler = () => {
521
+ var n;
522
+ const t = this.currentImages[this.currentImages.length === 1 ? 0 : Math.floor(this.currentImages.length / 2)];
523
+ this.setInitialDimPos(t);
524
+ const e = (n = this.rootElm) == null ? void 0 : n.querySelectorAll(
525
+ ".vistaview-image-highres.vistaview-image-loaded"
526
+ );
527
+ e == null || e.forEach((i) => {
528
+ const o = i, { width: l, height: a } = P(o);
529
+ o.classList.contains("vistaview-image--zooming") ? (o.dataset.vistaviewInitialWidth = l.toString(), o.dataset.vistaviewInitialHeight = a.toString()) : (o.style.width = `${l}px`, o.style.height = `${a}px`);
530
+ });
531
+ }, window.addEventListener("resize", this.onResizeHandler);
532
+ }
533
+ open(t = 0) {
534
+ var l, a, r, h, c, d, v, u, g, m, E, w, y;
535
+ if (b.somethingOpened) {
536
+ console.error("VistaView: another instance is already opened. Returning.");
537
+ return;
538
+ }
539
+ if (b.somethingOpened = this, this.currentIndex._value = t, document.body.prepend(
540
+ K({
541
+ controls: this.options.controls,
542
+ isReducedMotion: this.isReducedMotion
543
+ })
544
+ ), this.rootElm = document.querySelector("#vistaview-root"), this.imageContainerElm = ((l = this.rootElm) == null ? void 0 : l.querySelector(".vistaview-image-container")) || null, !this.rootElm || !this.imageContainerElm)
545
+ throw b.somethingOpened = null, new Error("Failed to create VistaView element");
546
+ const { images: e, positions: n } = this.getCurrentIndexes(t);
547
+ this.currentImages = this.getImages(e);
548
+ const i = this.currentImages.map((p, x) => H(p, n[x]));
549
+ this.currentItems = i;
550
+ const o = {
551
+ htmlElements: { from: null, to: this.currentItems },
552
+ images: { from: null, to: this.currentImages },
553
+ index: { from: null, to: t },
554
+ via: this.currentIndex.via,
555
+ container: this.imageContainerElm,
556
+ elements: this.elements,
557
+ isReducedMotion: this.isReducedMotion,
558
+ navActive: this.navActive,
559
+ isZoomed: this.isZoomed,
560
+ options: this.options
561
+ };
562
+ this.userSetup(o), this.imageContainerElm.innerHTML = "", this.currentItems.forEach((p) => {
563
+ this.imageContainerElm.appendChild(p);
564
+ }), (a = this.rootElm.querySelector(".vistaview-close-btn")) == null || a.addEventListener("click", () => this.close()), (r = this.rootElm.querySelector(".vistaview-zoom-in-btn")) == null || r.addEventListener("click", () => this.zoomIn()), (h = this.rootElm.querySelector(".vistaview-zoom-out-btn")) == null || h.addEventListener("click", () => this.zoomOut()), (c = this.rootElm.querySelector(".vistaview-prev-btn>button")) == null || c.addEventListener("click", () => this.prev()), (d = this.rootElm.querySelector(".vistaview-next-btn>button")) == null || d.addEventListener("click", () => this.next()), [
565
+ ...this.options.controls.topLeft || [],
566
+ ...this.options.controls.topRight || [],
567
+ ...this.options.controls.topCenter || [],
568
+ ...this.options.controls.bottomCenter || [],
569
+ ...this.options.controls.bottomLeft || [],
570
+ ...this.options.controls.bottomRight || []
571
+ ].forEach((p) => {
572
+ typeof p != "string" && (this.customControls[p.name] = p);
573
+ }), this.rootElm.querySelectorAll("button[data-vistaview-custom-control]").forEach((p) => {
574
+ p.addEventListener("click", (x) => {
575
+ const I = this.customControls[x.currentTarget.dataset.vistaviewCustomControl], L = this.currentImages.find(
576
+ (C) => C.index === this.currentIndex.value
577
+ );
578
+ I && L && (I.onClick.constructor.name === "AsyncFunction" ? (p.classList.add("vistaview-button--loading"), I.onClick(L).finally(() => {
579
+ p.classList.remove("vistaview-button--loading");
580
+ })) : I.onClick(L));
581
+ });
582
+ }), this.options.animationDurationBase && this.rootElm.style.setProperty(
583
+ "--vistaview-animation-duration",
584
+ `${this.options.animationDurationBase}`
585
+ ), this.options.initialZIndex !== void 0 && this.rootElm.style.setProperty(
586
+ "--vistaview-initial-z-index",
587
+ `${this.options.initialZIndex}`
588
+ ), this.setInitialDimPos(
589
+ this.currentImages[this.currentImages.length === 1 ? 0 : Math.floor(this.currentImages.length / 2)]
590
+ ), this.setResizeListeners(), this.options.keyboardListeners && this.setKeyboardListeners(), this.elements.length === 1 && ((v = this.rootElm.querySelector(".vistaview-prev-btn")) == null || v.classList.add("vistaview-ui--none"), (u = this.rootElm.querySelector(".vistaview-next-btn")) == null || u.classList.add("vistaview-ui--none"), (g = this.rootElm.querySelector(".vistaview-index-display")) == null || g.classList.add("vistaview-ui--none")), this.rootElm && this.rootElm.classList.add("vistaview--initialized"), this.loadImages(), this.setCurrentDescription(), this.setIndexDisplay(), this.userInit(this), (E = (m = this.options).onOpen) == null || E.call(m, o), (y = (w = this.options).onImageView) == null || y.call(w, o);
591
+ }
592
+ async close(t = !0) {
593
+ var n, i, o;
594
+ if (b.somethingOpened !== this) return;
595
+ t && ((n = this.rootElm) == null || n.classList.add("vistaview--closing"), await new Promise((l) => {
596
+ var r;
597
+ let a;
598
+ (r = this.rootElm) == null || r.addEventListener("transitionend", (h) => {
599
+ h.currentTarget === this.rootElm && (a && clearTimeout(a), a = setTimeout(() => {
600
+ l();
601
+ }, 333));
602
+ });
603
+ }));
604
+ const e = {
605
+ htmlElements: { from: this.currentItems, to: null },
606
+ images: { from: this.currentImages, to: null },
607
+ index: { from: this.currentIndex.value, to: null },
608
+ container: this.imageContainerElm,
609
+ elements: this.elements,
610
+ via: { prev: !1, next: !1 },
611
+ isReducedMotion: this.isReducedMotion,
612
+ navActive: this.navActive,
613
+ isZoomed: this.isZoomed,
614
+ options: this.options
615
+ };
616
+ this.userClose(this), (o = (i = this.options).onClose) == null || o.call(i, e), document.body.removeChild(this.rootElm), this.currentIndex._value = null, this.currentIndex._via = { next: !1, prev: !1 }, this.rootElm = null, this.imageContainerElm = null, this.currentImages = null, this.currentItems = null, this.navActive = !0, this.onResizeHandler && (window.removeEventListener("resize", this.onResizeHandler), this.onResizeHandler = null), this.onKeyDown && (window.removeEventListener("keydown", this.onKeyDown), this.onKeyDown = null), (this.onZoomedPointerDown || this.onZoomedPointerMove || this.onZoomedPointerUp) && (this.setZoomed(!1), this.onZoomedPointerDown = null, this.onZoomedPointerMove = null, this.onZoomedPointerUp = null), b.somethingOpened = null;
617
+ }
618
+ destroy() {
619
+ this.close(!1), this.elements instanceof NodeList && this.elements.forEach((t, e) => {
620
+ t.removeEventListener("click", this.onClickElements[e]);
621
+ });
622
+ }
623
+ view(t, e) {
624
+ b.somethingOpened === this && this.navActive && (t < 0 && (t = this.elements.length - 1), t >= this.elements.length && (t = 0), this.currentIndex.via = e || { next: !1, prev: !1 }, this.currentIndex.value = t);
625
+ }
626
+ next() {
627
+ b.somethingOpened === this && this.view(this.currentIndex.value + 1, { next: !0, prev: !1 });
628
+ }
629
+ prev() {
630
+ b.somethingOpened === this && this.view(this.currentIndex.value - 1, { next: !1, prev: !0 });
631
+ }
632
+ getCurrentIndex() {
633
+ return b.somethingOpened === this ? this.currentIndex.value : -1;
634
+ }
635
+ }
636
+ function nt(s) {
637
+ let t = null;
638
+ if (typeof s == "string" ? t = document.querySelectorAll(s) : s instanceof NodeList && (t = s), t)
639
+ for (let e = 0; e < t.length; e++) {
640
+ const n = t[e];
641
+ if (!(n.dataset.vistaviewSrc || n.getAttribute("href") || n.getAttribute("src") || ""))
642
+ return `Element at index ${e} is missing 'src' / 'data-vistaview-src' / 'href' attribute.`;
643
+ }
644
+ else {
645
+ const e = s;
646
+ for (let n = 0; n < e.length; n++)
647
+ if (!e[n].src)
648
+ return `Element at index ${n} is missing 'src' attribute.`;
649
+ }
650
+ return t || s;
651
+ }
652
+ function ot({ elements: s, ...t }) {
653
+ if (!s) throw new Error("No elements");
654
+ let e = nt(s);
655
+ if (typeof e == "string")
656
+ return console.error(e), console.warn("VistaView: silently returning."), null;
657
+ const n = new it(e, t);
658
+ return {
659
+ open: (i = 0) => n.open(i),
660
+ close: () => n.close(),
661
+ next: () => n.next(),
662
+ prev: () => n.prev(),
663
+ destroy: () => n.destroy(),
664
+ getCurrentIndex: () => n.getCurrentIndex(),
665
+ view: (i) => {
666
+ n.view(i);
667
+ }
668
+ };
669
+ }
670
+ export {
671
+ W as DefaultOptions,
672
+ et as defaultClose,
673
+ J as defaultInit,
674
+ Q as defaultSetup,
675
+ tt as defaultTransition,
676
+ q as removeTouchActions,
677
+ G as setTouchActions,
678
+ ot as vistaView,
679
+ N as vistaViewDownload
680
+ };