vistaview 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +57 -56
  2. package/dist/lib/components.d.ts +5 -6
  3. package/dist/lib/components.d.ts.map +1 -1
  4. package/dist/lib/defaults/close.d.ts +3 -0
  5. package/dist/lib/defaults/close.d.ts.map +1 -0
  6. package/dist/lib/defaults/init.d.ts +3 -0
  7. package/dist/lib/defaults/init.d.ts.map +1 -0
  8. package/dist/lib/defaults/options.d.ts +3 -0
  9. package/dist/lib/defaults/options.d.ts.map +1 -0
  10. package/dist/lib/defaults/setup.d.ts +3 -0
  11. package/dist/lib/defaults/setup.d.ts.map +1 -0
  12. package/dist/lib/defaults/transition.d.ts +3 -0
  13. package/dist/lib/defaults/transition.d.ts.map +1 -0
  14. package/dist/lib/errors.d.ts +4 -0
  15. package/dist/lib/errors.d.ts.map +1 -0
  16. package/dist/lib/image-state.d.ts +39 -0
  17. package/dist/lib/image-state.d.ts.map +1 -0
  18. package/dist/lib/main.d.ts +3 -0
  19. package/dist/lib/main.d.ts.map +1 -0
  20. package/dist/lib/pointers.d.ts +23 -0
  21. package/dist/lib/pointers.d.ts.map +1 -0
  22. package/dist/lib/throttle.d.ts +7 -0
  23. package/dist/lib/throttle.d.ts.map +1 -0
  24. package/dist/lib/types.d.ts +70 -36
  25. package/dist/lib/types.d.ts.map +1 -1
  26. package/dist/lib/utils.d.ts +17 -9
  27. package/dist/lib/utils.d.ts.map +1 -1
  28. package/dist/lib/vista-view.d.ts +36 -70
  29. package/dist/lib/vista-view.d.ts.map +1 -1
  30. package/dist/react.d.ts +4 -12
  31. package/dist/react.d.ts.map +1 -1
  32. package/dist/react.js +17 -13
  33. package/dist/solid.d.ts +4 -12
  34. package/dist/solid.d.ts.map +1 -1
  35. package/dist/solid.js +21 -20
  36. package/dist/svelte.d.ts +2 -11
  37. package/dist/svelte.d.ts.map +1 -1
  38. package/dist/svelte.js +7 -6
  39. package/dist/vistaview.css +1 -1
  40. package/dist/vistaview.d.ts +3 -19
  41. package/dist/vistaview.d.ts.map +1 -1
  42. package/dist/vistaview.js +753 -643
  43. package/dist/vistaview.umd.js +11 -15
  44. package/dist/vue.d.ts +2 -10
  45. package/dist/vue.d.ts.map +1 -1
  46. package/dist/vue.js +15 -14
  47. package/package.json +8 -13
  48. package/dist/lib/defaults.d.ts +0 -9
  49. package/dist/lib/defaults.d.ts.map +0 -1
  50. package/dist/lib/pinch-detector.d.ts +0 -33
  51. package/dist/lib/pinch-detector.d.ts.map +0 -1
  52. package/dist/react.cjs +0 -1
  53. package/dist/solid.cjs +0 -1
  54. package/dist/svelte.cjs +0 -1
  55. package/dist/vistaview.cjs +0 -16
  56. package/dist/vue.cjs +0 -1
package/dist/vistaview.js CHANGED
@@ -1,26 +1,109 @@
1
- var V = Object.defineProperty;
2
- var N = (s, t, i) => t in s ? V(s, t, { enumerable: !0, configurable: !0, writable: !0, value: i }) : s[t] = i;
3
- var p = (s, t, i) => N(s, typeof t != "symbol" ? t + "" : t, i);
4
- function R(s) {
5
- const t = getComputedStyle(s), i = s.getBoundingClientRect();
1
+ var T = Object.defineProperty;
2
+ var z = (s, t, e) => t in s ? T(s, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : s[t] = e;
3
+ var l = (s, t, e) => z(s, typeof t != "symbol" ? t + "" : t, e);
4
+ function $(s) {
5
+ return s && !/^0(px|%|r?em|vw|vh|vmin|vmax|cm|mm|in|pt|pc|ex|ch)?$/i.test(s.trim()) && s;
6
+ }
7
+ function F(s) {
8
+ const e = window.getComputedStyle(s).objectFit || "", { width: i, height: n } = s.getBoundingClientRect(), o = s.naturalWidth, r = s.naturalHeight;
9
+ if (!e)
10
+ return { width: i, height: n };
11
+ if (!o || !r)
12
+ return { width: i, height: n };
13
+ const a = o / r, h = i / n;
14
+ switch (e) {
15
+ case "fill":
16
+ return { width: i, height: n };
17
+ case "none":
18
+ return { width: o, height: r };
19
+ case "contain":
20
+ return a > h ? { width: i, height: i / a } : { width: n * a, height: n };
21
+ case "cover":
22
+ return a < h ? { width: i, height: i / a } : { width: n * a, height: n };
23
+ case "scale-down": {
24
+ const c = { width: o, height: r }, m = a > h ? { width: i, height: i / a } : { width: n * a, height: n };
25
+ return m.width <= c.width && m.height <= c.height ? m : c;
26
+ }
27
+ }
28
+ return { width: i, height: n };
29
+ }
30
+ function S(s) {
31
+ const t = getComputedStyle(s), e = s.getBoundingClientRect();
6
32
  return {
7
33
  objectFit: t.objectFit,
8
34
  borderRadius: t.borderRadius,
9
35
  objectPosition: t.objectPosition,
10
36
  overflow: t.overflow,
11
- top: i.top,
12
- left: i.left,
13
- width: i.width,
14
- height: i.height,
37
+ top: e.top,
38
+ left: e.left,
39
+ width: e.width,
40
+ height: e.height,
15
41
  naturalWidth: s.naturalWidth,
16
42
  naturalHeight: s.naturalHeight
17
43
  };
18
44
  }
19
- let $ = null;
20
- function U() {
21
- return $ || (window.trustedTypes || (window.trustedTypes = {
45
+ function A(s) {
46
+ const t = s.imageElm ? S(s.imageElm) : null, e = s.anchorElm ? S(s.anchorElm) : null, i = $(t == null ? void 0 : t.borderRadius), n = e && $(e == null ? void 0 : e.borderRadius), o = (n ? e == null ? void 0 : e.borderRadius : i ? t == null ? void 0 : t.borderRadius : "") || "";
47
+ return {
48
+ fit: (t == null ? void 0 : t.objectFit) || (e == null ? void 0 : e.objectFit) || "",
49
+ pos: (t == null ? void 0 : t.objectPosition) || "",
50
+ br: o,
51
+ overflow: n ? e.overflow : i ? t.overflow : "",
52
+ nw: (t == null ? void 0 : t.naturalWidth) || 0,
53
+ nh: (t == null ? void 0 : t.naturalHeight) || 0,
54
+ w: (e == null ? void 0 : e.width) || (t == null ? void 0 : t.width) || 0,
55
+ h: (e == null ? void 0 : e.height) || (t == null ? void 0 : t.height) || 0,
56
+ top: (e == null ? void 0 : e.top) || (t == null ? void 0 : t.top) || 0,
57
+ left: (e == null ? void 0 : e.left) || (t == null ? void 0 : t.left) || 0
58
+ };
59
+ }
60
+ function M(s, t, e, i = !1) {
61
+ const {
62
+ fit: n,
63
+ w: o,
64
+ h: r,
65
+ // this ones makes things hard. not used.
66
+ // pos,
67
+ // overflow,
68
+ nw: a,
69
+ nh: h,
70
+ br: c,
71
+ top: m,
72
+ left: w
73
+ } = A(s), L = Math.min(Math.max(w, -o), window.innerWidth + o) - window.innerWidth / 2 + o / 2, p = Math.min(Math.max(m, -r), window.innerHeight + r) - window.innerHeight / 2 + r / 2, d = e.style;
74
+ d.width = `${o}px`, d.height = `${r}px`, d.objectFit = n, e.width = a, e.height = h, d.setProperty("--vvw-init-radius", `${c}`), d.setProperty("--vvw-pulse-radius", `calc(1.3 * ${c})`), d.setProperty("--vvw-init-x", `${L}px`), d.setProperty("--vvw-init-y", `${p}px`), i && (d.setProperty("--vvw-current-x", `${L}px`), d.setProperty("--vvw-current-y", `${p}px`));
75
+ const v = F(s.imageElm), g = Math.min(o, v.width), f = Math.min(r, v.height), u = t.style;
76
+ u.setProperty("--vvw-init-radius", `${c}`), u.setProperty("--vvw-init-w", `${g}px`), u.setProperty("--vvw-init-h", `${f}px`), i && (u.setProperty("--vvw-current-radius", `${c}`), u.setProperty("--vvw-current-w", `${g}px`), u.setProperty("--vvw-current-h", `${f}px`), t.dataset.vvwWidth = g.toString(), t.dataset.vvwHeight = f.toString());
77
+ }
78
+ function D(s) {
79
+ const t = window.innerWidth, e = window.innerHeight, i = s.naturalWidth, n = s.naturalHeight;
80
+ if (!i || !n)
81
+ throw new Error("Image natural dimensions are zero");
82
+ if (i < t && n < e)
83
+ return {
84
+ width: i,
85
+ height: n
86
+ };
87
+ const o = i / n, r = t / e;
88
+ let a, h;
89
+ return o > r ? (a = t, h = t / o) : (h = e, a = e * o), {
90
+ width: a,
91
+ height: h
92
+ };
93
+ }
94
+ function P(s, t, e) {
95
+ return Math.min(Math.max(s, t), e);
96
+ }
97
+ function C(s, t = 2) {
98
+ const e = Math.pow(10, t);
99
+ return Math.round(s * e) / e;
100
+ }
101
+ const q = '<svg viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></svg>', k = '<svg viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></svg>', R = '<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>', O = '<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>', Z = '<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>';
102
+ let I = null;
103
+ function X() {
104
+ return I || (window.trustedTypes || (window.trustedTypes = {
22
105
  createPolicy: (s, t) => t
23
- }), $ = window.trustedTypes.createPolicy("vistaView-policy", {
106
+ }), I = window.trustedTypes.createPolicy("vistaView-policy", {
24
107
  createHTML: (s) => s,
25
108
  // HTML is generated by us, not user input
26
109
  createScript: () => {
@@ -29,228 +112,73 @@ function U() {
29
112
  createScriptURL: () => {
30
113
  throw new Error("Not implemented");
31
114
  }
32
- }), $);
33
- }
34
- function O(s) {
35
- const i = U().createHTML(s), n = document.createElement("template");
36
- n.innerHTML = i;
37
- const e = n.content;
38
- return n.remove(), e;
39
- }
40
- function H(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 K(s) {
44
- const i = window.getComputedStyle(s).objectFit || "", { width: n, height: e } = s.getBoundingClientRect(), r = s.naturalWidth, l = s.naturalHeight;
45
- if (!i)
46
- return { width: n, height: e };
47
- if (!r || !l)
48
- return { width: n, height: e };
49
- const o = r / l, c = n / e;
50
- switch (i) {
51
- case "fill":
52
- return { width: n, height: e };
53
- case "none":
54
- return { width: r, height: l };
55
- case "contain":
56
- return o > c ? { width: n, height: n / o } : { width: e * o, height: e };
57
- case "cover":
58
- return o < c ? { width: n, height: n / o } : { width: e * o, height: e };
59
- case "scale-down": {
60
- const a = { width: r, height: l }, d = o > c ? { width: n, height: n / o } : { width: e * o, height: e };
61
- return d.width <= a.width && d.height <= a.height ? d : a;
62
- }
63
- }
64
- return { width: n, height: e };
65
- }
66
- function q(s) {
67
- const t = window.innerWidth, i = window.innerHeight, n = s.naturalWidth, e = s.naturalHeight;
68
- if (!n || !e)
69
- throw console.error("Error", s), new Error("Image natural dimensions are zero");
70
- if (n < t && e < i)
71
- return {
72
- width: n,
73
- height: e
74
- };
75
- const r = n / e, l = t / i;
76
- let o, c;
77
- return r > l ? (o = t, c = t / r) : (c = i, o = i * r), {
78
- width: o,
79
- height: c
80
- };
115
+ }), I);
81
116
  }
82
- function j(s, t) {
83
- const i = window.innerHeight, n = window.innerWidth, e = s, r = t, l = Math.max(0, (e - n) / 2) + n / 2, o = Math.max(0, (r - i) / 2) + i / 2, c = -l, a = -o;
84
- return {
85
- maxDiffX: l,
86
- minDiffY: a,
87
- maxDiffY: o,
88
- minDiffX: c
89
- };
117
+ function W(s) {
118
+ const e = X().createHTML(s), i = document.createElement("template");
119
+ i.innerHTML = e;
120
+ const n = i.content;
121
+ return i.remove(), n;
90
122
  }
91
- const G = '<svg viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></svg>', J = '<svg viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></svg>', Q = '<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>', tt = '<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>', et = '<svg viewBox="0 0 24 24"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>', it = '<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 nt() {
123
+ function B() {
93
124
  return {
94
125
  name: "download",
95
- icon: it,
126
+ icon: Z,
96
127
  onClick: async (s) => {
97
- var r;
98
- const t = await fetch(s.src), i = await t.blob(), n = t.url, e = document.createElement("a");
99
- e.href = URL.createObjectURL(i), e.download = ((r = n.split("/").pop()) == null ? void 0 : r.split("?")[0].split("#")[0]) || "download", document.body.appendChild(e), e.click(), document.body.removeChild(e);
128
+ var o;
129
+ const t = await fetch(s.src), e = await t.blob(), i = t.url, n = document.createElement("a");
130
+ n.href = URL.createObjectURL(e), n.download = ((o = i.split("/").pop()) == null ? void 0 : o.split("?")[0].split("#")[0]) || "download", document.body.appendChild(n), n.click(), document.body.removeChild(n);
100
131
  }
101
132
  };
102
133
  }
103
- function st(s) {
134
+ function N(s) {
104
135
  if (typeof s == "string")
105
136
  switch (s) {
106
137
  case "zoomIn":
107
- return `<button class="vistaview-zoom-in-btn">${Q}</button>`;
138
+ return `<button class="vvw-zoom-in vvw-ui">${R}</button>`;
108
139
  case "zoomOut":
109
- return `<button disabled class="vistaview-zoom-out-btn">${tt}</button>`;
140
+ return `<button disabled class="vvw-zoom-out vvw-ui">${O}</button>`;
110
141
  case "close":
111
- return `<button class="vistaview-close-btn">${et}</button>`;
142
+ return `<button class="vvw-close vvw-ui">${Y}</button>`;
112
143
  case "indexDisplay":
113
- return '<div class="vistaview-index-display"></div>';
144
+ return '<div class="vvw-index vvw-ui"></div>';
114
145
  case "description":
115
- return '<div class="vistaview-description"></div>';
146
+ return '<div class="vvw-desc vvw-ui"></div>';
116
147
  default:
117
148
  return "";
118
149
  }
119
- return `<button data-vistaview-custom-control="${s.name}">${s.icon}</button>`;
150
+ return `<button data-vvw-control="${s.name}">${s.icon}</button>`;
120
151
  }
121
- function k(s, t) {
122
- var d, h;
123
- const i = s.imageElm ? getComputedStyle(s.imageElm) : null, n = (i == null ? void 0 : i.objectFit) || "", e = ((d = s.imageElm) == null ? void 0 : d.naturalWidth) || "", r = ((h = s.imageElm) == null ? void 0 : h.naturalHeight) || "", l = (i == null ? void 0 : i.width) || "", o = (i == null ? void 0 : i.height) || "", c = document.createElement("div");
124
- c.className = "vistaview-item", c.dataset.vistaviewPos = `${t !== void 0 ? t : ""}`, c.dataset.vistaviewIndex = s.index.toString();
125
- const a = O(`<img class="vistaview-image-lowres"
126
- style="${n ? `object-fit:${n};` : ""}${l ? `width:${l};` : ""}${o ? `height:${o};` : ""}"
127
- src="${s.thumb || s.src}"
128
- alt="${s.alt || ""}"
129
- ${e ? `width="${e}"` : ""}
130
- ${r ? `height="${r}"` : ""}
131
- />
132
- <img class="vistaview-image-highres" src="${s.src}" alt="${s.alt || ""}" />`);
133
- return c.appendChild(a), c;
152
+ function j(s, t) {
153
+ const e = document.createElement("div");
154
+ e.className = "vvw-item", e.dataset.vvwPos = `${t !== void 0 ? t : ""}`, e.dataset.vvwIdx = s.index.toString(), e.appendChild(
155
+ W(
156
+ `<p class="vvw-img-err">Error loading image</p>
157
+ <img class="vvw-img-lo" src="${s.thumb || s.src}" alt="${s.alt || ""}" />
158
+ <img class="vvw-img-hi" src="${s.src}" alt="${s.alt || ""}" />`
159
+ )
160
+ );
161
+ const i = e.querySelector("img.vvw-img-lo"), n = e.querySelector("img.vvw-img-hi");
162
+ return M(s, n, i, t === 0), e;
134
163
  }
135
- function ot({
136
- controls: s,
137
- isReducedMotion: t
164
+ function U({
165
+ controls: s
138
166
  }) {
139
- const i = (e) => e ? e.map(st).join("") : "";
140
- return O(
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>${i(s == null ? void 0 : s.topLeft)}</div><div>${i(s == null ? void 0 : s.topCenter)}</div><div>${i(s == null ? void 0 : s.topRight)}</div></div>
145
- <div class="vistaview-bottom-bar vistaview-ui"><div>${i(s == null ? void 0 : s.bottomLeft)}</div><div>${i(s == null ? void 0 : s.bottomCenter)}</div><div>${i(s == null ? void 0 : s.bottomRight)}</div></div>
146
- <div class="vistaview-prev-btn vistaview-ui"><button>${G}</button></div>
147
- <div class="vistaview-next-btn vistaview-ui"><button>${J}</button></div>
167
+ const t = (i) => i ? i.map(N).join("") : "";
168
+ return W(
169
+ `<div class="vvw-root" id="vvw-root">
170
+ <div class="vvw-container">
171
+ <div class="vvw-bg"></div>
172
+ <div class="vvw-image-container"></div>
173
+ <div class="vvw-top-bar vvw-ui"><div>${t(s == null ? void 0 : s.topLeft)}</div><div>${t(s == null ? void 0 : s.topCenter)}</div><div>${t(s == null ? void 0 : s.topRight)}</div></div>
174
+ <div class="vvw-bottom-bar vvw-ui"><div>${t(s == null ? void 0 : s.bottomLeft)}</div><div>${t(s == null ? void 0 : s.bottomCenter)}</div><div>${t(s == null ? void 0 : s.bottomRight)}</div></div>
175
+ <div class="vvw-prev vvw-ui"><button>${q}</button></div>
176
+ <div class="vvw-next vvw-ui"><button>${k}</button></div>
148
177
  </div>
149
178
  </div>`
150
179
  );
151
180
  }
152
- let A = null, M = null, Z = null, T = null;
153
- function rt(s) {
154
- F(s);
155
- const t = s.imageContainerElm, i = s.elements.length;
156
- if (!t) return;
157
- let n = 0, e = 0, r = 0, l = 0, o = null, c = 0, a = !1;
158
- A = (d) => {
159
- d.preventDefault(), d.stopPropagation(), s.isZoomed === !1 && (a = !0, n = d.pageX, e = d.pageY, r = d.pageX, l = d.pageY, c = Date.now(), o = null, t.setPointerCapture(d.pointerId));
160
- }, M = (d) => {
161
- if (d.preventDefault(), d.stopPropagation(), s.isZoomed !== !1 || !a) return;
162
- const h = d.pageX - n, u = d.pageY - e;
163
- r = d.pageX, l = d.pageY, Math.abs(h) >= Math.abs(u) && (o === null || o === !0) ? (t.style.setProperty("--vistaview-pointer-diff-x", `${h}px`), o = !0) : Math.abs(u) > Math.abs(h) && (o === null || o === !1) && (t.style.setProperty("--vistaview-pointer-diff-y", `${u}px`), o = !1);
164
- }, T = (d) => {
165
- if (d.preventDefault(), d.stopPropagation(), t.releasePointerCapture(d.pointerId), s.isZoomed !== !1 || !a) return;
166
- a = !1, o = null;
167
- const h = Array.from(t.querySelectorAll(".vistaview-item"));
168
- t.style.removeProperty("--vistaview-pointer-diff-x"), t.style.removeProperty("--vistaview-pointer-diff-y"), h.forEach((u) => {
169
- u.style.transition = "", u.style.translate = "";
170
- });
171
- }, Z = (d) => {
172
- if (d.preventDefault(), d.stopPropagation(), t.releasePointerCapture(d.pointerId), s.isZoomed !== !1 || !a) return;
173
- a = !1;
174
- const h = Array.from(t.querySelectorAll(".vistaview-item")), u = r - n, w = l - e, f = Date.now() - c, v = u / f, y = w / f, b = s.options.touchSpeedThreshold || 0.5, L = h.find(
175
- (g) => g.dataset.vistaviewPos === "0"
176
- ), C = Number(L.dataset.vistaviewIndex);
177
- function E() {
178
- h[0].removeEventListener("transitionend", E), t.style.removeProperty("--vistaview-pointer-diff-x"), t.style.removeProperty("--vistaview-pointer-diff-y"), h.forEach((g) => {
179
- g.style.transition = "", g.style.translate = "";
180
- });
181
- }
182
- function m(g = "0%", x = "0%") {
183
- h.forEach((I) => {
184
- I.style.transition = `translate ${s.options.animationDurationBase * 0.5}ms ease-out`, I.style.translate = `${g} ${x}`;
185
- });
186
- }
187
- if (v < -b || v > b) {
188
- let g = function() {
189
- h[0].removeEventListener("transitionend", g), setTimeout(() => {
190
- const x = s.isReducedMotion, I = s.options.detectReducedMotion;
191
- s.isReducedMotion = !0, s.options.detectReducedMotion = !0, E(), s.view(
192
- v < -b ? (C + 1) % i : (C - 1 + i) % i,
193
- {
194
- next: v < -b,
195
- prev: v > b
196
- }
197
- ), s.isReducedMotion = x, s.options.detectReducedMotion = I;
198
- }, 100);
199
- };
200
- m(v < -b ? "-100%" : "100%"), h[0].addEventListener("transitionend", g);
201
- } else y < -b || y > b ? (s.close(), m("0%", "0%")) : (h[0].addEventListener("transitionend", E), m("0%"), v === 0 && y === 0 && s.zoomIn());
202
- }, t.addEventListener("pointermove", M), t.addEventListener("pointerup", Z), t.addEventListener("pointerdown", A), t.addEventListener("pointercancel", T);
203
- }
204
- function F(s) {
205
- const t = s.imageContainerElm;
206
- t && (M && t.removeEventListener("pointermove", M), Z && t.removeEventListener("pointerup", Z), A && t.removeEventListener("pointerdown", A), T && t.removeEventListener("pointercancel", T));
207
- }
208
- const at = (s) => {
209
- rt(s);
210
- }, lt = ({
211
- htmlElements: { to: s },
212
- index: { to: t },
213
- vistaView: i
214
- }) => {
215
- i.elements instanceof NodeList && t !== null && (i.elements.forEach((n) => n.style.opacity = "1"), i.elements[t].style.opacity = "0"), s && s.forEach((n) => {
216
- const e = Number(n.dataset.vistaviewPos);
217
- e !== 0 ? (n.style.zIndex = "1", n.style.left = 100 * e + "%") : n.style.zIndex = "2";
218
- });
219
- }, dt = async ({
220
- htmlElements: { from: s },
221
- via: { next: t, prev: i },
222
- vistaView: n
223
- // index: { from: fromIndex, to: toIndex },
224
- }, e) => {
225
- if (n.options.detectReducedMotion && n.isReducedMotion)
226
- return;
227
- const r = s.filter((l) => l.dataset.vistaviewPos === "0" || (t ? l.dataset.vistaviewPos === "1" : l.dataset.vistaviewPos === "-1"));
228
- await new Promise((l, o) => {
229
- let c = 0, a = !1;
230
- if (e.aborted) {
231
- o(new z("Transition aborted"));
232
- return;
233
- }
234
- const d = (h) => {
235
- if (a) return o(new z("Transition aborted"));
236
- if (e.aborted)
237
- return a || (a = !0), o(new z("Transition aborted"));
238
- h.currentTarget.removeEventListener("transitionend", d), c++, c >= r.length && l(0);
239
- };
240
- r.forEach((h) => {
241
- h.style.transition = `translate ${n.options.animationDurationBase * 0.5}ms ease-out`, h.style.translate = t ? "-100%" : i ? "100%" : "0%", h.addEventListener("transitionend", d);
242
- });
243
- });
244
- }, ct = (s) => {
245
- s.elements instanceof NodeList && s.elements.forEach((t) => t.style.opacity = "1"), F(s);
246
- };
247
- class z extends Error {
248
- constructor(t) {
249
- super(t), this.name = "VistaViewTransitionAbortedError";
250
- }
251
- }
252
- const W = {
253
- detectReducedMotion: !0,
181
+ const H = {
254
182
  // debug, don't remove
255
183
  // animationDurationBase: 1000,
256
184
  animationDurationBase: 333,
@@ -260,340 +188,354 @@ const W = {
260
188
  preloads: 1,
261
189
  keyboardListeners: !0,
262
190
  arrowOnSmallScreens: !1,
191
+ rapidLimit: 222,
263
192
  controls: {
264
193
  topLeft: ["indexDisplay"],
265
- topRight: ["zoomIn", "zoomOut", nt(), "close"],
266
- bottomCenter: ["description"]
194
+ topRight: ["zoomIn", "zoomOut", B(), "close"],
195
+ bottomLeft: ["description"]
267
196
  }
268
- }, S = {
269
- somethingOpened: null
270
197
  };
271
- class ht {
272
- constructor(t, i) {
273
- p(this, "options");
274
- p(this, "elements");
275
- p(this, "isReducedMotion");
276
- p(this, "currentIndex", {
277
- _value: null,
278
- _vistaView: null,
279
- _via: { next: !1, prev: !1 },
280
- set value(t) {
281
- var n, e, r;
282
- const i = this._value;
283
- this._value = t;
284
- for (const l in (n = this._vistaView) == null ? void 0 : n.transitionAbortControllers)
285
- (e = this._vistaView) == null || e.transitionAbortControllers[l].abort();
286
- (r = this._vistaView) == null || r.swap(i, this._value);
287
- },
288
- get value() {
289
- return this._value;
290
- },
291
- get via() {
292
- return this._via;
198
+ function K(s) {
199
+ }
200
+ function _(s) {
201
+ const t = s.options.preloads;
202
+ s.imageContainer.style.width = `${(t * 2 + 1) * 100}vw`, s.imageContainer.style.left = `-${t * 100}vw`, s.imageContainer.style.display = "flex", G(s);
203
+ }
204
+ function G(s) {
205
+ let t = { x: 0, y: 0 }, e = { x: 0, y: 0 }, i = null;
206
+ s.registerPointerListener((n) => {
207
+ if (!n.hasInternalExecution && !(n.pointers.length > 1)) {
208
+ if (n.event === "down" && (t = { x: n.pointer.x, y: n.pointer.y }, e = { x: n.pointer.x, y: n.pointer.y }), n.event === "move") {
209
+ e = { x: n.pointer.x, y: n.pointer.y };
210
+ const o = e.x - t.x, r = e.y - t.y;
211
+ if (!i && Math.abs(r) > Math.abs(o) || i === "y") {
212
+ const a = r / window.innerHeight * 100;
213
+ s.imageContainer.style.transition = "none", s.imageContainer.style.transform = `translateY(${a}vh)`, i = "y";
214
+ } else if (!i && Math.abs(o) > Math.abs(r) || i === "x") {
215
+ const a = o / window.innerWidth * 100;
216
+ s.imageContainer.style.transition = "none", s.imageContainer.style.transform = `translateX(${a}vw)`, i = "x";
217
+ }
218
+ }
219
+ if (n.event === "up" || n.event === "cancel") {
220
+ let o = function(r) {
221
+ var a;
222
+ (a = s.imageContainer) == null || a.addEventListener("transitionend", function h() {
223
+ var c;
224
+ (c = s.imageContainer) == null || c.removeEventListener("transitionend", h), s.imageContainer.style.transition = "", s.imageContainer.style.transform = "";
225
+ }), s.imageContainer.style.transition = "transform 222ms ease", s.imageContainer.style.transform = r;
226
+ };
227
+ if (i === "y") {
228
+ const r = e.y - t.y, a = n.pointer.movementY, h = 8;
229
+ s.imageContainer.style.transition = "", r > 0 && Math.abs(a) > h || r < 0 && Math.abs(a) > h ? (s.imageContainer.style.transition = "transform 222ms ease", s.imageContainer.style.transform = "translateY(0vh)", s.close()) : o("translateY(0vh)");
230
+ }
231
+ if (i === "x") {
232
+ const r = e.x - t.x, a = n.pointer.movementX, h = 8;
233
+ s.imageContainer.style.transition = "", r > 0 && Math.abs(a) > h ? s.prev() : r < 0 && Math.abs(a) > h ? s.next() : o("translateX(0vw)");
234
+ }
235
+ i = null;
236
+ }
237
+ }
238
+ });
239
+ }
240
+ function J(s) {
241
+ }
242
+ async function Q({
243
+ vistaView: { isReducedMotion: s },
244
+ htmlElements: { to: t },
245
+ index: { from: e, to: i },
246
+ vistaView: { elements: n, imageContainer: o, options: r }
247
+ }, a) {
248
+ if (!t || a.aborted || s || !(Math.abs(i - e) === 1 || e === 0 && i === n.length - 1 || e === n.length - 1 && i === 0))
249
+ return;
250
+ const c = Math.round(r.animationDurationBase * 1.5 * 100) / 100;
251
+ return new Promise((m) => {
252
+ o.addEventListener(
253
+ "transitionend",
254
+ () => {
255
+ m(() => {
256
+ o.style.transition = "", o.style.transform = "";
257
+ });
293
258
  },
294
- set via(t) {
295
- this._via = t;
259
+ { once: !0 }
260
+ );
261
+ const w = i === e + 1 || e === n.length - 1 && i === 0 ? "translateX(-100vw)" : "translateX(100vw)";
262
+ o.style.transition = `transform ${c}ms ease`, o.style.transform = w;
263
+ });
264
+ }
265
+ class V {
266
+ constructor({ elm: t, listeners: e }) {
267
+ l(this, "pointers", []);
268
+ l(this, "elm");
269
+ l(this, "listeners", []);
270
+ l(this, "lastPointerDownId", null);
271
+ l(this, "removeLastPointer", () => {
272
+ if (this.pointers.length && this.lastPointerDownId !== null) {
273
+ const t = this.pointers.findIndex((e) => e.id === this.lastPointerDownId);
274
+ t !== -1 && this.pointers.splice(t, 1);
296
275
  }
297
276
  });
298
- p(this, "rootElm", null);
299
- p(this, "imageContainerElm", null);
300
- p(this, "customControls", {});
301
- p(this, "currentImages", null);
302
- p(this, "currentItems", null);
303
- p(this, "isZoomed", !1);
304
- p(this, "onClickElements", (t) => {
277
+ l(this, "onPointerDown", (t) => {
278
+ if (!this.listeners.length || t.button !== 0) return;
279
+ t.preventDefault(), this.lastPointerDownId = t.pointerId, window.addEventListener("contextmenu", this.removeLastPointer, { once: !0 }), window.addEventListener("auxclick", this.removeLastPointer, { once: !0 });
280
+ let e = {
281
+ x: t.clientX,
282
+ y: t.clientY,
283
+ movementX: 0,
284
+ movementY: 0,
285
+ id: t.pointerId
286
+ };
287
+ this.pointers.push(e), this.listeners.forEach(
288
+ (i) => i({
289
+ event: "down",
290
+ pointer: e,
291
+ pointers: this.pointers,
292
+ lastPointerLen: this.pointers.length - 1
293
+ })
294
+ );
295
+ });
296
+ l(this, "onPointerMove", (t) => {
297
+ if (!this.listeners.length) return;
305
298
  t.preventDefault();
306
- const i = t.currentTarget;
307
- i.dataset.vistaviewIndex && this.open(parseInt(i.dataset.vistaviewIndex));
299
+ const e = this.pointers.find((i) => i.id === t.pointerId);
300
+ e && (e.movementX = t.movementX, e.movementY = t.movementY, e.x = t.clientX, e.y = t.clientY, this.listeners.forEach(
301
+ (i) => i({
302
+ event: "move",
303
+ pointer: e,
304
+ pointers: this.pointers,
305
+ lastPointerLen: this.pointers.length - 1
306
+ })
307
+ ));
308
308
  });
309
- p(this, "defaultOnClickHandler", (t) => t.preventDefault());
310
- p(this, "onResizeHandler", null);
311
- p(this, "onKeyDown", null);
312
- p(this, "userSetup", lt);
313
- p(this, "userTransition", dt);
314
- p(this, "userClose", ct);
315
- p(this, "userInit", at);
316
- p(this, "onZoomedPointerDown", null);
317
- p(this, "onZoomedPointerMove", null);
318
- p(this, "onZoomedPointerUp", null);
319
- p(this, "transitionAbortControllers", {});
320
- // weird on iphones
321
- // private loadImageWaiting = (img: HTMLImageElement): Promise<void> => {
322
- // return new Promise((resolve) => {
323
- // const observer = new MutationObserver((mutations) => {
324
- // mutations.forEach((mutation) => {
325
- // if (
326
- // mutation.type === 'attributes' &&
327
- // mutation.attributeName === 'class' &&
328
- // (mutation.target as HTMLElement).classList.contains('vistaview-image-settled')
329
- // ) {
330
- // console.log('vistaview-image-settled detected')
331
- // resolve()
332
- // }
333
- // });
334
- // // Start observing
335
- // observer.observe(img, {
336
- // attributes: true,
337
- // attributeOldValue: true,
338
- // attributeFilter: ['class']
339
- // });
340
- // });
341
- // });
342
- // };
343
- p(this, "loadImageTimeout", null);
344
- this.elements = t, this.currentIndex._vistaView = this, this.options = {
345
- ...W,
346
- ...i || {},
347
- controls: {
348
- ...W.controls,
349
- ...(i == null ? void 0 : i.controls) || {}
350
- }
351
- }, 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, e) => {
352
- n.dataset.vistaviewIndex = e.toString(), n.addEventListener("click", this.defaultOnClickHandler), n.addEventListener("pointerup", this.onClickElements);
309
+ l(this, "onPointerUp", (t) => {
310
+ if (!this.listeners.length || t.button !== 0 || (window.removeEventListener("contextmenu", this.removeLastPointer), window.removeEventListener("auxclick", this.removeLastPointer), t.target instanceof Node && !this.elm.contains(t.target) && t.target !== document.querySelector("html") && t.target !== document))
311
+ return;
312
+ t.preventDefault();
313
+ const e = this.pointers.findIndex((o) => o.id === t.pointerId);
314
+ if (e === -1) return;
315
+ const i = this.pointers[e];
316
+ i.x = t.clientX, i.y = t.clientY;
317
+ const n = this.pointers.length;
318
+ this.pointers.splice(e, 1), this.listeners.forEach(
319
+ (o) => o({
320
+ event: "up",
321
+ pointer: i,
322
+ pointers: this.pointers,
323
+ lastPointerLen: n
324
+ })
325
+ );
326
+ });
327
+ l(this, "onPointerCancel", (t) => {
328
+ if (!this.listeners.length || t.target instanceof Node && !this.elm.contains(t.target) && t.target !== document.querySelector("html") && t.target !== document)
329
+ return;
330
+ t.preventDefault();
331
+ const e = this.pointers.findIndex((o) => o.id === t.pointerId);
332
+ if (e === -1) return;
333
+ const i = this.pointers[e];
334
+ i.x = t.clientX, i.y = t.clientY;
335
+ const n = this.pointers.length;
336
+ this.pointers.splice(e, 1), this.listeners.forEach(
337
+ (o) => o({
338
+ event: "cancel",
339
+ pointer: i,
340
+ pointers: this.pointers,
341
+ lastPointerLen: n
342
+ })
343
+ );
353
344
  });
345
+ this.elm = t ?? document, e && (this.listeners = e), this.startListeners();
354
346
  }
355
- setFullSizeImageDim(t) {
356
- var r, l;
357
- const i = t.getBoundingClientRect(), { width: n, height: e } = q(t);
358
- if (n === i.width && e === i.height)
359
- (l = (r = t.parentElement) == null ? void 0 : r.querySelector(".vistaview-image-lowres")) == null || l.classList.add("vistaview-image--hidden"), t.classList.add("vistaview-image-settled");
360
- else {
361
- let o = 0;
362
- const c = () => {
363
- var a, d;
364
- o++, !(o < 3) && (t.removeEventListener("transitionend", c), (d = (a = t.parentElement) == null ? void 0 : a.querySelector(".vistaview-image-lowres")) == null || d.classList.add("vistaview-image--hidden"), t.classList.add("vistaview-image-settled"));
365
- };
366
- requestAnimationFrame(() => {
367
- t.addEventListener("transitionend", c), t.style.width = `${n}px`, t.style.height = `${e}px`;
368
- });
369
- }
347
+ startListeners() {
348
+ this.elm.addEventListener("pointerdown", this.onPointerDown), this.elm.addEventListener("pointermove", this.onPointerMove), document.addEventListener("pointerup", this.onPointerUp), document.addEventListener("pointercancel", this.onPointerCancel);
370
349
  }
371
- async swap(t, i) {
372
- var d, h;
373
- if (!S.somethingOpened || t === i || t === null) return;
374
- if (!this.imageContainerElm)
375
- throw new Error("VistaView: imageContainerElm is null in swap()");
376
- this.setIndexDisplay(), this.clearZoom();
377
- const { images: n, positions: e } = this.getCurrentIndexes(i), r = this.getImages(n), l = r.map((u, w) => k(u, e[w])), o = {
378
- htmlElements: { from: this.currentItems, to: l },
379
- images: { from: this.currentImages, to: r },
380
- index: { from: t, to: i },
381
- via: this.currentIndex.via,
382
- vistaView: this
383
- };
384
- this.userSetup(o);
385
- const c = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
386
- this.transitionAbortControllers[c] = new AbortController();
387
- try {
388
- await this.userTransition(o, this.transitionAbortControllers[c].signal);
389
- } catch (u) {
390
- u instanceof z || console.warn(u);
391
- }
392
- const a = l.find((u) => u.dataset.vistaviewPos === "0");
393
- if (a) {
394
- const u = a.dataset.vistaviewIndex, w = this.currentItems.find((v) => v.dataset.vistaviewIndex === u), f = w == null ? void 0 : w.querySelector(".vistaview-image-highres");
395
- if (f) {
396
- const v = a.querySelector(
397
- ".vistaview-image-highres"
398
- );
399
- if (v.setAttribute("class", f.getAttribute("class") || ""), v.setAttribute("style", f.getAttribute("style") || ""), v.classList.remove("vistaview-image--zooming"), f.classList.contains("vistaview-image-loaded") && !f.classList.contains("vistaview-image-settled")) {
400
- const y = f.getBoundingClientRect();
401
- v.style.width = `${y.width}px`, v.style.height = `${y.height}px`;
402
- }
403
- }
404
- }
405
- delete this.transitionAbortControllers[c], this.imageContainerElm.innerHTML = "", l.forEach((u) => {
406
- var y;
407
- const w = u.querySelector(".vistaview-image-highres"), f = !!w.classList.contains("vistaview-image-loaded"), v = !!w.classList.contains("vistaview-image-settled");
408
- this.imageContainerElm.appendChild(u), f && !v ? this.setFullSizeImageDim(w) : f && v && ((y = u == null ? void 0 : u.querySelector(".vistaview-image-lowres")) == null || y.classList.add("vistaview-image--hidden"));
409
- }), this.setInitialDimPos(), this.currentImages = r, this.currentItems = l, this.setCurrentDescription(), this.updateZoomButtonsVisibility(), (h = (d = this.options).onImageView) == null || h.call(d, o), this.loadImageTimeout && clearTimeout(this.loadImageTimeout), this.loadImageTimeout = setTimeout(() => {
410
- this.loadImages();
411
- }, 333);
412
- }
413
- //
414
- setZoomed(t) {
415
- var n, e, r, l, o, c;
416
- if (this.isZoomed === t) return;
417
- let i = null;
418
- if (this.isZoomed) {
419
- i && cancelAnimationFrame(i);
420
- let a = this.isZoomed;
421
- if (a.classList.remove("vistaview-image--zooming"), this.onZoomedPointerDown && ((n = a.parentElement) == null || n.removeEventListener("pointerdown", this.onZoomedPointerDown), this.onZoomedPointerDown = null), this.onZoomedPointerMove && ((e = a.parentElement) == null || e.removeEventListener("pointermove", this.onZoomedPointerMove), this.onZoomedPointerMove = null), this.onZoomedPointerUp && ((r = a.parentElement) == null || r.removeEventListener("pointerup", this.onZoomedPointerUp), this.onZoomedPointerUp = null), a == null || a.style.removeProperty("--pointer-diff-x"), a == null || a.style.removeProperty("--pointer-diff-y"), setTimeout(() => {
422
- a == null || a.classList.remove("vistaview-image--zooming");
423
- }, 500), this.isZoomed = !1, !t) return;
424
- }
425
- if (t) {
426
- let a = function({ speedX: m, speedY: g }) {
427
- i = requestAnimationFrame(() => {
428
- if (Math.abs(m) < 0.01 && Math.abs(g) < 0.01)
429
- return;
430
- const x = t, I = window.innerWidth / 2, P = window.innerHeight / 2, D = x.getBoundingClientRect(), X = D.bottom < P, Y = D.top > P, B = D.right < I, _ = D.left > I;
431
- w += m, f += g, X && (f += (P - D.bottom) / C), Y && (f -= (D.top - P) / C), B && (w += (I - D.right) / C), _ && (w -= (D.left - I) / C), x == null || x.style.setProperty("--pointer-diff-x", `${w}px`), x == null || x.style.setProperty("--pointer-diff-y", `${f}px`), a({
432
- speedX: m * (1 - E),
433
- speedY: g * (1 - E)
434
- });
435
- });
436
- };
437
- 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");
438
- let d = !1, h = 0, u = 0, w = 0, f = 0, v = 0, y = 0, b = 0, L = 15, C = 5, E = 0.1;
439
- this.onZoomedPointerDown = (m) => {
440
- i && cancelAnimationFrame(i), m.preventDefault(), m.stopPropagation(), d = !0, h = m.pageX, u = m.pageY, b = performance.now(), t.setPointerCapture(m.pointerId);
441
- }, this.onZoomedPointerMove = (m) => {
442
- d && (m.preventDefault(), v = m.pageX - h, y = m.pageY - u, t == null || t.style.setProperty("--pointer-diff-x", `${v + w}px`), t == null || t.style.setProperty("--pointer-diff-y", `${y + f}px`));
443
- }, this.onZoomedPointerUp = (m) => {
444
- if (d = !1, t.releasePointerCapture(m.pointerId), w += v, f += y, v === 0 && y === 0)
445
- this.zoomIn();
446
- else {
447
- let g = performance.now() - b;
448
- if (g === 0) return;
449
- let x = (m.pageY - u) / g, I = (m.pageX - h) / g;
450
- a({ speedX: I * L, speedY: x * L });
451
- }
452
- v = 0, y = 0;
453
- }, (l = t == null ? void 0 : t.parentElement) == null || l.addEventListener("pointerdown", this.onZoomedPointerDown), (o = t == null ? void 0 : t.parentElement) == null || o.addEventListener("pointermove", this.onZoomedPointerMove), (c = t == null ? void 0 : t.parentElement) == null || c.addEventListener("pointerup", this.onZoomedPointerUp);
454
- return;
455
- }
350
+ removeListeners() {
351
+ this.elm.removeEventListener("pointerdown", this.onPointerDown), this.elm.removeEventListener("pointermove", this.onPointerMove), document.removeEventListener("pointerup", this.onPointerUp), document.removeEventListener("pointercancel", this.onPointerCancel), this.pointers = [];
456
352
  }
457
- zoomIn() {
458
- var r, l, o, c, a;
459
- const t = (r = this.rootElm) == null ? void 0 : r.querySelector(
460
- '[data-vistaview-pos="0"] .vistaview-image-highres'
461
- ), i = t.width, n = t.height;
462
- t.dataset.vistaviewInitialWidth || (t.dataset.vistaviewInitialWidth = i.toString()), t.dataset.vistaviewInitialHeight || (t.dataset.vistaviewInitialHeight = n.toString()), this.setZoomed(t);
463
- const e = (t.naturalWidth || 0) * this.options.maxZoomLevel;
464
- if (i && e && i < e) {
465
- const d = Math.min(i + this.options.zoomStep, e);
466
- t.style.width = `${d}px`;
467
- const h = d / i * n;
468
- t.style.height = `${h}px`, (o = (l = this.rootElm) == null ? void 0 : l.querySelector("button.vistaview-zoom-out-btn")) == null || o.removeAttribute("disabled"), t.dataset.vistaviewCurrentWidth = d.toString(), t.dataset.vistaviewCurrentHeight = h.toString(), d === e && ((a = (c = this.rootElm) == null ? void 0 : c.querySelector("button.vistaview-zoom-in-btn")) == null || a.setAttribute("disabled", "true"));
469
- }
353
+ addEventListener(t) {
354
+ this.listeners.push(t);
470
355
  }
471
- zoomOut() {
472
- var l, o, c, a, d;
473
- const t = (l = this.rootElm) == null ? void 0 : l.querySelector(
474
- '[data-vistaview-pos="0"] .vistaview-image-highres'
475
- ), i = t.width, n = t.height, e = t.dataset.vistaviewInitialWidth ? parseInt(t.dataset.vistaviewInitialWidth) : 0, r = (h) => {
476
- h.target === t && (t.classList.remove("vistaview-image--zooming-out"), t.removeEventListener("transitionend", r));
477
- };
478
- if (t.addEventListener("transitionend", r), t.classList.add("vistaview-image--zooming-out"), i && e && i > e) {
479
- const h = Math.max(i - this.options.zoomStep, e);
480
- t.style.width = `${h}px`;
481
- const u = h / i * n;
482
- t.style.height = `${u}px`, (c = (o = this.rootElm) == null ? void 0 : o.querySelector("button.vistaview-zoom-in-btn")) == null || c.removeAttribute("disabled"), t.dataset.vistaviewCurrentWidth = h.toString(), t.dataset.vistaviewCurrentHeight = u.toString();
483
- const { maxDiffX: w, minDiffY: f, maxDiffY: v, minDiffX: y } = j(h, u);
484
- let b = parseInt(
485
- (t == null ? void 0 : t.style.getPropertyValue("--pointer-diff-x").replace("px", "")) || "0"
486
- ), L = parseInt(
487
- (t == null ? void 0 : t.style.getPropertyValue("--pointer-diff-y").replace("px", "")) || "0"
488
- );
489
- b = Math.min(w, Math.max(y, b)), L = Math.min(v, Math.max(f, L)), t == null || t.style.setProperty("--pointer-diff-x", `${b}px`), t == null || t.style.setProperty("--pointer-diff-y", `${L}px`), h === e && ((d = (a = this.rootElm) == null ? void 0 : a.querySelector("button.vistaview-zoom-out-btn")) == null || d.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));
490
- }
356
+ removeEventListener(t) {
357
+ this.listeners = this.listeners.filter((e) => e !== t);
491
358
  }
492
- clearZoom() {
493
- }
494
- getImages(t) {
495
- return t.map((i, n) => {
496
- const e = this.elements[i];
497
- if (e instanceof HTMLElement) {
498
- const r = e.querySelector("img"), l = e.getAttribute("href") || "", o = e.getAttribute("src") || "", c = e.dataset.vistaviewSrc || l || o || (r == null ? void 0 : r.src) || "", a = e.dataset.vistaviewAlt || e.getAttribute("alt") || (r == null ? void 0 : r.alt) || "", d = e.dataset.vistaviewThumb || (r == null ? void 0 : r.src) || l || o || "";
499
- return {
500
- index: t[n],
501
- src: c,
502
- alt: a,
503
- thumb: d,
504
- imageElm: e instanceof HTMLImageElement ? e : r,
505
- anchorElm: e instanceof HTMLAnchorElement ? e : void 0
506
- };
507
- } else
508
- return { index: t[n], ...e };
509
- });
359
+ getPointerDistance(t, e) {
360
+ const i = t.x - e.x, n = t.y - e.y;
361
+ return Math.sqrt(i * i + n * n);
510
362
  }
511
- setInitialDimPos() {
512
- var a, d;
513
- if (!this.rootElm) return;
514
- const t = (a = this.rootElm.querySelector('[data-vistaview-pos="0"]')) == null ? void 0 : a.dataset.vistaviewIndex, i = ((d = this.currentImages) == null ? void 0 : d.find((h) => h.index === Number(t))) || null;
515
- if (!i) return;
516
- const n = i.imageElm ? R(i.imageElm) : void 0, e = i.anchorElm ? R(i.anchorElm) : void 0, r = (e == null ? void 0 : e.width) || (n == null ? void 0 : n.width) || 0, l = (e == null ? void 0 : e.height) || (n == null ? void 0 : n.height) || 0, o = ((e == null ? void 0 : e.left) || (n == null ? void 0 : n.left) || 0) + r / 2, c = ((e == null ? void 0 : e.top) || (n == null ? void 0 : n.top) || 0) + l / 2;
517
- this.rootElm.style.setProperty("--vistaview-container-initial-width", r + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-height", l + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-top", c + "px"), this.rootElm.style.setProperty("--vistaview-container-initial-left", o + "px"), this.rootElm.style.setProperty(
518
- "--vistaview-image-border-radius",
519
- H(e == null ? void 0 : e.borderRadius) || H(n == null ? void 0 : n.borderRadius) || "0px"
363
+ getCentroid() {
364
+ if (this.pointers.length === 0) return null;
365
+ const t = this.pointers.reduce(
366
+ (e, i) => (e.x += i.x, e.y += i.y, e),
367
+ { x: 0, y: 0 }
520
368
  );
369
+ return {
370
+ x: t.x / this.pointers.length,
371
+ y: t.y / this.pointers.length
372
+ };
373
+ }
374
+ }
375
+ class tt {
376
+ constructor(t, e) {
377
+ l(this, "maxZoomLevel");
378
+ l(this, "image", null);
379
+ l(this, "rect", null);
380
+ l(this, "initialCenter", { x: 0, y: 0 });
381
+ l(this, "maxDimension", { width: 0 });
382
+ l(this, "minDimension", { initialWidth: 0, initialHeight: 0, minWidth: 0, closingWidth: 0 });
383
+ l(this, "accumulatedTranslate", { x: 0, y: 0 });
384
+ // state
385
+ l(this, "scale", 1);
386
+ l(this, "translate", { x: 0, y: 0 });
387
+ l(this, "onScale", null);
388
+ l(this, "animationTimestamp", 0);
389
+ this.maxZoomLevel = t, this.onScale = e;
521
390
  }
522
- updateZoomButtonsVisibility() {
523
- var e;
524
- const t = (e = this.rootElm) == null ? void 0 : e.querySelector(
525
- '[data-vistaview-pos="0"] img.vistaview-image-highres'
391
+ clean() {
392
+ this.image && (this.image.style.transform = "", this.image.style.width = "", this.image.style.height = "", this.image.style.top = "", this.image.style.left = "", this.image.style.opacity = "");
393
+ }
394
+ reset() {
395
+ this.clean(), this.image = null, this.rect = null, this.initialCenter = { x: window.innerWidth / 2, y: window.innerHeight / 2 }, this.maxDimension = { width: 0 }, this.minDimension = { initialWidth: 0, initialHeight: 0, minWidth: 0, closingWidth: 0 }, this.accumulatedTranslate = { x: 0, y: 0 }, this.scale = 1, this.translate = { x: 0, y: 0 };
396
+ }
397
+ setCurrentImage(t) {
398
+ if (this.rect = null, this.image = t, this.maxDimension = {
399
+ width: t.naturalWidth * this.maxZoomLevel
400
+ }, !t.dataset.vvwWidth || !t.dataset.vvwHeight)
401
+ throw new Error("VistaImageState: Image dataset vvwWidth or vvwHeight not set.");
402
+ const e = parseFloat(t.dataset.vvwWidth), i = parseFloat(t.dataset.vvwHeight);
403
+ this.minDimension = {
404
+ initialWidth: e,
405
+ initialHeight: i,
406
+ minWidth: e * 0.1,
407
+ closingWidth: e * 0.5
408
+ }, this.accumulatedTranslate = { x: 0, y: 0 };
409
+ }
410
+ setInitialCenter(t) {
411
+ this.initialCenter = t || { x: window.innerWidth / 2, y: window.innerHeight / 2 };
412
+ }
413
+ move(t) {
414
+ this.image && (this.rect || (this.rect = this.image.getBoundingClientRect()), this.translate.x = C(t.x - this.initialCenter.x), this.translate.y = C(t.y - this.initialCenter.y), this.image.style.transform = `translate3d(${this.translate.x}px, ${this.translate.y}px, 0px) scale(${this.scale})`);
415
+ }
416
+ scaleMove(t, e) {
417
+ if (!this.image) return;
418
+ this.rect || (this.rect = this.image.getBoundingClientRect()), e || (e = this.initialCenter);
419
+ const i = P(
420
+ this.rect.width * t,
421
+ this.minDimension.minWidth,
422
+ this.maxDimension.width
526
423
  );
527
- if (!t) return;
528
- const i = this;
529
- function n() {
530
- var d, h;
531
- const r = (d = i.rootElm) == null ? void 0 : d.querySelector(
532
- "button.vistaview-zoom-in-btn"
533
- ), l = (h = i.rootElm) == null ? void 0 : h.querySelector(
534
- "button.vistaview-zoom-out-btn"
535
- ), o = parseInt(t.style.width) || t.width, c = t.naturalWidth * i.options.maxZoomLevel, a = o < c && c > 0;
536
- r && (r.style.display = a ? "" : "none"), l && (l.style.display = a ? "" : "none");
537
- }
538
- t.complete && t.naturalWidth > 0 ? n() : t.addEventListener("load", n);
539
- }
540
- loadImages() {
541
- if (!this.rootElm) return;
542
- this.rootElm.querySelectorAll(
543
- ".vistaview-image-highres:not(.vistaview-image-loaded)"
544
- ).forEach((i, n) => {
545
- const e = i, l = this.currentImages[n].imageElm, o = { w: 0, h: 0 };
546
- if (l) {
547
- const { width: a, height: d } = K(l);
548
- o.w = Math.min(l.width, a), o.h = Math.min(l.height, d);
549
- }
550
- const c = () => {
551
- var d;
552
- const a = () => {
553
- var h;
554
- o.w && o.h && (e.style.width = `${o.w}px`, e.style.height = `${o.h}px`, e.style.setProperty("--vistaview-fitted-width", `${o.w}px`), e.style.setProperty("--vistaview-fitted-height", `${o.h}px`)), e.classList.add("vistaview-image-loaded"), e.width = e.naturalWidth, e.height = e.naturalHeight, setTimeout(() => {
555
- this.setFullSizeImageDim(e);
556
- }, 100), (h = i.parentElement) != null && h.matches('[data-vistaview-pos="0"]') && this.updateZoomButtonsVisibility();
557
- };
558
- if ((d = this.rootElm) != null && d.classList.contains("vistaview--opened"))
559
- a();
560
- else {
561
- const h = setInterval(() => {
562
- var u;
563
- (u = this.rootElm) != null && u.classList.contains("vistaview--opened") && (clearInterval(h), a());
564
- }, 50);
565
- }
566
- };
567
- e.complete && e.naturalWidth > 0 ? c() : (e.onload = c, e.onerror = () => {
568
- var a;
569
- console.error("VistaView: failed to load image " + e.src), (a = e.parentElement) == null || a.classList.add("vistaview-image-load-failed");
424
+ this.onScale && this.onScale({
425
+ scale: i / (this.maxDimension.width / this.maxZoomLevel),
426
+ isMax: i >= this.maxDimension.width,
427
+ isMin: i <= this.minDimension.initialWidth
428
+ }), this.scale = C(i / this.rect.width);
429
+ const n = this.rect.left + this.rect.width / 2, o = this.rect.top + this.rect.height / 2, r = this.initialCenter.x - n, a = this.initialCenter.y - o, h = r * (1 - this.scale), c = a * (1 - this.scale), m = e.x - this.initialCenter.x, w = e.y - this.initialCenter.y;
430
+ this.translate.x = C(h + m), this.translate.y = C(c + w), this.image.style.transform = `translate3d(${this.translate.x}px, ${this.translate.y}px, 0px) scale(${this.scale})`, i <= this.minDimension.closingWidth ? this.image.style.opacity = "0.5" : this.image.style.opacity = "";
431
+ }
432
+ moveAndNormalize(t) {
433
+ let e = 0, i = !1;
434
+ const n = ({ x: o, y: r }) => {
435
+ if (i)
436
+ return;
437
+ if (Math.abs(o) < 1e-3 && Math.abs(r) < 1e-3)
438
+ return this.normalize();
439
+ o *= 0.9, r *= 0.9;
440
+ const a = this.image.getBoundingClientRect();
441
+ this.translate.x = C(this.translate.x + o), this.translate.y = C(this.translate.y + r), a.right < window.innerWidth / 2 && (this.translate.x += (window.innerWidth / 2 - a.right) * 0.1, o *= 0.7), a.left > window.innerWidth / 2 && (this.translate.x -= (a.left - window.innerWidth / 2) * 0.1, o *= 0.7), a.bottom < window.innerHeight / 2 && (this.translate.y += (window.innerHeight / 2 - a.bottom) * 0.1, r *= 0.7), a.top > window.innerHeight / 2 && (this.translate.y -= (a.top - window.innerHeight / 2) * 0.1, r *= 0.7), this.image.style.transform = `translate3d(${this.translate.x}px, ${this.translate.y}px, 0px) scale(${this.scale})`, e = requestAnimationFrame(() => n({ x: o, y: r }));
442
+ };
443
+ return n({
444
+ x: t.movementX,
445
+ y: t.movementY
446
+ }), () => {
447
+ i = !0, cancelAnimationFrame(e), this.normalize(!1);
448
+ };
449
+ }
450
+ animateZoom(t) {
451
+ if (!this.image) return;
452
+ this.rect || (this.rect = this.image.getBoundingClientRect());
453
+ const e = Date.now(), i = this.image;
454
+ this.rect.width * t < this.minDimension.closingWidth || i.width < Math.floor(this.minDimension.initialWidth) || (i.addEventListener(
455
+ "transitionend",
456
+ () => {
457
+ this.animationTimestamp === e && i && (i.style.transition = "", this.normalize());
458
+ },
459
+ { once: !0 }
460
+ ), i.style.transition || (i.style.transition = "all 222ms ease"), this.animationTimestamp = e, this.scaleMove(t));
461
+ }
462
+ normalize(t = !0) {
463
+ if (!this.image || !this.rect) return;
464
+ let e = this.rect.width * this.scale, i = this.rect.height * this.scale;
465
+ if (Math.round(e) === Math.round(this.minDimension.initialWidth) && (e = this.minDimension.initialWidth, i = this.minDimension.initialHeight), this.image.style.width = `${e}px`, this.image.style.height = `${i}px`, this.scale = 1, this.image.style.opacity = "", this.accumulatedTranslate.x += this.translate.x, this.accumulatedTranslate.y += this.translate.y, this.image.style.left = `calc(50% + ${this.accumulatedTranslate.x}px)`, this.image.style.top = `calc(50% + ${this.accumulatedTranslate.y}px)`, this.translate = { x: 0, y: 0 }, this.image.style.transform = "", this.rect = this.image.getBoundingClientRect(), e <= this.minDimension.closingWidth)
466
+ return this.clean(), !0;
467
+ if (e < this.minDimension.initialWidth)
468
+ this.accumulatedTranslate.x = 0, this.accumulatedTranslate.y = 0, requestAnimationFrame(() => {
469
+ const n = this.image;
470
+ n && (n.addEventListener(
471
+ "transitionend",
472
+ () => {
473
+ n && (this.clean(), this.rect = null);
474
+ },
475
+ { once: !0 }
476
+ ), n.style.transition = "all 222ms ease", n.style.width = `${this.minDimension.initialWidth}px`, n.style.height = `${this.minDimension.initialHeight}px`, n.style.left = "50%", n.style.top = "50%");
570
477
  });
571
- });
478
+ else if (t) {
479
+ let n = !1;
480
+ if (this.rect.right < window.innerWidth / 2 && (n = !0, this.accumulatedTranslate.x += window.innerWidth / 2 - this.rect.right), this.rect.left > window.innerWidth / 2 && (n = !0, this.accumulatedTranslate.x -= this.rect.left - window.innerWidth / 2), this.rect.bottom < window.innerHeight / 2 && (n = !0, this.accumulatedTranslate.y += window.innerHeight / 2 - this.rect.bottom), this.rect.top > window.innerHeight / 2 && (n = !0, this.accumulatedTranslate.y -= this.rect.top - window.innerHeight / 2), n) {
481
+ const o = this.image;
482
+ o.addEventListener(
483
+ "transitionend",
484
+ () => {
485
+ o && (o.style.transition = "", this.rect = null);
486
+ },
487
+ { once: !0 }
488
+ ), o.style.transition = "all 222ms ease", o.style.left = `calc(50% + ${this.accumulatedTranslate.x}px)`, o.style.top = `calc(50% + ${this.accumulatedTranslate.y}px)`;
489
+ } else
490
+ this.rect = null;
491
+ }
572
492
  }
573
- setIndexDisplay() {
574
- this.elements.length !== 1 && (this.rootElm.querySelector(".vistaview-index-display").textContent = `${this.currentIndex.value + 1} / ${this.elements.length}`);
575
- }
576
- setCurrentDescription() {
577
- this.rootElm.querySelector(".vistaview-description").textContent = (this.currentImages[1] || this.currentImages[0]).alt || "";
578
- }
579
- getCurrentIndexes(t) {
580
- const i = this.options.preloads, n = this.elements.length, e = n < 1 || !i ? [t] : [
581
- .../* @__PURE__ */ new Set([
582
- ...Array.from(
583
- { length: i },
584
- (l, o) => ((t - i + o) % n + n) % n
585
- ),
586
- t,
587
- ...Array.from({ length: i }, (l, o) => (t + 1 + o) % n)
588
- ])
589
- ], r = n < 1 || !i ? [0] : e.map((l, o) => o - Math.floor(e.length / 2));
590
- return {
591
- images: e,
592
- positions: r
493
+ }
494
+ class et {
495
+ constructor() {
496
+ l(this, "fiolast", {});
497
+ }
498
+ // first in out
499
+ fio(t, e, i = 50) {
500
+ const o = Date.now() - (this.fiolast[e] ?? 0), r = () => {
501
+ this.fiolast[e] = Date.now(), t();
593
502
  };
503
+ if (!this.fiolast[e]) {
504
+ r();
505
+ return;
506
+ }
507
+ o >= i && r();
594
508
  }
595
- setKeyboardListeners() {
596
- this.onKeyDown = (t) => {
509
+ }
510
+ const x = {
511
+ somethingOpened: null
512
+ };
513
+ class it {
514
+ constructor(t, e = {}) {
515
+ l(this, "options");
516
+ l(this, "elements");
517
+ l(this, "isReducedMotion");
518
+ l(this, "currentIndex", -1);
519
+ l(this, "currentChildren", null);
520
+ l(this, "setupFunction", K);
521
+ l(this, "initFunction", _);
522
+ l(this, "closeFunction", J);
523
+ l(this, "transitionFunction", Q);
524
+ l(this, "pointers", null);
525
+ l(this, "imageState");
526
+ l(this, "root", null);
527
+ l(this, "imageContainer", null);
528
+ l(this, "onClickElements", (t) => {
529
+ t.preventDefault();
530
+ const e = t.currentTarget;
531
+ e.dataset.vistaIdx && this.open(parseInt(e.dataset.vistaIdx));
532
+ });
533
+ l(this, "defaultOnClickHandler", (t) => t.preventDefault());
534
+ l(this, "abortController", null);
535
+ l(this, "throttle", new et());
536
+ l(this, "lastSwapTime", 0);
537
+ l(this, "isZoomedIn", !1);
538
+ l(this, "onKeyDown", (t) => {
597
539
  switch (t.key) {
598
540
  case "ArrowLeft":
599
541
  t.preventDefault(), this.prev();
@@ -611,164 +553,332 @@ class ht {
611
553
  t.preventDefault(), this.close();
612
554
  break;
613
555
  }
614
- }, window.addEventListener("keydown", this.onKeyDown);
615
- }
616
- setResizeListeners() {
617
- this.onResizeHandler = () => {
618
- var i;
619
- this.setInitialDimPos();
620
- const t = (i = this.rootElm) == null ? void 0 : i.querySelectorAll(
621
- ".vistaview-image-highres.vistaview-image-loaded"
622
- );
623
- t == null || t.forEach((n) => {
624
- const e = n, { width: r, height: l } = q(e);
625
- e.classList.contains("vistaview-image--zooming") ? (e.dataset.vistaviewInitialWidth = r.toString(), e.dataset.vistaviewInitialHeight = l.toString()) : (e.style.width = `${r}px`, e.style.height = `${l}px`);
556
+ });
557
+ l(this, "onScroll", (t) => {
558
+ t.preventDefault();
559
+ const e = t.deltaY;
560
+ this.imageState.setInitialCenter({
561
+ x: t.clientX,
562
+ y: t.clientY
563
+ }), e < 0 ? this.zoomIn() : e > 0 && this.zoomOut();
564
+ });
565
+ l(this, "onResizeHandler", () => {
566
+ this.currentChildren.htmls.forEach((t, e) => {
567
+ const i = this.currentChildren.images[e], n = t.querySelector("img.vvw-img-hi"), o = t.querySelector("img.vvw-img-lo");
568
+ if (M(i, n, o, !1), n.classList.contains("vvw--loaded")) {
569
+ const { width: r, height: a } = D(n);
570
+ n.style.setProperty("--vvw-current-w", `${r}px`), n.style.setProperty("--vvw-current-h", `${a}px`), n.dataset.vvwWidth = r.toString(), n.dataset.vvwHeight = a.toString();
571
+ }
572
+ });
573
+ });
574
+ /// POINTERS
575
+ l(this, "pointerListeners", []);
576
+ l(this, "getInternalPointerListener", () => {
577
+ const t = this.imageState;
578
+ let e = 0, i = !1, n = () => {
579
+ };
580
+ return (o) => {
581
+ if (o.event === "down") {
582
+ if (n(), this.isZoomedIn && o.pointers.length === 1) {
583
+ const r = this.pointers.getCentroid();
584
+ t.setInitialCenter(r);
585
+ }
586
+ if (o.pointers.length >= 2) {
587
+ i = !0;
588
+ const r = this.pointers.getCentroid();
589
+ e = this.pointers.getPointerDistance(o.pointers[0], o.pointers[1]), t.setInitialCenter(r);
590
+ }
591
+ } else if (o.event === "move") {
592
+ if (this.isZoomedIn && o.pointers.length === 1 && o.lastPointerLen === 0) {
593
+ const r = this.pointers.getCentroid();
594
+ t.move(r);
595
+ }
596
+ if (o.pointers.length >= 2 && i) {
597
+ const r = this.pointers.getCentroid(), a = this.pointers.getPointerDistance(o.pointers[0], o.pointers[1]);
598
+ t.scaleMove(a / e, r);
599
+ }
600
+ } else (o.event === "up" || o.event === "cancel") && (i || this.isZoomedIn) && (i ? (i = !1, t.normalize() && requestAnimationFrame(() => {
601
+ this.close();
602
+ })) : this.isZoomedIn && o.pointers.length === 0 && (n = t.moveAndNormalize(o.pointer)));
603
+ this.pointerListeners.forEach(
604
+ (r) => r({
605
+ ...o,
606
+ hasInternalExecution: this.isZoomedIn || i
607
+ })
608
+ );
609
+ };
610
+ });
611
+ this.elements = t, this.options = {
612
+ ...H,
613
+ ...e,
614
+ controls: {
615
+ ...H.controls,
616
+ ...e.controls
617
+ }
618
+ }, this.imageState = new tt(
619
+ this.options.maxZoomLevel,
620
+ (i) => {
621
+ var n, o, r, a, h, c;
622
+ i.isMin ? (this.isZoomedIn = !1, (n = this.qs(".vvw-zoom-out")) == null || n.setAttribute("disabled", "true"), (o = this.qs('.vvw-item[data-vvw-idx="' + this.currentIndex + '"]')) == null || o.style.setProperty(
623
+ "pointer-events",
624
+ "none"
625
+ )) : (this.isZoomedIn = !0, (r = this.qs(".vvw-zoom-out")) == null || r.removeAttribute("disabled"), (a = this.qs('.vvw-item[data-vvw-idx="' + this.currentIndex + '"]')) == null || a.style.setProperty(
626
+ "pointer-events",
627
+ "auto"
628
+ )), i.isMax ? (h = this.qs(".vvw-zoom-in")) == null || h.setAttribute("disabled", "true") : (c = this.qs(".vvw-zoom-in")) == null || c.removeAttribute("disabled");
629
+ }
630
+ ), this.options.setupFunction && (this.setupFunction = this.options.setupFunction), this.options.closeFunction && (this.closeFunction = this.options.closeFunction), this.options.initFunction && (this.initFunction = this.options.initFunction), this.options.transitionFunction && (this.transitionFunction = this.options.transitionFunction), this.isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches, this.elements instanceof NodeList && this.elements.forEach((i, n) => {
631
+ i.dataset.vistaIdx = n.toString(), i.addEventListener("click", this.defaultOnClickHandler), i.addEventListener("pointerup", this.onClickElements);
632
+ });
633
+ }
634
+ qs(t) {
635
+ return this.root ? this.root.querySelector(t) : null;
636
+ }
637
+ async swap(t, e) {
638
+ const i = this.options.preloads || 0, n = this.currentIndex, { htmls: o, images: r } = this.getChildElements(i, n), a = this.imageContainer, h = this.currentChildren, c = {
639
+ htmlElements: { from: h.htmls, to: o },
640
+ images: { from: h.images, to: r },
641
+ index: { from: t, to: this.currentIndex },
642
+ via: e || { next: !1, prev: !1 },
643
+ vistaView: this
644
+ };
645
+ this.setupFunction(c), this.currentChildren = { htmls: o, images: r }, this.displayActiveIndex();
646
+ const m = this.abortController.signal, w = performance.now(), L = w - this.lastSwapTime < this.options.rapidLimit;
647
+ let p = null;
648
+ L || (p = await this.transitionFunction(c, m)), this.lastSwapTime = w;
649
+ const d = o[Math.floor(o.length / 2)].dataset.vvwIdx, v = a.querySelector(
650
+ `.vvw-item[data-vvw-idx="${d}"] img.vvw-img-hi`
651
+ ), g = v.getAttribute("style") || "", f = v.classList.contains("vvw--loaded"), u = v.width, b = v.height;
652
+ this.imageState.reset(), a.innerHTML = "", p instanceof Function && p(), o.forEach((E) => {
653
+ const y = E.querySelector("img.vvw-img-hi");
654
+ E.dataset.vvwPos === "0" && !m.aborted && g && f && // ready &&
655
+ u && b && (y.classList.add("vvw--loaded"), y.classList.add("vvw--ready"), y.setAttribute("style", g), y.width = u, y.height = b, y.dataset.vvwWidth = u.toString(), y.dataset.vvwHeight = b.toString()), a.appendChild(E), y.classList.contains("vvw--ready") && (this.imageState.setCurrentImage(y), this.imageState.setInitialCenter());
656
+ }), this.waitForImagesToLoad(), this.options.onImageView && this.options.onImageView(c);
657
+ }
658
+ getChildElements(t, e) {
659
+ const i = [], n = [];
660
+ for (let o = -t; o <= t; o++) {
661
+ const r = (e + o + this.elements.length) % this.elements.length, a = this.elements[r], h = a instanceof HTMLImageElement ? a : a instanceof HTMLAnchorElement && a.querySelector("img") || void 0, c = a instanceof HTMLElement ? {
662
+ index: r,
663
+ imageElm: h instanceof HTMLImageElement ? h : void 0,
664
+ anchorElm: a instanceof HTMLAnchorElement ? a : void 0,
665
+ src: a.dataset.vistaviewSrc || a.getAttribute("href") || a.getAttribute("src") || "",
666
+ thumb: a.dataset.vistaviewThumb || (h instanceof HTMLImageElement ? h.getAttribute("src") : void 0) || a.getAttribute("href") || void 0,
667
+ alt: h instanceof HTMLImageElement && h.getAttribute("alt") || void 0
668
+ } : {
669
+ index: r,
670
+ ...a
671
+ };
672
+ n.push(c), i.push(j(c, o));
673
+ }
674
+ return {
675
+ htmls: i,
676
+ images: n
677
+ };
678
+ }
679
+ zoomIn() {
680
+ this.throttle.fio(
681
+ () => {
682
+ this.imageState.animateZoom(1.68);
683
+ },
684
+ "zoom",
685
+ 222
686
+ );
687
+ }
688
+ zoomOut() {
689
+ this.throttle.fio(
690
+ () => {
691
+ this.imageState.animateZoom(0.68);
692
+ },
693
+ "zoom",
694
+ 222
695
+ );
696
+ }
697
+ displayActiveIndex() {
698
+ var n;
699
+ const t = this.currentIndex;
700
+ this.elements instanceof NodeList && this.elements.forEach((o, r) => {
701
+ o.style.opacity = "", r === t && (o.style.opacity = "0");
702
+ });
703
+ const e = this.qs(".vvw-index");
704
+ e && (e.textContent = `${t + 1} / ${this.elements.length}`);
705
+ const i = this.qs(".vvw-desc");
706
+ if (i) {
707
+ const o = (n = this.currentChildren) == null ? void 0 : n.images.find((r) => r.index === t);
708
+ o && o.alt ? i.textContent = o.alt : i.textContent = "";
709
+ }
710
+ }
711
+ waitForImagesToLoad() {
712
+ this.imageContainer.querySelectorAll("img.vvw-img-hi:not(.vvw--loaded)").forEach((i) => {
713
+ const n = i, o = () => {
714
+ var a;
715
+ n.width = n.naturalWidth, n.height = n.naturalHeight;
716
+ const r = (a = n.parentElement) == null ? void 0 : a.matches(`[data-vvw-idx="${this.currentIndex}"]`);
717
+ n.addEventListener(
718
+ "transitionend",
719
+ () => {
720
+ r && (this.imageState.setCurrentImage(n), this.imageState.setInitialCenter()), n.classList.add("vvw--ready");
721
+ },
722
+ { once: !0 }
723
+ ), n.classList.add("vvw--loaded"), requestAnimationFrame(() => {
724
+ const { width: h, height: c } = D(n);
725
+ n.style.setProperty("--vvw-current-w", `${h}px`), n.style.setProperty("--vvw-current-h", `${c}px`), n.dataset.vvwWidth = h.toString(), n.dataset.vvwHeight = c.toString(), n.style.setProperty("--vvw-current-radius", "0px");
726
+ });
727
+ };
728
+ if (n.complete && n.naturalWidth !== 0) {
729
+ o();
730
+ return;
731
+ }
732
+ n.addEventListener("load", () => {
733
+ o();
734
+ }), n.addEventListener("error", () => {
735
+ n.classList.add("vvw--loaderror");
626
736
  });
627
- }, window.addEventListener("resize", this.onResizeHandler);
737
+ });
738
+ }
739
+ registerPointerListener(t) {
740
+ this.pointerListeners.push(t);
741
+ }
742
+ unregisterPointerListeners() {
743
+ this.pointerListeners = [];
628
744
  }
745
+ /// OPEN
629
746
  open(t = 0) {
630
- var o, c, a, d, h, u, w, f, v, y, b, L, C;
631
- if (S.somethingOpened) {
632
- console.error("VistaView: another instance is already opened. Returning.");
747
+ var c, m, w, L, p;
748
+ if (x.somethingOpened)
633
749
  return;
634
- }
635
- if (S.somethingOpened = this, this.currentIndex._value = t, document.body.prepend(
636
- ot({
637
- controls: this.options.controls,
638
- isReducedMotion: this.isReducedMotion
639
- })
640
- ), this.rootElm = document.querySelector("#vistaview-root"), this.imageContainerElm = ((o = this.rootElm) == null ? void 0 : o.querySelector(".vistaview-image-container")) || null, !this.rootElm || !this.imageContainerElm)
641
- throw S.somethingOpened = null, new Error("Failed to create VistaView element");
642
- this.options.arrowOnSmallScreens || this.rootElm.classList.add("vistaview-no-arrows-sm");
643
- const { images: i, positions: n } = this.getCurrentIndexes(t);
644
- this.currentImages = this.getImages(i);
645
- const e = this.currentImages.map((E, m) => k(E, n[m]));
646
- this.currentItems = e;
647
- const r = {
648
- htmlElements: { from: null, to: this.currentItems },
649
- images: { from: null, to: this.currentImages },
650
- index: { from: null, to: t },
651
- via: this.currentIndex.via,
750
+ x.somethingOpened = this, this.currentIndex = t, document.body.style.overflow = "hidden";
751
+ const e = U({
752
+ controls: this.options.controls
753
+ });
754
+ if (document.body.prepend(e), this.root = document.body.querySelector("#vvw-root"), !this.root)
755
+ throw new Error("Failed to setup VistaView root element.");
756
+ this.imageContainer = this.qs(".vvw-image-container"), this.options.animationDurationBase && this.root.style.setProperty("--vvw-anim-dur", `${this.options.animationDurationBase}`), this.options.initialZIndex !== void 0 && this.root.style.setProperty("--vvw-init-z", `${this.options.initialZIndex}`);
757
+ const i = this.options.preloads || 0, n = t, { images: o, htmls: r } = this.getChildElements(i, n), a = {
758
+ htmlElements: { from: null, to: r },
759
+ images: { from: null, to: o },
760
+ index: { from: null, to: this.currentIndex },
761
+ via: { next: !1, prev: !1 },
652
762
  vistaView: this
653
763
  };
654
- this.userSetup(r), this.imageContainerElm.innerHTML = "", this.currentItems.forEach((E) => {
655
- this.imageContainerElm.appendChild(E);
764
+ this.setupFunction(a), this.currentChildren = { htmls: r, images: o }, r.forEach((d) => {
765
+ this.imageContainer.appendChild(d);
766
+ }), (c = this.qs(".vvw-close")) == null || c.addEventListener("click", () => this.close()), (m = this.qs(".vvw-zoom-in")) == null || m.addEventListener("click", () => this.zoomIn()), (w = this.qs(".vvw-zoom-out")) == null || w.addEventListener("click", () => this.zoomOut()), (L = this.qs(".vvw-prev>button")) == null || L.addEventListener("click", () => this.prev()), (p = this.qs(".vvw-next>button")) == null || p.addEventListener("click", () => this.next()), window.addEventListener("keydown", this.onKeyDown), window.addEventListener("wheel", this.onScroll, { passive: !1 }), window.addEventListener("resize", this.onResizeHandler), this.pointers = new V({
767
+ elm: this.imageContainer,
768
+ listeners: [this.getInternalPointerListener()]
656
769
  });
657
- let l = 0;
658
- this.rootElm.addEventListener("animationend", (E) => {
659
- var m;
660
- E.currentTarget === this.rootElm && (l++, l >= 2 && ((m = this.rootElm) == null || m.classList.add("vistaview--opened")));
661
- }), (c = this.rootElm.querySelector(".vistaview-close-btn")) == null || c.addEventListener("click", () => this.close()), (a = this.rootElm.querySelector(".vistaview-zoom-in-btn")) == null || a.addEventListener("click", () => this.zoomIn()), (d = this.rootElm.querySelector(".vistaview-zoom-out-btn")) == null || d.addEventListener("click", () => this.zoomOut()), (h = this.rootElm.querySelector(".vistaview-prev-btn>button")) == null || h.addEventListener("click", () => this.prev()), (u = this.rootElm.querySelector(".vistaview-next-btn>button")) == null || u.addEventListener("click", () => this.next()), [
770
+ const h = {};
771
+ [
662
772
  ...this.options.controls.topLeft || [],
663
773
  ...this.options.controls.topRight || [],
664
774
  ...this.options.controls.topCenter || [],
665
775
  ...this.options.controls.bottomCenter || [],
666
776
  ...this.options.controls.bottomLeft || [],
667
777
  ...this.options.controls.bottomRight || []
668
- ].forEach((E) => {
669
- typeof E != "string" && (this.customControls[E.name] = E);
670
- }), this.rootElm.querySelectorAll("button[data-vistaview-custom-control]").forEach((E) => {
671
- E.addEventListener("click", (m) => {
672
- const g = this.customControls[m.currentTarget.dataset.vistaviewCustomControl], x = this.currentImages.find(
673
- (I) => I.index === this.currentIndex.value
778
+ ].forEach((d) => {
779
+ typeof d != "string" && (h[d.name] = d);
780
+ }), this.root.querySelectorAll("button[data-vvw-control]").forEach((d) => {
781
+ const v = d;
782
+ v.addEventListener("click", (g) => {
783
+ const f = g.currentTarget.dataset.vvwControl, u = h[f], b = this.currentChildren.images.find(
784
+ (E) => E.index === this.currentIndex
674
785
  );
675
- g && x && (g.onClick.constructor.name === "AsyncFunction" ? (E.classList.add("vistaview-button--loading"), g.onClick(x).finally(() => {
676
- E.classList.remove("vistaview-button--loading");
677
- })) : g.onClick(x));
678
- });
679
- }), this.options.animationDurationBase && this.rootElm.style.setProperty(
680
- "--vistaview-animation-duration",
681
- `${this.options.animationDurationBase}`
682
- ), this.options.initialZIndex !== void 0 && this.rootElm.style.setProperty(
683
- "--vistaview-initial-z-index",
684
- `${this.options.initialZIndex}`
685
- ), this.setInitialDimPos(), this.setResizeListeners(), this.options.keyboardListeners && this.setKeyboardListeners(), this.elements.length === 1 && ((w = this.rootElm.querySelector(".vistaview-prev-btn")) == null || w.classList.add("vistaview-ui--none"), (f = this.rootElm.querySelector(".vistaview-next-btn")) == null || f.classList.add("vistaview-ui--none"), (v = this.rootElm.querySelector(".vistaview-index-display")) == null || v.classList.add("vistaview-ui--none")), this.rootElm && this.rootElm.classList.add("vistaview--initialized"), this.loadImages(), this.setCurrentDescription(), this.setIndexDisplay(), this.userInit(this), (b = (y = this.options).onOpen) == null || b.call(y, r), (C = (L = this.options).onImageView) == null || C.call(L, r);
686
- }
687
- async close(t = !0) {
688
- var n, e, r;
689
- if (S.somethingOpened !== this) return;
690
- t && ((n = this.rootElm) == null || n.classList.add("vistaview--closing"), await new Promise((l) => {
691
- var c;
692
- let o;
693
- (c = this.rootElm) == null || c.addEventListener("transitionend", (a) => {
694
- a.currentTarget === this.rootElm && (o && clearTimeout(o), o = setTimeout(() => {
695
- l();
696
- }, 333));
786
+ u && b && (u.onClick.constructor.name === "AsyncFunction" ? (v.classList.add("vvw--loading"), u.onClick(b, this).finally(() => {
787
+ v.classList.remove("vvw--loading");
788
+ })) : u.onClick(b, this));
697
789
  });
698
- }));
699
- const i = {
700
- htmlElements: { from: this.currentItems, to: null },
701
- images: { from: this.currentImages, to: null },
702
- index: { from: this.currentIndex.value, to: null },
703
- via: { prev: !1, next: !1 },
704
- vistaView: this
705
- };
706
- this.userClose(this), (r = (e = this.options).onClose) == null || r.call(e, i), 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.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);
707
- for (const l in this.transitionAbortControllers)
708
- this.transitionAbortControllers[l].abort();
709
- this.transitionAbortControllers = {}, S.somethingOpened = null;
710
- }
711
- destroy() {
712
- this.close(!1), this.elements instanceof NodeList && this.elements.forEach((t) => {
713
- t.dataset.vistaviewIndex && delete t.dataset.vistaviewIndex, t.removeEventListener("click", this.defaultOnClickHandler), t.removeEventListener("pointerup", this.onClickElements);
790
+ }), this.initFunction(this), requestAnimationFrame(() => {
791
+ var d;
792
+ (d = this.root) == null || d.addEventListener(
793
+ "transitionend",
794
+ () => {
795
+ var v, g;
796
+ (v = this.root) == null || v.classList.add("vvw--settled"), this.waitForImagesToLoad(), (g = this.qs(".vvw-bg")) == null || g.addEventListener("click", (f) => {
797
+ f.preventDefault(), this.close();
798
+ }), this.imageState.reset();
799
+ },
800
+ { once: !0 }
801
+ ), this.root.classList.add("vvw--active"), this.displayActiveIndex(), this.options.onOpen && this.options.onOpen(this), this.options.onImageView && this.options.onImageView(a);
714
802
  });
715
803
  }
716
- view(t, i) {
717
- S.somethingOpened === this && (t < 0 && (t = this.elements.length - 1), t >= this.elements.length && (t = 0), this.currentIndex.via = i || { next: !1, prev: !1 }, this.currentIndex.value = t);
804
+ /// CLOSE
805
+ async close(t = !0) {
806
+ x.somethingOpened === this && this.root && (t ? await new Promise((e) => {
807
+ let n = 0;
808
+ this.root.addEventListener("transitionend", (o) => {
809
+ o.target === this.root && (n++, n === 2 && this.elements instanceof NodeList && this.elements.forEach((r) => {
810
+ r.style.opacity = "";
811
+ }), n === 3 && e(null));
812
+ }), this.root.classList.add("vvw--closing");
813
+ }) : this.elements instanceof NodeList && this.elements.forEach((e) => {
814
+ e.style.opacity = "";
815
+ }), window.removeEventListener("keydown", this.onKeyDown), window.removeEventListener("resize", this.onResizeHandler), window.removeEventListener("wheel", this.onScroll), this.unregisterPointerListeners(), this.pointers.removeListeners(), this.root.remove(), this.root = null, this.imageContainer = null, this.currentChildren = null, this.currentIndex = -1, document.body.style.overflow = "", x.somethingOpened = null, this.closeFunction(this), this.options.onClose && this.options.onClose(this));
718
816
  }
719
817
  next() {
720
- S.somethingOpened === this && this.view(this.currentIndex.value + 1, { next: !0, prev: !1 });
818
+ if (x.somethingOpened !== this)
819
+ return;
820
+ const t = (this.currentIndex + 1) % this.elements.length;
821
+ this.view(t, { next: !0, prev: !1 });
721
822
  }
722
823
  prev() {
723
- S.somethingOpened === this && this.view(this.currentIndex.value - 1, { next: !1, prev: !0 });
824
+ if (x.somethingOpened !== this)
825
+ return;
826
+ const t = (this.currentIndex - 1 + this.elements.length) % this.elements.length;
827
+ this.view(t, { next: !1, prev: !0 });
828
+ }
829
+ destroy() {
830
+ this.close(!1), this.elements instanceof NodeList && this.elements.forEach((t) => {
831
+ t.removeAttribute("data-vista-idx"), t.removeEventListener("click", this.defaultOnClickHandler), t.removeEventListener("pointerup", this.onClickElements);
832
+ });
724
833
  }
725
834
  getCurrentIndex() {
726
- return S.somethingOpened === this ? this.currentIndex.value : -1;
835
+ return x.somethingOpened !== this ? -1 : this.currentIndex;
836
+ }
837
+ view(t, e) {
838
+ if (x.somethingOpened !== this || t < 0 || t >= this.elements.length)
839
+ return;
840
+ const i = this.currentIndex;
841
+ this.currentIndex = t;
842
+ const n = this.abortController;
843
+ n == null || n.abort(), this.abortController = new AbortController(), this.swap(i, e);
727
844
  }
728
845
  }
729
- function ut(s) {
846
+ function nt(s) {
730
847
  let t = null;
731
848
  if (typeof s == "string" ? t = document.querySelectorAll(s) : s instanceof NodeList && (t = s), t)
732
- for (let i = 0; i < t.length; i++) {
733
- const n = t[i];
734
- if (!(n.dataset.vistaviewSrc || n.getAttribute("href") || n.getAttribute("src") || ""))
735
- return `Element at index ${i} is missing 'src' / 'data-vistaview-src' / 'href' attribute.`;
849
+ for (let e = 0; e < t.length; e++) {
850
+ const i = t[e];
851
+ if (!(i.dataset.vistaviewSrc || i.getAttribute("href") || i.getAttribute("src") || ""))
852
+ return `Element at index ${e} is missing 'src' / 'data-vistaview-src' / 'href' attribute.`;
736
853
  }
737
854
  else {
738
- const i = s;
739
- for (let n = 0; n < i.length; n++)
740
- if (!i[n].src)
741
- return `Element at index ${n} is missing 'src' attribute.`;
855
+ const e = s;
856
+ for (let i = 0; i < e.length; i++)
857
+ if (!e[i].src)
858
+ return `Element at index ${i} is missing 'src' attribute.`;
742
859
  }
743
860
  return t || s;
744
861
  }
745
- function mt({ elements: s, ...t }) {
862
+ function ot({ elements: s, ...t }) {
746
863
  if (!s) throw new Error("No elements");
747
- let i = ut(s);
748
- if (typeof i == "string")
749
- return console.error(i), console.warn("VistaView: silently returning."), null;
750
- const n = new ht(i, t);
864
+ let e = nt(s);
865
+ if (typeof e == "string")
866
+ return null;
867
+ const i = new it(e, t);
751
868
  return {
752
- open: (e = 0) => n.open(e),
753
- close: () => n.close(),
754
- next: () => n.next(),
755
- prev: () => n.prev(),
756
- destroy: () => n.destroy(),
757
- getCurrentIndex: () => n.getCurrentIndex(),
758
- view: (e) => {
759
- n.view(e);
869
+ open: (n = 0) => i.open(n),
870
+ close: () => i.close(),
871
+ next: () => i.next(),
872
+ prev: () => i.prev(),
873
+ destroy: () => i.destroy(),
874
+ getCurrentIndex: () => i.getCurrentIndex(),
875
+ view: (n) => {
876
+ i.view(n);
760
877
  }
761
878
  };
762
879
  }
763
880
  export {
764
- W as DefaultOptions,
765
- z as VistaViewTransitionAbortedError,
766
- ct as defaultClose,
767
- at as defaultInit,
768
- lt as defaultSetup,
769
- dt as defaultTransition,
770
- F as removeTouchActions,
771
- rt as setTouchActions,
772
- mt as vistaView,
773
- nt as vistaViewDownload
881
+ H as DefaultOptions,
882
+ ot as vistaView,
883
+ B as vistaViewDownload
774
884
  };