js-cloudimage-before-after 1.0.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.
- package/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/a11y/aria.d.ts +4 -0
- package/dist/a11y/keyboard.d.ts +22 -0
- package/dist/animation/entrance.d.ts +18 -0
- package/dist/core/ci-before-after.d.ts +64 -0
- package/dist/core/config.d.ts +3 -0
- package/dist/core/types.d.ts +127 -0
- package/dist/fullscreen/fullscreen.d.ts +16 -0
- package/dist/index.d.ts +10 -0
- package/dist/js-cloudimage-before-after.cjs.js +2 -0
- package/dist/js-cloudimage-before-after.cjs.js.map +1 -0
- package/dist/js-cloudimage-before-after.esm.js +1210 -0
- package/dist/js-cloudimage-before-after.esm.js.map +1 -0
- package/dist/js-cloudimage-before-after.min.js +2 -0
- package/dist/js-cloudimage-before-after.min.js.map +1 -0
- package/dist/labels/labels.d.ts +6 -0
- package/dist/react/ci-before-after-viewer.d.ts +3 -0
- package/dist/react/index.cjs +2 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +179 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/types.d.ts +11 -0
- package/dist/react/use-ci-before-after.d.ts +5 -0
- package/dist/slider/gestures.d.ts +31 -0
- package/dist/slider/handle.d.ts +2 -0
- package/dist/slider/slider.d.ts +11 -0
- package/dist/utils/cloudimage.d.ts +2 -0
- package/dist/utils/dom.d.ts +8 -0
- package/dist/utils/events.d.ts +12 -0
- package/dist/zoom/controls.d.ts +12 -0
- package/dist/zoom/gestures.d.ts +21 -0
- package/dist/zoom/scroll-hint.d.ts +7 -0
- package/dist/zoom/zoom-pan.d.ts +40 -0
- package/package.json +69 -0
|
@@ -0,0 +1,1210 @@
|
|
|
1
|
+
const he = ["drag", "hover", "click"], fe = ["horizontal", "vertical"], de = ["light", "dark"], me = ["arrows", "circle", "line"], be = ["top", "bottom"], ue = [
|
|
2
|
+
"top-left",
|
|
3
|
+
"top-center",
|
|
4
|
+
"top-right",
|
|
5
|
+
"bottom-left",
|
|
6
|
+
"bottom-center",
|
|
7
|
+
"bottom-right"
|
|
8
|
+
], d = {
|
|
9
|
+
beforeAlt: "Before",
|
|
10
|
+
afterAlt: "After",
|
|
11
|
+
mode: "drag",
|
|
12
|
+
orientation: "horizontal",
|
|
13
|
+
initialPosition: 50,
|
|
14
|
+
zoom: !1,
|
|
15
|
+
zoomMax: 4,
|
|
16
|
+
zoomMin: 1,
|
|
17
|
+
theme: "light",
|
|
18
|
+
handleStyle: "arrows",
|
|
19
|
+
labelPosition: "top",
|
|
20
|
+
animateOnce: !0,
|
|
21
|
+
fullscreenButton: !0,
|
|
22
|
+
lazyLoad: !0,
|
|
23
|
+
zoomControls: !0,
|
|
24
|
+
zoomControlsPosition: "bottom-right",
|
|
25
|
+
scrollHint: !0,
|
|
26
|
+
keyboardStep: 1,
|
|
27
|
+
keyboardLargeStep: 10
|
|
28
|
+
};
|
|
29
|
+
function G(o) {
|
|
30
|
+
const e = o.labels;
|
|
31
|
+
let t = !0, i = "Before", n = "After";
|
|
32
|
+
e === !1 ? t = !1 : typeof e == "object" && (i = e.before ?? "Before", n = e.after ?? "After");
|
|
33
|
+
const r = o.animate;
|
|
34
|
+
let s = !1, l = 800, a = 0, c = "ease-out";
|
|
35
|
+
r === !0 ? s = !0 : typeof r == "object" && (s = !0, l = Math.max(0, r.duration ?? 800), a = Math.max(0, r.delay ?? 0), c = r.easing ?? "ease-out");
|
|
36
|
+
const h = o.zoom ?? d.zoom;
|
|
37
|
+
return {
|
|
38
|
+
beforeSrc: o.beforeSrc,
|
|
39
|
+
afterSrc: o.afterSrc,
|
|
40
|
+
beforeAlt: o.beforeAlt ?? d.beforeAlt,
|
|
41
|
+
afterAlt: o.afterAlt ?? d.afterAlt,
|
|
42
|
+
mode: z(o.mode, he, d.mode, "mode"),
|
|
43
|
+
orientation: z(o.orientation, fe, d.orientation, "orientation"),
|
|
44
|
+
initialPosition: ve(o.initialPosition ?? d.initialPosition),
|
|
45
|
+
zoom: h,
|
|
46
|
+
zoomMax: Math.max(1, o.zoomMax ?? d.zoomMax),
|
|
47
|
+
zoomMin: Math.max(1, Math.min(o.zoomMin ?? d.zoomMin, o.zoomMax ?? d.zoomMax)),
|
|
48
|
+
theme: z(o.theme, de, d.theme, "theme"),
|
|
49
|
+
handleStyle: z(o.handleStyle, me, d.handleStyle, "handleStyle"),
|
|
50
|
+
labelsEnabled: t,
|
|
51
|
+
labelBefore: i,
|
|
52
|
+
labelAfter: n,
|
|
53
|
+
labelPosition: z(o.labelPosition, be, d.labelPosition, "labelPosition"),
|
|
54
|
+
animateEnabled: s,
|
|
55
|
+
animateDuration: l,
|
|
56
|
+
animateDelay: a,
|
|
57
|
+
animateEasing: c,
|
|
58
|
+
animateOnce: o.animateOnce ?? d.animateOnce,
|
|
59
|
+
fullscreenButton: o.fullscreenButton ?? d.fullscreenButton,
|
|
60
|
+
lazyLoad: o.lazyLoad ?? d.lazyLoad,
|
|
61
|
+
zoomControls: o.zoomControls ?? (h ? d.zoomControls : !1),
|
|
62
|
+
zoomControlsPosition: z(o.zoomControlsPosition, ue, d.zoomControlsPosition, "zoomControlsPosition"),
|
|
63
|
+
scrollHint: o.scrollHint ?? (h ? d.scrollHint : !1),
|
|
64
|
+
keyboardStep: Math.max(0.5, o.keyboardStep ?? d.keyboardStep),
|
|
65
|
+
keyboardLargeStep: Math.max(1, o.keyboardLargeStep ?? d.keyboardLargeStep),
|
|
66
|
+
onSlide: o.onSlide,
|
|
67
|
+
onZoom: o.onZoom,
|
|
68
|
+
onFullscreenChange: o.onFullscreenChange,
|
|
69
|
+
onReady: o.onReady,
|
|
70
|
+
cloudimage: o.cloudimage
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function w(o, e, t) {
|
|
74
|
+
if (e.includes(o)) return o;
|
|
75
|
+
console.warn(`CIBeforeAfter: Invalid ${t} "${o}". Allowed: ${e.join(", ")}`);
|
|
76
|
+
}
|
|
77
|
+
function z(o, e, t, i) {
|
|
78
|
+
return o === void 0 ? t : e.includes(o) ? o : (console.warn(`CIBeforeAfter: Invalid ${i} "${o}". Allowed: ${e.join(", ")}. Using default "${t}".`), t);
|
|
79
|
+
}
|
|
80
|
+
function pe(o) {
|
|
81
|
+
const e = (k) => o.getAttribute(`data-ci-before-after-${k}`), t = (k) => {
|
|
82
|
+
const x = e(k);
|
|
83
|
+
if (x !== null)
|
|
84
|
+
return x === "true";
|
|
85
|
+
}, i = (k) => {
|
|
86
|
+
const x = e(k);
|
|
87
|
+
if (x === null) return;
|
|
88
|
+
const _ = parseFloat(x);
|
|
89
|
+
return isNaN(_) ? void 0 : _;
|
|
90
|
+
}, n = e("before-src"), r = e("after-src");
|
|
91
|
+
if (!n || !r)
|
|
92
|
+
throw new Error("CIBeforeAfter: data-ci-before-after-before-src and data-ci-before-after-after-src are required");
|
|
93
|
+
const s = {
|
|
94
|
+
beforeSrc: n,
|
|
95
|
+
afterSrc: r
|
|
96
|
+
}, l = e("before-alt");
|
|
97
|
+
l !== null && (s.beforeAlt = l);
|
|
98
|
+
const a = e("after-alt");
|
|
99
|
+
a !== null && (s.afterAlt = a);
|
|
100
|
+
const c = e("mode");
|
|
101
|
+
c && (s.mode = w(c, he, "mode"));
|
|
102
|
+
const h = e("orientation");
|
|
103
|
+
h && (s.orientation = w(h, fe, "orientation"));
|
|
104
|
+
const m = i("initial-position");
|
|
105
|
+
m !== void 0 && (s.initialPosition = m);
|
|
106
|
+
const b = t("zoom");
|
|
107
|
+
b !== void 0 && (s.zoom = b);
|
|
108
|
+
const p = i("zoom-max");
|
|
109
|
+
p !== void 0 && (s.zoomMax = p);
|
|
110
|
+
const g = i("zoom-min");
|
|
111
|
+
g !== void 0 && (s.zoomMin = g);
|
|
112
|
+
const u = e("theme");
|
|
113
|
+
u && (s.theme = w(u, de, "theme"));
|
|
114
|
+
const y = e("handle-style");
|
|
115
|
+
y && (s.handleStyle = w(y, me, "handleStyle"));
|
|
116
|
+
const P = t("labels"), C = e("label-before"), T = e("label-after");
|
|
117
|
+
P === !1 ? s.labels = !1 : C !== null || T !== null ? s.labels = {
|
|
118
|
+
before: C ?? void 0,
|
|
119
|
+
after: T ?? void 0
|
|
120
|
+
} : P === !0 && (s.labels = !0);
|
|
121
|
+
const O = e("label-position");
|
|
122
|
+
O && (s.labelPosition = w(O, be, "labelPosition"));
|
|
123
|
+
const D = t("animate"), Z = i("animate-duration"), H = i("animate-delay"), A = e("animate-easing");
|
|
124
|
+
Z !== void 0 || H !== void 0 || A != null ? s.animate = {
|
|
125
|
+
duration: Z,
|
|
126
|
+
delay: H,
|
|
127
|
+
easing: A ?? void 0
|
|
128
|
+
} : D !== void 0 && (s.animate = D);
|
|
129
|
+
const B = t("animate-once");
|
|
130
|
+
B !== void 0 && (s.animateOnce = B);
|
|
131
|
+
const R = t("fullscreen-button");
|
|
132
|
+
R !== void 0 && (s.fullscreenButton = R);
|
|
133
|
+
const $ = t("lazy-load");
|
|
134
|
+
$ !== void 0 && (s.lazyLoad = $);
|
|
135
|
+
const F = t("zoom-controls");
|
|
136
|
+
F !== void 0 && (s.zoomControls = F);
|
|
137
|
+
const Y = e("zoom-controls-position");
|
|
138
|
+
Y && (s.zoomControlsPosition = w(Y, ue, "zoomControlsPosition"));
|
|
139
|
+
const X = t("scroll-hint");
|
|
140
|
+
X !== void 0 && (s.scrollHint = X);
|
|
141
|
+
const W = i("keyboard-step");
|
|
142
|
+
W !== void 0 && (s.keyboardStep = W);
|
|
143
|
+
const N = i("keyboard-large-step");
|
|
144
|
+
N !== void 0 && (s.keyboardLargeStep = N);
|
|
145
|
+
const j = e("ci-token");
|
|
146
|
+
return j && (s.cloudimage = {
|
|
147
|
+
token: j,
|
|
148
|
+
apiVersion: e("ci-api-version") ?? void 0,
|
|
149
|
+
domain: e("ci-domain") ?? void 0,
|
|
150
|
+
limitFactor: i("ci-limit-factor"),
|
|
151
|
+
params: e("ci-params") ?? void 0
|
|
152
|
+
}), s;
|
|
153
|
+
}
|
|
154
|
+
function ve(o) {
|
|
155
|
+
return isFinite(o) ? Math.max(0, Math.min(100, o)) : 50;
|
|
156
|
+
}
|
|
157
|
+
const V = "ci-before-after-styles";
|
|
158
|
+
function U(o) {
|
|
159
|
+
if (!S() || document.getElementById(V)) return;
|
|
160
|
+
const e = document.createElement("style");
|
|
161
|
+
e.id = V, e.textContent = o, document.head.appendChild(e);
|
|
162
|
+
}
|
|
163
|
+
function f(o, e, t) {
|
|
164
|
+
const i = document.createElement(o);
|
|
165
|
+
if (e && (i.className = e), t)
|
|
166
|
+
for (const [n, r] of Object.entries(t))
|
|
167
|
+
i.setAttribute(n, r);
|
|
168
|
+
return i;
|
|
169
|
+
}
|
|
170
|
+
function we(o) {
|
|
171
|
+
if (typeof o == "string") {
|
|
172
|
+
const e = document.querySelector(o);
|
|
173
|
+
if (!e)
|
|
174
|
+
throw new Error(`CIBeforeAfter: Element not found for selector "${o}"`);
|
|
175
|
+
return e;
|
|
176
|
+
}
|
|
177
|
+
return o;
|
|
178
|
+
}
|
|
179
|
+
function S() {
|
|
180
|
+
return typeof window < "u" && typeof document < "u";
|
|
181
|
+
}
|
|
182
|
+
function I() {
|
|
183
|
+
if (!S()) return !1;
|
|
184
|
+
const o = document;
|
|
185
|
+
return !!(o.fullscreenEnabled || o.webkitFullscreenEnabled);
|
|
186
|
+
}
|
|
187
|
+
function ze(o) {
|
|
188
|
+
const e = o;
|
|
189
|
+
return e.requestFullscreen ? e.requestFullscreen() : e.webkitRequestFullscreen ? e.webkitRequestFullscreen() : Promise.reject(new Error("Fullscreen API not supported"));
|
|
190
|
+
}
|
|
191
|
+
function q() {
|
|
192
|
+
const o = document;
|
|
193
|
+
return o.exitFullscreen ? o.exitFullscreen() : o.webkitExitFullscreen ? o.webkitExitFullscreen() : Promise.reject(new Error("Fullscreen API not supported"));
|
|
194
|
+
}
|
|
195
|
+
function K() {
|
|
196
|
+
const o = document;
|
|
197
|
+
return o.fullscreenElement || o.webkitFullscreenElement || null;
|
|
198
|
+
}
|
|
199
|
+
class v {
|
|
200
|
+
constructor() {
|
|
201
|
+
this.cleanups = [];
|
|
202
|
+
}
|
|
203
|
+
on(e, t, i, n) {
|
|
204
|
+
e.addEventListener(t, i, n), this.cleanups.push(() => e.removeEventListener(t, i, n));
|
|
205
|
+
}
|
|
206
|
+
onPassive(e, t, i) {
|
|
207
|
+
this.on(e, t, i, { passive: !0 });
|
|
208
|
+
}
|
|
209
|
+
onNonPassive(e, t, i) {
|
|
210
|
+
this.on(e, t, i, { passive: !1 });
|
|
211
|
+
}
|
|
212
|
+
destroy() {
|
|
213
|
+
for (const e of this.cleanups)
|
|
214
|
+
e();
|
|
215
|
+
this.cleanups = [];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function ye(o, e) {
|
|
219
|
+
var n;
|
|
220
|
+
let t, i;
|
|
221
|
+
if ("touches" in o) {
|
|
222
|
+
const r = o.touches[0] || ((n = o.changedTouches) == null ? void 0 : n[0]);
|
|
223
|
+
if (!r) return { x: 0, y: 0 };
|
|
224
|
+
t = r.clientX, i = r.clientY;
|
|
225
|
+
} else
|
|
226
|
+
t = o.clientX, i = o.clientY;
|
|
227
|
+
return {
|
|
228
|
+
x: t - e.left,
|
|
229
|
+
y: i - e.top
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function E(o, e, t) {
|
|
233
|
+
const { x: i, y: n } = ye(o, e), r = t === "horizontal" ? e.width : e.height;
|
|
234
|
+
return r === 0 ? 50 : Math.max(0, Math.min(100, (t === "horizontal" ? i : n) / r * 100));
|
|
235
|
+
}
|
|
236
|
+
const Pe = /^[a-zA-Z0-9_-]+$/, Ce = /^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/, ke = /^v\d+$/;
|
|
237
|
+
function xe(o) {
|
|
238
|
+
if (!Pe.test(o.token))
|
|
239
|
+
throw new Error(`CIBeforeAfter: Invalid cloudimage token "${o.token}". Must match [a-zA-Z0-9_-]+`);
|
|
240
|
+
if (o.domain && !Ce.test(o.domain))
|
|
241
|
+
throw new Error(`CIBeforeAfter: Invalid cloudimage domain "${o.domain}".`);
|
|
242
|
+
if (o.apiVersion && !ke.test(o.apiVersion))
|
|
243
|
+
throw new Error(`CIBeforeAfter: Invalid cloudimage apiVersion "${o.apiVersion}". Must be "v" followed by digits.`);
|
|
244
|
+
}
|
|
245
|
+
function Le(o, e, t) {
|
|
246
|
+
xe(t);
|
|
247
|
+
const {
|
|
248
|
+
token: i,
|
|
249
|
+
apiVersion: n = "v7",
|
|
250
|
+
domain: r = "cloudimg.io",
|
|
251
|
+
limitFactor: s = 100,
|
|
252
|
+
params: l = "",
|
|
253
|
+
devicePixelRatioList: a = [1, 1.5, 2]
|
|
254
|
+
} = t, c = typeof window < "u" && window.devicePixelRatio || 1, m = (a.length > 0 ? a : [1]).reduce(
|
|
255
|
+
(P, C) => Math.abs(C - c) < Math.abs(P - c) ? C : P
|
|
256
|
+
), b = s > 0 ? s : 100, p = e * m, g = Math.ceil(p / b) * b, u = `https://${i}.${r}/${n}`, y = l ? `?${l}&w=${g}` : `?w=${g}`;
|
|
257
|
+
return o.startsWith("http://") || o.startsWith("https://") ? `${u}/${o}${y}` : `${u}/${o}${y}`;
|
|
258
|
+
}
|
|
259
|
+
function M(o, e, t, i) {
|
|
260
|
+
let n = e;
|
|
261
|
+
i && i.level > 1 && (t === "horizontal" ? n = e / i.level - i.panX * 100 / (i.level * i.containerWidth) : n = e / i.level - i.panY * 100 / (i.level * i.containerHeight), n = Math.max(0, Math.min(100, n)));
|
|
262
|
+
const r = t === "horizontal" ? `inset(0 0 0 ${n}%)` : `inset(${n}% 0 0 0)`;
|
|
263
|
+
o.style.clipPath = r, o.style.setProperty("-webkit-clip-path", r);
|
|
264
|
+
}
|
|
265
|
+
function Ee(o, e, t) {
|
|
266
|
+
t === "horizontal" ? (o.style.left = `${e}%`, o.style.top = "") : (o.style.top = `${e}%`, o.style.left = "");
|
|
267
|
+
}
|
|
268
|
+
function J(o) {
|
|
269
|
+
return isFinite(o) ? Math.max(0, Math.min(100, o)) : 50;
|
|
270
|
+
}
|
|
271
|
+
const Ae = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg>', Ie = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>', Me = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>', Se = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>', Te = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 8 22 12 18 16"/><polyline points="6 8 2 12 6 16"/><line x1="2" x2="22" y1="12" y2="12"/></svg>', Oe = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="8 18 12 22 16 18"/><polyline points="8 6 12 2 16 6"/><line x1="12" x2="12" y1="2" y2="22"/></svg>';
|
|
272
|
+
function Q(o, e, t) {
|
|
273
|
+
const i = f("div", `ci-before-after-handle ci-before-after-handle--${o}`, {
|
|
274
|
+
role: "slider",
|
|
275
|
+
"aria-valuenow": String(Math.round(t)),
|
|
276
|
+
"aria-valuemin": "0",
|
|
277
|
+
"aria-valuemax": "100",
|
|
278
|
+
"aria-label": "Image comparison slider. Use arrow keys to adjust the before and after split position.",
|
|
279
|
+
"aria-orientation": e,
|
|
280
|
+
tabindex: "0"
|
|
281
|
+
});
|
|
282
|
+
switch (e === "horizontal" ? i.style.left = `${t}%` : i.style.top = `${t}%`, o) {
|
|
283
|
+
case "arrows":
|
|
284
|
+
De(i, e);
|
|
285
|
+
break;
|
|
286
|
+
case "circle":
|
|
287
|
+
Ze(i, e);
|
|
288
|
+
break;
|
|
289
|
+
case "line":
|
|
290
|
+
He(i);
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
return i;
|
|
294
|
+
}
|
|
295
|
+
function De(o, e) {
|
|
296
|
+
const t = f("div", "ci-before-after-handle-line"), i = f("div", "ci-before-after-handle-grip"), n = f("div", "ci-before-after-handle-line");
|
|
297
|
+
e === "horizontal" ? i.innerHTML = Ae + Ie : i.innerHTML = Me + Se, o.append(t, i, n);
|
|
298
|
+
}
|
|
299
|
+
function Ze(o, e) {
|
|
300
|
+
const t = f("div", "ci-before-after-handle-grip");
|
|
301
|
+
e === "horizontal" ? t.innerHTML = Te : t.innerHTML = Oe, o.append(t);
|
|
302
|
+
}
|
|
303
|
+
function He(o) {
|
|
304
|
+
const e = f("div", "ci-before-after-handle-line"), t = f("div", "ci-before-after-handle-grip ci-before-after-handle-grip--pill"), i = f("div", "ci-before-after-handle-line");
|
|
305
|
+
o.append(e, t, i);
|
|
306
|
+
}
|
|
307
|
+
class ee {
|
|
308
|
+
constructor(e, t, i, n, r) {
|
|
309
|
+
this.container = e, this.handle = t, this.mode = i, this.orientation = n, this.callbacks = r, this.events = new v(), this.containerRect = null, this.rafId = null, this.pendingPosition = null, this.abortController = null, this.bind();
|
|
310
|
+
}
|
|
311
|
+
bind() {
|
|
312
|
+
switch (this.mode) {
|
|
313
|
+
case "drag":
|
|
314
|
+
this.bindDrag();
|
|
315
|
+
break;
|
|
316
|
+
case "hover":
|
|
317
|
+
this.bindHover();
|
|
318
|
+
break;
|
|
319
|
+
case "click":
|
|
320
|
+
this.bindClick();
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
bindDrag() {
|
|
325
|
+
this.events.on(this.handle, "mousedown", (e) => {
|
|
326
|
+
e.preventDefault(), this.startDrag();
|
|
327
|
+
}), this.events.on(this.handle, "touchstart", (e) => {
|
|
328
|
+
e.preventDefault(), this.handle.focus(), this.startTouchDrag();
|
|
329
|
+
}, { passive: !1 });
|
|
330
|
+
}
|
|
331
|
+
startDrag() {
|
|
332
|
+
this.cleanupWindowListeners(), this.abortController = new AbortController();
|
|
333
|
+
const e = this.abortController.signal;
|
|
334
|
+
this.containerRect = this.container.getBoundingClientRect(), this.callbacks.onDragStart();
|
|
335
|
+
const t = (n) => {
|
|
336
|
+
if (!this.containerRect) return;
|
|
337
|
+
const r = E(n, this.containerRect, this.orientation);
|
|
338
|
+
this.schedulePositionUpdate(r);
|
|
339
|
+
}, i = () => {
|
|
340
|
+
this.flushPositionUpdate(), this.callbacks.onDragEnd(), this.containerRect = null, this.cleanupWindowListeners();
|
|
341
|
+
};
|
|
342
|
+
window.addEventListener("mousemove", t, { signal: e }), window.addEventListener("mouseup", i, { signal: e });
|
|
343
|
+
}
|
|
344
|
+
startTouchDrag() {
|
|
345
|
+
this.cleanupWindowListeners(), this.abortController = new AbortController();
|
|
346
|
+
const e = this.abortController.signal;
|
|
347
|
+
this.containerRect = this.container.getBoundingClientRect(), this.callbacks.onDragStart();
|
|
348
|
+
const t = (n) => {
|
|
349
|
+
if (!this.containerRect || n.touches.length !== 1) return;
|
|
350
|
+
n.preventDefault();
|
|
351
|
+
const r = E(n, this.containerRect, this.orientation);
|
|
352
|
+
this.schedulePositionUpdate(r);
|
|
353
|
+
}, i = () => {
|
|
354
|
+
this.flushPositionUpdate(), this.callbacks.onDragEnd(), this.containerRect = null, this.cleanupWindowListeners();
|
|
355
|
+
};
|
|
356
|
+
window.addEventListener("touchmove", t, { passive: !1, signal: e }), window.addEventListener("touchend", i, { signal: e }), window.addEventListener("touchcancel", i, { signal: e });
|
|
357
|
+
}
|
|
358
|
+
schedulePositionUpdate(e) {
|
|
359
|
+
this.pendingPosition = e, this.rafId === null && (this.rafId = requestAnimationFrame(() => {
|
|
360
|
+
this.rafId = null, this.pendingPosition !== null && (this.callbacks.onPositionChange(this.pendingPosition), this.pendingPosition = null);
|
|
361
|
+
}));
|
|
362
|
+
}
|
|
363
|
+
flushPositionUpdate() {
|
|
364
|
+
this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null), this.pendingPosition !== null && (this.callbacks.onPositionChange(this.pendingPosition), this.pendingPosition = null);
|
|
365
|
+
}
|
|
366
|
+
cleanupWindowListeners() {
|
|
367
|
+
this.abortController && (this.abortController.abort(), this.abortController = null);
|
|
368
|
+
}
|
|
369
|
+
bindHover() {
|
|
370
|
+
this.events.on(this.container, "mousemove", (e) => {
|
|
371
|
+
const t = this.container.getBoundingClientRect(), i = E(e, t, this.orientation);
|
|
372
|
+
this.schedulePositionUpdate(i);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
bindClick() {
|
|
376
|
+
this.events.on(this.container, "click", (e) => {
|
|
377
|
+
if (this.handle.contains(e.target)) return;
|
|
378
|
+
const t = this.container.getBoundingClientRect(), i = E(e, t, this.orientation);
|
|
379
|
+
this.callbacks.onPositionChange(i);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
updateMode(e) {
|
|
383
|
+
this.events.destroy(), this.cleanupWindowListeners(), this.flushPositionUpdate(), this.mode = e, this.bind();
|
|
384
|
+
}
|
|
385
|
+
updateOrientation(e) {
|
|
386
|
+
this.orientation = e;
|
|
387
|
+
}
|
|
388
|
+
destroy() {
|
|
389
|
+
this.cleanupWindowListeners(), this.rafId !== null && (cancelAnimationFrame(this.rafId), this.rafId = null), this.pendingPosition = null, this.events.destroy(), this.containerRect = null;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
class Be {
|
|
393
|
+
constructor(e, t, i, n, r) {
|
|
394
|
+
this.viewport = e, this.container = t, this.config = i, this.onZoomChange = n, this.zoomLevel = 1, this.panX = 0, this.panY = 0, this.containerWidth = 0, this.containerHeight = 0, this.transitioning = !1, this.transitionEndCleanup = null, this.resizeObserver = null, this.onTransformChange = r, this.updateContainerSize(), this.observeResize();
|
|
395
|
+
}
|
|
396
|
+
observeResize() {
|
|
397
|
+
typeof ResizeObserver > "u" || (this.resizeObserver = new ResizeObserver((e) => {
|
|
398
|
+
for (const t of e) {
|
|
399
|
+
const { width: i, height: n } = t.contentRect;
|
|
400
|
+
this.containerWidth = i, this.containerHeight = n;
|
|
401
|
+
}
|
|
402
|
+
}), this.resizeObserver.observe(this.container));
|
|
403
|
+
}
|
|
404
|
+
getZoom() {
|
|
405
|
+
return this.zoomLevel;
|
|
406
|
+
}
|
|
407
|
+
getContainerSize() {
|
|
408
|
+
return { width: this.containerWidth, height: this.containerHeight };
|
|
409
|
+
}
|
|
410
|
+
setZoom(e, t, i) {
|
|
411
|
+
var s;
|
|
412
|
+
const n = Math.max(this.config.zoomMin, Math.min(this.config.zoomMax, e));
|
|
413
|
+
if (n === this.zoomLevel) return;
|
|
414
|
+
const r = this.zoomLevel;
|
|
415
|
+
this.zoomLevel = n, t !== void 0 && i !== void 0 && (this.panX = t - (t - this.panX) * (n / r), this.panY = i - (i - this.panY) * (n / r)), this.clampPan(), this.applyTransform(!0), (s = this.onZoomChange) == null || s.call(this, this.zoomLevel);
|
|
416
|
+
}
|
|
417
|
+
zoomIn() {
|
|
418
|
+
this.setZoom(
|
|
419
|
+
this.zoomLevel * 1.5,
|
|
420
|
+
this.containerWidth / 2,
|
|
421
|
+
this.containerHeight / 2
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
zoomOut() {
|
|
425
|
+
this.setZoom(
|
|
426
|
+
this.zoomLevel / 1.5,
|
|
427
|
+
this.containerWidth / 2,
|
|
428
|
+
this.containerHeight / 2
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
resetZoom() {
|
|
432
|
+
var e;
|
|
433
|
+
this.zoomLevel = Math.max(1, this.config.zoomMin), this.panX = 0, this.panY = 0, this.applyTransform(!0), (e = this.onZoomChange) == null || e.call(this, this.zoomLevel);
|
|
434
|
+
}
|
|
435
|
+
getPan() {
|
|
436
|
+
return { x: this.panX, y: this.panY };
|
|
437
|
+
}
|
|
438
|
+
setPan(e, t) {
|
|
439
|
+
this.panX = e, this.panY = t, this.clampPan(), this.applyTransform(!1);
|
|
440
|
+
}
|
|
441
|
+
pan(e, t) {
|
|
442
|
+
this.zoomLevel <= 1 || (this.panX += e, this.panY += t, this.clampPan(), this.applyTransform(!1));
|
|
443
|
+
}
|
|
444
|
+
handleWheel(e) {
|
|
445
|
+
if (!e.ctrlKey && !e.metaKey) return;
|
|
446
|
+
e.preventDefault();
|
|
447
|
+
const t = this.container.getBoundingClientRect(), i = e.clientX - t.left, n = e.clientY - t.top, r = e.deltaY > 0 ? 0.9 : 1.1;
|
|
448
|
+
this.setZoom(this.zoomLevel * r, i, n);
|
|
449
|
+
}
|
|
450
|
+
toggleZoom(e, t) {
|
|
451
|
+
const i = Math.max(1, this.config.zoomMin);
|
|
452
|
+
this.zoomLevel > i ? this.resetZoom() : this.setZoom(Math.max(2, i * 1.5), e, t);
|
|
453
|
+
}
|
|
454
|
+
updateConfig(e) {
|
|
455
|
+
var i;
|
|
456
|
+
this.config = e;
|
|
457
|
+
const t = Math.max(e.zoomMin, Math.min(e.zoomMax, this.zoomLevel));
|
|
458
|
+
t !== this.zoomLevel && (this.zoomLevel = t, (i = this.onZoomChange) == null || i.call(this, this.zoomLevel)), this.clampPan(), this.applyTransform(!1);
|
|
459
|
+
}
|
|
460
|
+
updateContainerSize() {
|
|
461
|
+
const e = this.container.getBoundingClientRect();
|
|
462
|
+
this.containerWidth = e.width, this.containerHeight = e.height;
|
|
463
|
+
}
|
|
464
|
+
clampPan() {
|
|
465
|
+
if (this.zoomLevel <= 1) {
|
|
466
|
+
this.panX = 0, this.panY = 0;
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const e = this.containerWidth * (this.zoomLevel - 1), t = this.containerHeight * (this.zoomLevel - 1);
|
|
470
|
+
this.panX = Math.max(-e, Math.min(0, this.panX)), this.panY = Math.max(-t, Math.min(0, this.panY));
|
|
471
|
+
}
|
|
472
|
+
applyTransform(e) {
|
|
473
|
+
var t;
|
|
474
|
+
if (this.transitionEndCleanup && (this.transitionEndCleanup(), this.transitionEndCleanup = null), e) {
|
|
475
|
+
this.viewport.style.transition = "transform 300ms ease", this.transitioning = !0;
|
|
476
|
+
const i = (n) => {
|
|
477
|
+
n.target === this.viewport && (this.viewport.style.transition = "", this.transitioning = !1, this.transitionEndCleanup = null, this.viewport.removeEventListener("transitionend", i));
|
|
478
|
+
};
|
|
479
|
+
this.viewport.addEventListener("transitionend", i), this.transitionEndCleanup = () => {
|
|
480
|
+
this.viewport.removeEventListener("transitionend", i), this.viewport.style.transition = "", this.transitioning = !1;
|
|
481
|
+
};
|
|
482
|
+
} else this.transitioning || (this.viewport.style.transition = "");
|
|
483
|
+
this.viewport.style.transform = `scale(${this.zoomLevel}) translate(${this.panX / this.zoomLevel}px, ${this.panY / this.zoomLevel}px)`, (t = this.onTransformChange) == null || t.call(this);
|
|
484
|
+
}
|
|
485
|
+
destroy() {
|
|
486
|
+
var e;
|
|
487
|
+
this.transitionEndCleanup && (this.transitionEndCleanup(), this.transitionEndCleanup = null), this.viewport.style.transform = "", this.viewport.style.transition = "", (e = this.resizeObserver) == null || e.disconnect(), this.resizeObserver = null;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
const Re = 3;
|
|
491
|
+
class te {
|
|
492
|
+
constructor(e, t, i, n) {
|
|
493
|
+
this.container = e, this.handle = t, this.zoomPan = i, this.scrollHintCallback = n, this.events = new v(), this.isPanning = !1, this.lastPanX = 0, this.lastPanY = 0, this.initialPinchDistance = 0, this.initialPinchZoom = 1, this.abortController = null, this.bind();
|
|
494
|
+
}
|
|
495
|
+
bind() {
|
|
496
|
+
this.events.onNonPassive(this.container, "wheel", (e) => {
|
|
497
|
+
var t;
|
|
498
|
+
e.ctrlKey || e.metaKey ? this.zoomPan.handleWheel(e) : this.zoomPan.getZoom() > 1 || (t = this.scrollHintCallback) == null || t.call(this);
|
|
499
|
+
}), this.events.on(this.container, "dblclick", (e) => {
|
|
500
|
+
if (this.handle.contains(e.target)) return;
|
|
501
|
+
const t = this.container.getBoundingClientRect();
|
|
502
|
+
this.zoomPan.toggleZoom(e.clientX - t.left, e.clientY - t.top);
|
|
503
|
+
}), this.events.on(this.container, "mousedown", (e) => {
|
|
504
|
+
this.handle.contains(e.target) || this.zoomPan.getZoom() <= 1 || (e.preventDefault(), this.startPan(e.clientX, e.clientY));
|
|
505
|
+
}), this.events.on(this.container, "touchstart", (e) => {
|
|
506
|
+
this.handle.contains(e.target) || (e.touches.length === 2 ? (e.preventDefault(), this.startPinch(e)) : e.touches.length === 1 && this.zoomPan.getZoom() > 1 && (e.preventDefault(), this.startTouchPan(e)));
|
|
507
|
+
}, { passive: !1 }), typeof window < "u" && "GestureEvent" in window && (this.events.onNonPassive(this.container, "gesturestart", (e) => {
|
|
508
|
+
e.preventDefault(), this.initialPinchZoom = this.zoomPan.getZoom();
|
|
509
|
+
const t = e, i = this.container.getBoundingClientRect();
|
|
510
|
+
t.clientX - i.left, t.clientY - i.top;
|
|
511
|
+
}), this.events.onNonPassive(this.container, "gesturechange", (e) => {
|
|
512
|
+
e.preventDefault();
|
|
513
|
+
const t = e, i = this.container.getBoundingClientRect();
|
|
514
|
+
this.zoomPan.setZoom(
|
|
515
|
+
this.initialPinchZoom * t.scale,
|
|
516
|
+
t.clientX - i.left,
|
|
517
|
+
t.clientY - i.top
|
|
518
|
+
);
|
|
519
|
+
}));
|
|
520
|
+
}
|
|
521
|
+
startPan(e, t) {
|
|
522
|
+
this.cleanupWindowListeners(), this.abortController = new AbortController();
|
|
523
|
+
const i = this.abortController.signal;
|
|
524
|
+
this.isPanning = !1, this.lastPanX = e, this.lastPanY = t;
|
|
525
|
+
const n = e, r = t, s = (a) => {
|
|
526
|
+
const c = a.clientX - this.lastPanX, h = a.clientY - this.lastPanY;
|
|
527
|
+
if (!this.isPanning) {
|
|
528
|
+
const m = a.clientX - n, b = a.clientY - r;
|
|
529
|
+
if (Math.hypot(m, b) < Re) return;
|
|
530
|
+
this.isPanning = !0, this.container.style.cursor = "grabbing";
|
|
531
|
+
}
|
|
532
|
+
this.lastPanX = a.clientX, this.lastPanY = a.clientY, this.zoomPan.pan(c, h);
|
|
533
|
+
}, l = () => {
|
|
534
|
+
this.isPanning = !1, this.container.style.cursor = "", this.cleanupWindowListeners();
|
|
535
|
+
};
|
|
536
|
+
window.addEventListener("mousemove", s, { signal: i }), window.addEventListener("mouseup", l, { signal: i });
|
|
537
|
+
}
|
|
538
|
+
startTouchPan(e) {
|
|
539
|
+
this.cleanupWindowListeners(), this.abortController = new AbortController();
|
|
540
|
+
const t = this.abortController.signal, i = e.touches[0];
|
|
541
|
+
this.lastPanX = i.clientX, this.lastPanY = i.clientY;
|
|
542
|
+
const n = (s) => {
|
|
543
|
+
if (s.touches.length !== 1) return;
|
|
544
|
+
s.preventDefault();
|
|
545
|
+
const l = s.touches[0], a = l.clientX - this.lastPanX, c = l.clientY - this.lastPanY;
|
|
546
|
+
this.lastPanX = l.clientX, this.lastPanY = l.clientY, this.zoomPan.pan(a, c);
|
|
547
|
+
}, r = () => {
|
|
548
|
+
this.cleanupWindowListeners();
|
|
549
|
+
};
|
|
550
|
+
window.addEventListener("touchmove", n, { passive: !1, signal: t }), window.addEventListener("touchend", r, { signal: t }), window.addEventListener("touchcancel", r, { signal: t });
|
|
551
|
+
}
|
|
552
|
+
startPinch(e) {
|
|
553
|
+
if (e.touches.length < 2) return;
|
|
554
|
+
this.cleanupWindowListeners(), this.abortController = new AbortController();
|
|
555
|
+
const t = this.abortController.signal, [i, n] = [e.touches[0], e.touches[1]];
|
|
556
|
+
this.initialPinchDistance = Math.hypot(n.clientX - i.clientX, n.clientY - i.clientY), this.initialPinchDistance === 0 && (this.initialPinchDistance = 1), this.initialPinchZoom = this.zoomPan.getZoom();
|
|
557
|
+
const r = this.container.getBoundingClientRect(), s = (i.clientX + n.clientX) / 2 - r.left, l = (i.clientY + n.clientY) / 2 - r.top, a = (h) => {
|
|
558
|
+
if (h.touches.length !== 2) return;
|
|
559
|
+
h.preventDefault();
|
|
560
|
+
const [m, b] = [h.touches[0], h.touches[1]], g = Math.hypot(b.clientX - m.clientX, b.clientY - m.clientY) / this.initialPinchDistance;
|
|
561
|
+
this.zoomPan.setZoom(this.initialPinchZoom * g, s, l);
|
|
562
|
+
}, c = () => {
|
|
563
|
+
this.cleanupWindowListeners();
|
|
564
|
+
};
|
|
565
|
+
window.addEventListener("touchmove", a, { passive: !1, signal: t }), window.addEventListener("touchend", c, { signal: t }), window.addEventListener("touchcancel", c, { signal: t });
|
|
566
|
+
}
|
|
567
|
+
cleanupWindowListeners() {
|
|
568
|
+
this.abortController && (this.abortController.abort(), this.abortController = null);
|
|
569
|
+
}
|
|
570
|
+
destroy() {
|
|
571
|
+
this.cleanupWindowListeners(), this.events.destroy();
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
const $e = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/><path d="M12 5v14"/></svg>', Fe = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14"/></svg>', Ye = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>';
|
|
575
|
+
function ie(o, e) {
|
|
576
|
+
const t = new v(), i = f("div", `ci-before-after-zoom-controls ci-before-after-zoom-controls--${o}`), n = f("button", "ci-before-after-zoom-in", {
|
|
577
|
+
type: "button",
|
|
578
|
+
"aria-label": "Zoom in"
|
|
579
|
+
});
|
|
580
|
+
n.innerHTML = $e, t.on(n, "click", e.onZoomIn);
|
|
581
|
+
const r = f("button", "ci-before-after-zoom-out", {
|
|
582
|
+
type: "button",
|
|
583
|
+
"aria-label": "Zoom out"
|
|
584
|
+
});
|
|
585
|
+
r.innerHTML = Fe, t.on(r, "click", e.onZoomOut);
|
|
586
|
+
const s = f("button", "ci-before-after-zoom-reset", {
|
|
587
|
+
type: "button",
|
|
588
|
+
"aria-label": "Reset zoom"
|
|
589
|
+
});
|
|
590
|
+
return s.innerHTML = Ye, t.on(s, "click", e.onReset), i.append(n, r, s), { element: i, events: t };
|
|
591
|
+
}
|
|
592
|
+
class oe {
|
|
593
|
+
constructor(e) {
|
|
594
|
+
this.timeout = null, this.el = f("div", "ci-before-after-scroll-hint", {
|
|
595
|
+
"aria-hidden": "true"
|
|
596
|
+
});
|
|
597
|
+
const t = typeof navigator < "u" && /Mac|iPhone|iPad|iPod/.test(navigator.userAgent);
|
|
598
|
+
this.el.textContent = t ? "⌘ + scroll or pinch to zoom" : "Ctrl + scroll or pinch to zoom", e.appendChild(this.el);
|
|
599
|
+
}
|
|
600
|
+
show() {
|
|
601
|
+
this.timeout && clearTimeout(this.timeout), this.el.classList.add("ci-before-after-scroll-hint--visible"), this.timeout = setTimeout(() => {
|
|
602
|
+
this.el.classList.remove("ci-before-after-scroll-hint--visible"), this.timeout = null;
|
|
603
|
+
}, 1500);
|
|
604
|
+
}
|
|
605
|
+
destroy() {
|
|
606
|
+
this.timeout && clearTimeout(this.timeout), this.el.remove();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function ne(o, e, t, i) {
|
|
610
|
+
const n = `ci-before-after-label--${t}`, r = f(
|
|
611
|
+
"div",
|
|
612
|
+
`ci-before-after-label ci-before-after-label-before ${n}`,
|
|
613
|
+
{ "aria-hidden": "true" }
|
|
614
|
+
);
|
|
615
|
+
r.textContent = o;
|
|
616
|
+
const s = f(
|
|
617
|
+
"div",
|
|
618
|
+
`ci-before-after-label ci-before-after-label-after ${n}`,
|
|
619
|
+
{ "aria-hidden": "true" }
|
|
620
|
+
);
|
|
621
|
+
return s.textContent = e, { before: r, after: s };
|
|
622
|
+
}
|
|
623
|
+
function re(o, e, t, i) {
|
|
624
|
+
if (!o || !e) return;
|
|
625
|
+
const n = 15;
|
|
626
|
+
t < n ? o.classList.add("ci-before-after-label--hidden") : o.classList.remove("ci-before-after-label--hidden"), t > 100 - n ? e.classList.add("ci-before-after-label--hidden") : e.classList.remove("ci-before-after-label--hidden");
|
|
627
|
+
}
|
|
628
|
+
const se = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" x2="14" y1="3" y2="10"/><line x1="3" x2="10" y1="21" y2="14"/></svg>', Xe = '<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" x2="21" y1="10" y2="3"/><line x1="3" x2="10" y1="21" y2="14"/></svg>';
|
|
629
|
+
class ae {
|
|
630
|
+
constructor(e, t) {
|
|
631
|
+
this.container = e, this.onFullscreenChange = t, this.button = null, this.events = new v(), this.isActive = !1, I() && (this.createButton(), this.bindEvents());
|
|
632
|
+
}
|
|
633
|
+
createButton() {
|
|
634
|
+
this.button = f("button", "ci-before-after-fullscreen-btn", {
|
|
635
|
+
type: "button",
|
|
636
|
+
"aria-label": "Enter fullscreen",
|
|
637
|
+
"aria-pressed": "false"
|
|
638
|
+
}), this.button.innerHTML = se, this.events.on(this.button, "click", () => {
|
|
639
|
+
this.toggle().catch(() => {
|
|
640
|
+
});
|
|
641
|
+
}), this.container.appendChild(this.button);
|
|
642
|
+
}
|
|
643
|
+
bindEvents() {
|
|
644
|
+
this.events.on(document, "fullscreenchange", () => this.handleChange()), this.events.on(document, "webkitfullscreenchange", () => this.handleChange());
|
|
645
|
+
}
|
|
646
|
+
handleChange() {
|
|
647
|
+
var i;
|
|
648
|
+
const e = K(), t = this.isActive;
|
|
649
|
+
this.isActive = e === this.container, t !== this.isActive && (this.container.classList.toggle("ci-before-after-container--fullscreen", this.isActive), this.button && (this.button.innerHTML = this.isActive ? Xe : se, this.button.setAttribute("aria-label", this.isActive ? "Exit fullscreen" : "Enter fullscreen"), this.button.setAttribute("aria-pressed", String(this.isActive))), (i = this.onFullscreenChange) == null || i.call(this, this.isActive));
|
|
650
|
+
}
|
|
651
|
+
async enter() {
|
|
652
|
+
I() && await ze(this.container);
|
|
653
|
+
}
|
|
654
|
+
async exit() {
|
|
655
|
+
I() && K() === this.container && await q();
|
|
656
|
+
}
|
|
657
|
+
async toggle() {
|
|
658
|
+
this.isActive ? await this.exit() : await this.enter();
|
|
659
|
+
}
|
|
660
|
+
getIsFullscreen() {
|
|
661
|
+
return this.isActive;
|
|
662
|
+
}
|
|
663
|
+
destroy() {
|
|
664
|
+
var t, i;
|
|
665
|
+
const e = this.isActive;
|
|
666
|
+
this.events.destroy(), e && (this.isActive = !1, (t = this.onFullscreenChange) == null || t.call(this, !1), q().catch(() => {
|
|
667
|
+
})), this.container.classList.remove("ci-before-after-container--fullscreen"), (i = this.button) == null || i.remove();
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
class We {
|
|
671
|
+
constructor(e, t, i, n, r, s) {
|
|
672
|
+
this.container = e, this.duration = t, this.delay = i, this.easing = n, this.animateOnce = r, this.onAnimate = s, this.observer = null, this.hasPlayed = !1, this.isAnimating = !1, this.delayTimer = null, this.durationTimer = null, this.observe();
|
|
673
|
+
}
|
|
674
|
+
observe() {
|
|
675
|
+
typeof IntersectionObserver > "u" || (this.observer = new IntersectionObserver(
|
|
676
|
+
(e) => {
|
|
677
|
+
for (const t of e)
|
|
678
|
+
if (t.isIntersecting) {
|
|
679
|
+
if (this.animateOnce && this.hasPlayed || this.isAnimating) continue;
|
|
680
|
+
this.play();
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
{ threshold: 0.3 }
|
|
684
|
+
), this.observer.observe(this.container));
|
|
685
|
+
}
|
|
686
|
+
play() {
|
|
687
|
+
var e, t;
|
|
688
|
+
if (this.hasPlayed = !0, this.isAnimating = !0, typeof window < "u" && ((e = window.matchMedia) != null && e.call(window, "(prefers-reduced-motion: reduce)").matches)) {
|
|
689
|
+
this.onAnimate(!0), this.isAnimating = !1, this.animateOnce && ((t = this.observer) == null || t.disconnect());
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
this.container.classList.add("ci-before-after-animate-entrance"), this.container.style.setProperty("--ci-before-after-animate-duration", `${this.duration}ms`), this.container.style.setProperty("--ci-before-after-animate-easing", this.easing), this.delayTimer = setTimeout(() => {
|
|
693
|
+
this.delayTimer = null, this.onAnimate(!1), this.durationTimer = setTimeout(() => {
|
|
694
|
+
var i;
|
|
695
|
+
this.durationTimer = null, this.container.classList.remove("ci-before-after-animate-entrance"), this.isAnimating = !1, this.animateOnce && ((i = this.observer) == null || i.disconnect());
|
|
696
|
+
}, this.duration);
|
|
697
|
+
}, this.delay);
|
|
698
|
+
}
|
|
699
|
+
getHasPlayed() {
|
|
700
|
+
return this.hasPlayed;
|
|
701
|
+
}
|
|
702
|
+
destroy() {
|
|
703
|
+
var e;
|
|
704
|
+
this.delayTimer && clearTimeout(this.delayTimer), this.durationTimer && clearTimeout(this.durationTimer), this.delayTimer = null, this.durationTimer = null, this.isAnimating = !1, this.container.classList.remove("ci-before-after-animate-entrance"), this.container.style.removeProperty("--ci-before-after-animate-duration"), this.container.style.removeProperty("--ci-before-after-animate-easing"), (e = this.observer) == null || e.disconnect(), this.observer = null;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
class le {
|
|
708
|
+
constructor(e, t, i, n, r, s) {
|
|
709
|
+
this.handle = e, this.orientation = t, this.step = i, this.largeStep = n, this.zoomEnabled = r, this.callbacks = s, this.events = new v(), this.bind();
|
|
710
|
+
}
|
|
711
|
+
bind() {
|
|
712
|
+
this.events.on(this.handle, "keydown", (e) => {
|
|
713
|
+
this.handleKeyDown(e);
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
handleKeyDown(e) {
|
|
717
|
+
var r, s, l, a, c, h;
|
|
718
|
+
if (e.ctrlKey || e.altKey || e.metaKey) return;
|
|
719
|
+
const t = this.callbacks.getPosition(), i = e.shiftKey ? this.largeStep : this.step;
|
|
720
|
+
let n = null;
|
|
721
|
+
if (this.orientation === "horizontal")
|
|
722
|
+
switch (e.key) {
|
|
723
|
+
case "ArrowLeft":
|
|
724
|
+
n = t - i;
|
|
725
|
+
break;
|
|
726
|
+
case "ArrowRight":
|
|
727
|
+
n = t + i;
|
|
728
|
+
break;
|
|
729
|
+
}
|
|
730
|
+
else
|
|
731
|
+
switch (e.key) {
|
|
732
|
+
case "ArrowUp":
|
|
733
|
+
n = t - i;
|
|
734
|
+
break;
|
|
735
|
+
case "ArrowDown":
|
|
736
|
+
n = t + i;
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
switch (e.key) {
|
|
740
|
+
case "Home":
|
|
741
|
+
n = 0;
|
|
742
|
+
break;
|
|
743
|
+
case "End":
|
|
744
|
+
n = 100;
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
if (n !== null) {
|
|
748
|
+
e.preventDefault(), n = Math.max(0, Math.min(100, n)), this.callbacks.onPositionChange(n);
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (this.zoomEnabled)
|
|
752
|
+
switch (e.key) {
|
|
753
|
+
case "+":
|
|
754
|
+
case "=":
|
|
755
|
+
e.preventDefault(), (s = (r = this.callbacks).onZoomIn) == null || s.call(r);
|
|
756
|
+
break;
|
|
757
|
+
case "-":
|
|
758
|
+
e.preventDefault(), (a = (l = this.callbacks).onZoomOut) == null || a.call(l);
|
|
759
|
+
break;
|
|
760
|
+
case "0":
|
|
761
|
+
e.preventDefault(), (h = (c = this.callbacks).onZoomReset) == null || h.call(c);
|
|
762
|
+
break;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
updateConfig(e, t, i, n) {
|
|
766
|
+
this.orientation = e, this.step = t, this.largeStep = i, this.zoomEnabled = n;
|
|
767
|
+
}
|
|
768
|
+
destroy() {
|
|
769
|
+
this.events.destroy();
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
function Ne(o, e) {
|
|
773
|
+
o.setAttribute("aria-valuenow", String(Math.round(e)));
|
|
774
|
+
}
|
|
775
|
+
function je(o) {
|
|
776
|
+
o.setAttribute("role", "group"), o.setAttribute("aria-label", "Before and after image comparison");
|
|
777
|
+
}
|
|
778
|
+
class _e {
|
|
779
|
+
constructor(e, t) {
|
|
780
|
+
this.events = new v(), this.imageEvents = new v(), this.sliderGestures = null, this.zoomPan = null, this.zoomGestures = null, this.scrollHint = null, this.fullscreenManager = null, this.entranceAnimation = null, this.keyboardHandler = null, this.resizeObserver = null, this.zoomControlsEl = null, this.zoomControlsEvents = null, this.lazyLoadObserver = null, this.resizeDebounceTimer = null, this.animTransitionTimer = null, this.suppressCallbacks = !1;
|
|
781
|
+
const i = we(e);
|
|
782
|
+
this.userConfig = { ...t }, this.config = G(t), this.state = {
|
|
783
|
+
position: this.config.initialPosition,
|
|
784
|
+
isDragging: !1,
|
|
785
|
+
zoomLevel: 1,
|
|
786
|
+
panX: 0,
|
|
787
|
+
panY: 0,
|
|
788
|
+
isReady: !1,
|
|
789
|
+
isFullscreen: !1
|
|
790
|
+
}, this.buildDOM(i), this.initModules(), this.loadImages();
|
|
791
|
+
}
|
|
792
|
+
// --- Public API ---
|
|
793
|
+
getElements() {
|
|
794
|
+
return {
|
|
795
|
+
container: this.elements.container,
|
|
796
|
+
viewport: this.elements.viewport,
|
|
797
|
+
beforeImage: this.elements.beforeImage,
|
|
798
|
+
afterImage: this.elements.afterImage,
|
|
799
|
+
handle: this.elements.handle
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
setPosition(e) {
|
|
803
|
+
const t = J(e);
|
|
804
|
+
this.updatePosition(t);
|
|
805
|
+
}
|
|
806
|
+
getPosition() {
|
|
807
|
+
return this.state.position;
|
|
808
|
+
}
|
|
809
|
+
setZoom(e) {
|
|
810
|
+
var t;
|
|
811
|
+
(t = this.zoomPan) == null || t.setZoom(e);
|
|
812
|
+
}
|
|
813
|
+
getZoom() {
|
|
814
|
+
var e;
|
|
815
|
+
return ((e = this.zoomPan) == null ? void 0 : e.getZoom()) ?? 1;
|
|
816
|
+
}
|
|
817
|
+
resetZoom() {
|
|
818
|
+
var e;
|
|
819
|
+
(e = this.zoomPan) == null || e.resetZoom();
|
|
820
|
+
}
|
|
821
|
+
enterFullscreen() {
|
|
822
|
+
var e;
|
|
823
|
+
(e = this.fullscreenManager) == null || e.enter().catch(() => {
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
exitFullscreen() {
|
|
827
|
+
var e;
|
|
828
|
+
(e = this.fullscreenManager) == null || e.exit().catch(() => {
|
|
829
|
+
});
|
|
830
|
+
}
|
|
831
|
+
isFullscreen() {
|
|
832
|
+
var e;
|
|
833
|
+
return ((e = this.fullscreenManager) == null ? void 0 : e.getIsFullscreen()) ?? !1;
|
|
834
|
+
}
|
|
835
|
+
update(e) {
|
|
836
|
+
var s, l, a, c, h, m, b, p;
|
|
837
|
+
this.userConfig = { ...this.userConfig, ...e };
|
|
838
|
+
const t = this.config;
|
|
839
|
+
this.config = G(this.userConfig);
|
|
840
|
+
const i = this.config.beforeSrc !== t.beforeSrc, n = this.config.afterSrc !== t.afterSrc, r = !Ge(this.config.cloudimage, t.cloudimage);
|
|
841
|
+
if ((i || n || r) && (this.lazyLoadObserver && (this.lazyLoadObserver.disconnect(), this.lazyLoadObserver = null), this.state.isReady = !1, this.elements.container.classList.add("ci-before-after-loading"), (i || r) && (this.elements.beforeImage.src = this.resolveImageSrc(this.config.beforeSrc)), (n || r) && (this.elements.afterImage.src = this.resolveImageSrc(this.config.afterSrc)), this.registerImageLoadHandlers(i || r, n || r), this.config.cloudimage && !t.cloudimage ? this.initResizeObserver() : !this.config.cloudimage && t.cloudimage && ((s = this.resizeObserver) == null || s.disconnect(), this.resizeObserver = null)), this.config.beforeAlt !== t.beforeAlt && this.elements.beforeImage.setAttribute("alt", this.config.beforeAlt), this.config.afterAlt !== t.afterAlt && this.elements.afterImage.setAttribute("alt", this.config.afterAlt), this.elements.container.classList.toggle("ci-before-after-theme-dark", this.config.theme === "dark"), this.elements.container.classList.toggle("ci-before-after-container--horizontal", this.config.orientation === "horizontal"), this.elements.container.classList.toggle("ci-before-after-container--vertical", this.config.orientation === "vertical"), this.elements.container.classList.toggle("ci-before-after-container--hover-mode", this.config.mode === "hover"), this.elements.container.classList.toggle("ci-before-after-container--click-mode", this.config.mode === "click"), this.elements.viewport.classList.toggle("ci-before-after-viewport--zoomable", this.config.zoom), (this.config.handleStyle !== t.handleStyle || this.config.orientation !== t.orientation) && this.rebuildHandle(), this.config.mode !== t.mode && ((l = this.sliderGestures) == null || l.updateMode(this.config.mode)), this.config.orientation !== t.orientation && ((a = this.sliderGestures) == null || a.updateOrientation(this.config.orientation)), (this.config.labelsEnabled !== t.labelsEnabled || this.config.labelBefore !== t.labelBefore || this.config.labelAfter !== t.labelAfter || this.config.labelPosition !== t.labelPosition || this.config.orientation !== t.orientation) && this.rebuildLabels(), this.config.zoom !== t.zoom)
|
|
842
|
+
this.rebuildZoom();
|
|
843
|
+
else if (this.zoomPan && (this.zoomPan.updateConfig(this.config), this.config.scrollHint !== t.scrollHint && ((c = this.scrollHint) == null || c.destroy(), this.scrollHint = null, this.config.scrollHint && (this.scrollHint = new oe(this.elements.container))), (this.config.zoomControls !== t.zoomControls || this.config.zoomControlsPosition !== t.zoomControlsPosition) && ((h = this.zoomControlsEvents) == null || h.destroy(), this.zoomControlsEvents = null, (m = this.zoomControlsEl) == null || m.remove(), this.zoomControlsEl = null, this.elements.container.classList.remove("ci-before-after-container--zoom-top-right"), this.elements.container.classList.remove("ci-before-after-container--zoom-top"), this.elements.container.classList.remove("ci-before-after-container--zoom-left"), this.config.zoomControls))) {
|
|
844
|
+
const g = ie(
|
|
845
|
+
this.config.zoomControlsPosition,
|
|
846
|
+
{
|
|
847
|
+
onZoomIn: () => {
|
|
848
|
+
var u;
|
|
849
|
+
return (u = this.zoomPan) == null ? void 0 : u.zoomIn();
|
|
850
|
+
},
|
|
851
|
+
onZoomOut: () => {
|
|
852
|
+
var u;
|
|
853
|
+
return (u = this.zoomPan) == null ? void 0 : u.zoomOut();
|
|
854
|
+
},
|
|
855
|
+
onReset: () => {
|
|
856
|
+
var u;
|
|
857
|
+
return (u = this.zoomPan) == null ? void 0 : u.resetZoom();
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
);
|
|
861
|
+
this.zoomControlsEl = g.element, this.zoomControlsEvents = g.events, this.elements.container.appendChild(this.zoomControlsEl), this.applyZoomPositionClasses();
|
|
862
|
+
}
|
|
863
|
+
this.config.initialPosition !== t.initialPosition && this.updatePosition(this.config.initialPosition), this.config.fullscreenButton !== t.fullscreenButton && this.rebuildFullscreen(), this.config.animateEnabled !== t.animateEnabled && ((b = this.entranceAnimation) == null || b.destroy(), this.entranceAnimation = null, this.config.animateEnabled && this.initEntranceAnimation()), (p = this.keyboardHandler) == null || p.updateConfig(
|
|
864
|
+
this.config.orientation,
|
|
865
|
+
this.config.keyboardStep,
|
|
866
|
+
this.config.keyboardLargeStep,
|
|
867
|
+
this.config.zoom
|
|
868
|
+
), this.updatePosition(this.state.position);
|
|
869
|
+
}
|
|
870
|
+
destroy() {
|
|
871
|
+
var e, t, i, n, r, s, l, a, c, h, m;
|
|
872
|
+
(e = this.sliderGestures) == null || e.destroy(), (t = this.zoomGestures) == null || t.destroy(), (i = this.zoomPan) == null || i.destroy(), this.zoomPan = null, (n = this.scrollHint) == null || n.destroy(), (r = this.fullscreenManager) == null || r.destroy(), (s = this.entranceAnimation) == null || s.destroy(), (l = this.keyboardHandler) == null || l.destroy(), this.events.destroy(), this.imageEvents.destroy(), (a = this.resizeObserver) == null || a.disconnect(), (c = this.lazyLoadObserver) == null || c.disconnect(), this.lazyLoadObserver = null, (h = this.zoomControlsEvents) == null || h.destroy(), this.zoomControlsEvents = null, (m = this.zoomControlsEl) == null || m.remove(), this.resizeDebounceTimer && clearTimeout(this.resizeDebounceTimer), this.animTransitionTimer && clearTimeout(this.animTransitionTimer), this.elements.container.innerHTML = "", this.elements.container.removeAttribute("role"), this.elements.container.removeAttribute("aria-label"), this.elements.container.className = this.elements.container.className.split(" ").filter((b) => !b.startsWith("ci-before-after")).join(" ");
|
|
873
|
+
}
|
|
874
|
+
// --- Private Methods ---
|
|
875
|
+
buildDOM(e) {
|
|
876
|
+
e.innerHTML = "";
|
|
877
|
+
const t = `ci-before-after-container--${this.config.orientation}`;
|
|
878
|
+
e.classList.add("ci-before-after-container", t), this.config.mode === "hover" && e.classList.add("ci-before-after-container--hover-mode"), this.config.mode === "click" && e.classList.add("ci-before-after-container--click-mode"), this.config.theme === "dark" && e.classList.add("ci-before-after-theme-dark"), e.classList.add("ci-before-after-loading"), je(e);
|
|
879
|
+
const i = f("div", "ci-before-after-viewport");
|
|
880
|
+
this.config.zoom && i.classList.add("ci-before-after-viewport--zoomable");
|
|
881
|
+
const n = f("div", "ci-before-after-wrapper"), r = f("img", "ci-before-after-image ci-before-after-before", {
|
|
882
|
+
alt: this.config.beforeAlt,
|
|
883
|
+
draggable: "false",
|
|
884
|
+
role: "img"
|
|
885
|
+
}), s = f("div", "ci-before-after-clip");
|
|
886
|
+
M(s, this.state.position, this.config.orientation);
|
|
887
|
+
const l = f("img", "ci-before-after-image ci-before-after-after", {
|
|
888
|
+
alt: this.config.afterAlt,
|
|
889
|
+
draggable: "false",
|
|
890
|
+
role: "img"
|
|
891
|
+
});
|
|
892
|
+
s.appendChild(l), n.append(r, s), i.appendChild(n), e.appendChild(i);
|
|
893
|
+
const a = Q(this.config.handleStyle, this.config.orientation, this.state.position);
|
|
894
|
+
e.appendChild(a);
|
|
895
|
+
const c = a.querySelector(".ci-before-after-handle-grip");
|
|
896
|
+
let h = null, m = null;
|
|
897
|
+
if (this.config.labelsEnabled) {
|
|
898
|
+
const b = ne(
|
|
899
|
+
this.config.labelBefore,
|
|
900
|
+
this.config.labelAfter,
|
|
901
|
+
this.config.labelPosition,
|
|
902
|
+
this.config.orientation
|
|
903
|
+
);
|
|
904
|
+
h = b.before, m = b.after, e.append(h, m);
|
|
905
|
+
}
|
|
906
|
+
this.elements = {
|
|
907
|
+
container: e,
|
|
908
|
+
viewport: i,
|
|
909
|
+
wrapper: n,
|
|
910
|
+
beforeImage: r,
|
|
911
|
+
afterImage: l,
|
|
912
|
+
clip: s,
|
|
913
|
+
handle: a,
|
|
914
|
+
handleGrip: c,
|
|
915
|
+
labelBefore: h,
|
|
916
|
+
labelAfter: m
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
initModules() {
|
|
920
|
+
this.sliderGestures = new ee(
|
|
921
|
+
this.elements.container,
|
|
922
|
+
this.elements.handle,
|
|
923
|
+
this.config.mode,
|
|
924
|
+
this.config.orientation,
|
|
925
|
+
{
|
|
926
|
+
onPositionChange: (e) => this.updatePosition(e),
|
|
927
|
+
onDragStart: () => this.onDragStart(),
|
|
928
|
+
onDragEnd: () => this.onDragEnd()
|
|
929
|
+
}
|
|
930
|
+
), this.keyboardHandler = new le(
|
|
931
|
+
this.elements.handle,
|
|
932
|
+
this.config.orientation,
|
|
933
|
+
this.config.keyboardStep,
|
|
934
|
+
this.config.keyboardLargeStep,
|
|
935
|
+
this.config.zoom,
|
|
936
|
+
{
|
|
937
|
+
onPositionChange: (e) => this.updatePosition(e),
|
|
938
|
+
getPosition: () => this.state.position,
|
|
939
|
+
onZoomIn: () => {
|
|
940
|
+
var e;
|
|
941
|
+
return (e = this.zoomPan) == null ? void 0 : e.zoomIn();
|
|
942
|
+
},
|
|
943
|
+
onZoomOut: () => {
|
|
944
|
+
var e;
|
|
945
|
+
return (e = this.zoomPan) == null ? void 0 : e.zoomOut();
|
|
946
|
+
},
|
|
947
|
+
onZoomReset: () => {
|
|
948
|
+
var e;
|
|
949
|
+
return (e = this.zoomPan) == null ? void 0 : e.resetZoom();
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
), this.config.zoom && this.initZoom(), this.config.fullscreenButton && (this.elements.container.classList.add("ci-before-after-container--has-fullscreen"), this.fullscreenManager = new ae(
|
|
953
|
+
this.elements.container,
|
|
954
|
+
(e) => {
|
|
955
|
+
this.state.isFullscreen = e, L(this.config.onFullscreenChange, e);
|
|
956
|
+
}
|
|
957
|
+
)), this.config.animateEnabled && this.initEntranceAnimation(), this.config.cloudimage && this.initResizeObserver();
|
|
958
|
+
}
|
|
959
|
+
initZoom() {
|
|
960
|
+
if (this.zoomPan = new Be(
|
|
961
|
+
this.elements.viewport,
|
|
962
|
+
this.elements.container,
|
|
963
|
+
this.config,
|
|
964
|
+
(e) => {
|
|
965
|
+
this.state.zoomLevel = e, this.syncClip(), L(this.config.onZoom, e);
|
|
966
|
+
},
|
|
967
|
+
() => this.syncClip()
|
|
968
|
+
), this.config.scrollHint && (this.scrollHint = new oe(this.elements.container)), this.zoomGestures = new te(
|
|
969
|
+
this.elements.container,
|
|
970
|
+
this.elements.handle,
|
|
971
|
+
this.zoomPan,
|
|
972
|
+
() => {
|
|
973
|
+
var e;
|
|
974
|
+
return (e = this.scrollHint) == null ? void 0 : e.show();
|
|
975
|
+
}
|
|
976
|
+
), this.config.zoomControls) {
|
|
977
|
+
const e = ie(
|
|
978
|
+
this.config.zoomControlsPosition,
|
|
979
|
+
{
|
|
980
|
+
onZoomIn: () => {
|
|
981
|
+
var t;
|
|
982
|
+
return (t = this.zoomPan) == null ? void 0 : t.zoomIn();
|
|
983
|
+
},
|
|
984
|
+
onZoomOut: () => {
|
|
985
|
+
var t;
|
|
986
|
+
return (t = this.zoomPan) == null ? void 0 : t.zoomOut();
|
|
987
|
+
},
|
|
988
|
+
onReset: () => {
|
|
989
|
+
var t;
|
|
990
|
+
return (t = this.zoomPan) == null ? void 0 : t.resetZoom();
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
);
|
|
994
|
+
this.zoomControlsEl = e.element, this.zoomControlsEvents = e.events, this.elements.container.appendChild(this.zoomControlsEl), this.applyZoomPositionClasses();
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
applyZoomPositionClasses() {
|
|
998
|
+
const e = this.config.zoomControlsPosition;
|
|
999
|
+
this.elements.container.classList.toggle("ci-before-after-container--zoom-top-right", e === "top-right"), this.elements.container.classList.toggle("ci-before-after-container--zoom-top", e.startsWith("top-")), this.elements.container.classList.toggle("ci-before-after-container--zoom-left", e.endsWith("-left"));
|
|
1000
|
+
}
|
|
1001
|
+
initEntranceAnimation() {
|
|
1002
|
+
this.animTransitionTimer && (clearTimeout(this.animTransitionTimer), this.animTransitionTimer = null, this.elements.handle.style.transition = "", this.elements.clip.style.transition = "");
|
|
1003
|
+
const e = 0;
|
|
1004
|
+
this.suppressCallbacks = !0, this.updatePosition(e), this.suppressCallbacks = !1, this.entranceAnimation = new We(
|
|
1005
|
+
this.elements.container,
|
|
1006
|
+
this.config.animateDuration,
|
|
1007
|
+
this.config.animateDelay,
|
|
1008
|
+
this.config.animateEasing,
|
|
1009
|
+
this.config.animateOnce,
|
|
1010
|
+
(t) => {
|
|
1011
|
+
t || (this.elements.handle.style.transition = `left ${this.config.animateDuration}ms ${this.config.animateEasing}, top ${this.config.animateDuration}ms ${this.config.animateEasing}`, this.elements.clip.style.transition = `clip-path ${this.config.animateDuration}ms ${this.config.animateEasing}`), this.updatePosition(this.config.initialPosition), t || (this.animTransitionTimer = setTimeout(() => {
|
|
1012
|
+
this.animTransitionTimer = null, this.elements.handle.style.transition = "", this.elements.clip.style.transition = "";
|
|
1013
|
+
}, this.config.animateDuration));
|
|
1014
|
+
}
|
|
1015
|
+
);
|
|
1016
|
+
}
|
|
1017
|
+
loadImages() {
|
|
1018
|
+
const e = this.resolveImageSrc(this.config.beforeSrc), t = this.resolveImageSrc(this.config.afterSrc);
|
|
1019
|
+
this.config.lazyLoad && typeof IntersectionObserver < "u" ? (this.lazyLoadObserver = new IntersectionObserver(
|
|
1020
|
+
(i) => {
|
|
1021
|
+
var n;
|
|
1022
|
+
for (const r of i)
|
|
1023
|
+
r.isIntersecting && (this.elements.beforeImage.src = e, this.elements.afterImage.src = t, (n = this.lazyLoadObserver) == null || n.disconnect(), this.lazyLoadObserver = null);
|
|
1024
|
+
},
|
|
1025
|
+
{ threshold: 0 }
|
|
1026
|
+
), this.lazyLoadObserver.observe(this.elements.container)) : (this.elements.beforeImage.src = e, this.elements.afterImage.src = t), this.registerImageLoadHandlers(!0, !0);
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Register load/error handlers for images. Cleans up previous handlers first.
|
|
1030
|
+
* When only one image changed, the unchanged image is treated as already loaded.
|
|
1031
|
+
*/
|
|
1032
|
+
registerImageLoadHandlers(e, t) {
|
|
1033
|
+
this.imageEvents.destroy();
|
|
1034
|
+
let i = !e, n = !t;
|
|
1035
|
+
const r = () => {
|
|
1036
|
+
i && n && this.onImagesReady();
|
|
1037
|
+
}, s = () => {
|
|
1038
|
+
i || (i = !0, r());
|
|
1039
|
+
}, l = () => {
|
|
1040
|
+
n || (n = !0, r());
|
|
1041
|
+
}, a = () => {
|
|
1042
|
+
console.warn(`CIBeforeAfter: Failed to load image "${this.elements.beforeImage.src}"`), i || (i = !0, r());
|
|
1043
|
+
}, c = () => {
|
|
1044
|
+
console.warn(`CIBeforeAfter: Failed to load image "${this.elements.afterImage.src}"`), n || (n = !0, r());
|
|
1045
|
+
};
|
|
1046
|
+
this.imageEvents.on(this.elements.beforeImage, "load", s), this.imageEvents.on(this.elements.afterImage, "load", l), this.imageEvents.on(this.elements.beforeImage, "error", a), this.imageEvents.on(this.elements.afterImage, "error", c), this.elements.beforeImage.complete && this.elements.beforeImage.src && s(), this.elements.afterImage.complete && this.elements.afterImage.src && l();
|
|
1047
|
+
}
|
|
1048
|
+
onImagesReady() {
|
|
1049
|
+
if (this.state.isReady) return;
|
|
1050
|
+
this.state.isReady = !0;
|
|
1051
|
+
const { naturalWidth: e, naturalHeight: t } = this.elements.beforeImage;
|
|
1052
|
+
e && t && (this.elements.wrapper.style.aspectRatio = `${e} / ${t}`), this.elements.container.classList.remove("ci-before-after-loading"), L(this.config.onReady);
|
|
1053
|
+
}
|
|
1054
|
+
getClipZoomInfo() {
|
|
1055
|
+
if (!this.zoomPan || this.zoomPan.getZoom() <= 1) return;
|
|
1056
|
+
const e = this.zoomPan.getPan(), t = this.zoomPan.getContainerSize();
|
|
1057
|
+
return {
|
|
1058
|
+
level: this.zoomPan.getZoom(),
|
|
1059
|
+
panX: e.x,
|
|
1060
|
+
panY: e.y,
|
|
1061
|
+
containerWidth: t.width,
|
|
1062
|
+
containerHeight: t.height
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
syncClip() {
|
|
1066
|
+
M(this.elements.clip, this.state.position, this.config.orientation, this.getClipZoomInfo());
|
|
1067
|
+
}
|
|
1068
|
+
updatePosition(e) {
|
|
1069
|
+
this.state.position = J(e), M(this.elements.clip, this.state.position, this.config.orientation, this.getClipZoomInfo()), Ee(this.elements.handle, this.state.position, this.config.orientation), Ne(this.elements.handle, this.state.position), re(
|
|
1070
|
+
this.elements.labelBefore,
|
|
1071
|
+
this.elements.labelAfter,
|
|
1072
|
+
this.state.position,
|
|
1073
|
+
this.config.orientation
|
|
1074
|
+
), this.suppressCallbacks || L(this.config.onSlide, this.state.position);
|
|
1075
|
+
}
|
|
1076
|
+
onDragStart() {
|
|
1077
|
+
this.state.isDragging = !0, this.elements.container.classList.add("ci-before-after-container--dragging");
|
|
1078
|
+
}
|
|
1079
|
+
onDragEnd() {
|
|
1080
|
+
this.state.isDragging = !1, this.elements.container.classList.remove("ci-before-after-container--dragging");
|
|
1081
|
+
}
|
|
1082
|
+
resolveImageSrc(e) {
|
|
1083
|
+
if (this.config.cloudimage) {
|
|
1084
|
+
const t = this.elements.container.getBoundingClientRect().width || 800;
|
|
1085
|
+
return Le(e, t, this.config.cloudimage);
|
|
1086
|
+
}
|
|
1087
|
+
return e;
|
|
1088
|
+
}
|
|
1089
|
+
rebuildHandle() {
|
|
1090
|
+
var i, n;
|
|
1091
|
+
const e = document.activeElement === this.elements.handle;
|
|
1092
|
+
this.elements.handle.remove();
|
|
1093
|
+
const t = Q(this.config.handleStyle, this.config.orientation, this.state.position);
|
|
1094
|
+
this.elements.container.appendChild(t), this.elements.handle = t, this.elements.handleGrip = t.querySelector(".ci-before-after-handle-grip"), (i = this.sliderGestures) == null || i.destroy(), this.sliderGestures = new ee(
|
|
1095
|
+
this.elements.container,
|
|
1096
|
+
this.elements.handle,
|
|
1097
|
+
this.config.mode,
|
|
1098
|
+
this.config.orientation,
|
|
1099
|
+
{
|
|
1100
|
+
onPositionChange: (r) => this.updatePosition(r),
|
|
1101
|
+
onDragStart: () => this.onDragStart(),
|
|
1102
|
+
onDragEnd: () => this.onDragEnd()
|
|
1103
|
+
}
|
|
1104
|
+
), (n = this.keyboardHandler) == null || n.destroy(), this.keyboardHandler = new le(
|
|
1105
|
+
this.elements.handle,
|
|
1106
|
+
this.config.orientation,
|
|
1107
|
+
this.config.keyboardStep,
|
|
1108
|
+
this.config.keyboardLargeStep,
|
|
1109
|
+
this.config.zoom,
|
|
1110
|
+
{
|
|
1111
|
+
onPositionChange: (r) => this.updatePosition(r),
|
|
1112
|
+
getPosition: () => this.state.position,
|
|
1113
|
+
onZoomIn: () => {
|
|
1114
|
+
var r;
|
|
1115
|
+
return (r = this.zoomPan) == null ? void 0 : r.zoomIn();
|
|
1116
|
+
},
|
|
1117
|
+
onZoomOut: () => {
|
|
1118
|
+
var r;
|
|
1119
|
+
return (r = this.zoomPan) == null ? void 0 : r.zoomOut();
|
|
1120
|
+
},
|
|
1121
|
+
onZoomReset: () => {
|
|
1122
|
+
var r;
|
|
1123
|
+
return (r = this.zoomPan) == null ? void 0 : r.resetZoom();
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
), this.zoomGestures && this.zoomPan && (this.zoomGestures.destroy(), this.zoomGestures = new te(
|
|
1127
|
+
this.elements.container,
|
|
1128
|
+
this.elements.handle,
|
|
1129
|
+
this.zoomPan,
|
|
1130
|
+
() => {
|
|
1131
|
+
var r;
|
|
1132
|
+
return (r = this.scrollHint) == null ? void 0 : r.show();
|
|
1133
|
+
}
|
|
1134
|
+
)), e && this.elements.handle.focus();
|
|
1135
|
+
}
|
|
1136
|
+
rebuildLabels() {
|
|
1137
|
+
var e, t;
|
|
1138
|
+
if ((e = this.elements.labelBefore) == null || e.remove(), (t = this.elements.labelAfter) == null || t.remove(), this.elements.labelBefore = null, this.elements.labelAfter = null, this.config.labelsEnabled) {
|
|
1139
|
+
const i = ne(
|
|
1140
|
+
this.config.labelBefore,
|
|
1141
|
+
this.config.labelAfter,
|
|
1142
|
+
this.config.labelPosition,
|
|
1143
|
+
this.config.orientation
|
|
1144
|
+
);
|
|
1145
|
+
this.elements.labelBefore = i.before, this.elements.labelAfter = i.after, this.elements.container.append(i.before, i.after), re(i.before, i.after, this.state.position, this.config.orientation);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
rebuildZoom() {
|
|
1149
|
+
var e, t, i, n, r;
|
|
1150
|
+
(e = this.zoomGestures) == null || e.destroy(), this.zoomGestures = null, (t = this.scrollHint) == null || t.destroy(), this.scrollHint = null, (i = this.zoomControlsEvents) == null || i.destroy(), this.zoomControlsEvents = null, (n = this.zoomControlsEl) == null || n.remove(), this.zoomControlsEl = null, (r = this.zoomPan) == null || r.destroy(), this.zoomPan = null, this.elements.container.classList.remove("ci-before-after-container--zoom-top-right"), this.elements.container.classList.remove("ci-before-after-container--zoom-top"), this.elements.container.classList.remove("ci-before-after-container--zoom-left"), this.config.zoom && this.initZoom();
|
|
1151
|
+
}
|
|
1152
|
+
rebuildFullscreen() {
|
|
1153
|
+
var e;
|
|
1154
|
+
(e = this.fullscreenManager) == null || e.destroy(), this.fullscreenManager = null, this.elements.container.classList.remove("ci-before-after-container--has-fullscreen"), this.config.fullscreenButton && (this.elements.container.classList.add("ci-before-after-container--has-fullscreen"), this.fullscreenManager = new ae(
|
|
1155
|
+
this.elements.container,
|
|
1156
|
+
(t) => {
|
|
1157
|
+
this.state.isFullscreen = t, L(this.config.onFullscreenChange, t);
|
|
1158
|
+
}
|
|
1159
|
+
));
|
|
1160
|
+
}
|
|
1161
|
+
initResizeObserver() {
|
|
1162
|
+
typeof ResizeObserver > "u" || (this.resizeObserver = new ResizeObserver(() => {
|
|
1163
|
+
this.resizeDebounceTimer && clearTimeout(this.resizeDebounceTimer), this.resizeDebounceTimer = setTimeout(() => {
|
|
1164
|
+
if (this.config.cloudimage) {
|
|
1165
|
+
const e = this.resolveImageSrc(this.config.beforeSrc), t = this.resolveImageSrc(this.config.afterSrc);
|
|
1166
|
+
this.elements.beforeImage.src !== e && (this.elements.beforeImage.src = e), this.elements.afterImage.src !== t && (this.elements.afterImage.src = t);
|
|
1167
|
+
}
|
|
1168
|
+
this.resizeDebounceTimer = null;
|
|
1169
|
+
}, 200);
|
|
1170
|
+
}), this.resizeObserver.observe(this.elements.container));
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
function L(o, ...e) {
|
|
1174
|
+
if (o)
|
|
1175
|
+
try {
|
|
1176
|
+
o(...e);
|
|
1177
|
+
} catch (t) {
|
|
1178
|
+
console.error("CIBeforeAfter: callback error:", t);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
function Ge(o, e) {
|
|
1182
|
+
if (o === e) return !0;
|
|
1183
|
+
if (!o || !e) return !1;
|
|
1184
|
+
const t = Object.keys(o), i = Object.keys(e);
|
|
1185
|
+
if (t.length !== i.length) return !1;
|
|
1186
|
+
for (const n of t)
|
|
1187
|
+
if (o[n] !== e[n]) return !1;
|
|
1188
|
+
return !0;
|
|
1189
|
+
}
|
|
1190
|
+
const ce = ".ci-before-after-container{--ci-before-after-handle-width: 4px;--ci-before-after-handle-color: #ffffff;--ci-before-after-handle-shadow: 0 0 8px rgba(0, 0, 0, .3);--ci-before-after-grip-size: 44px;--ci-before-after-grip-bg: #ffffff;--ci-before-after-grip-border: 2px solid rgba(0, 0, 0, .1);--ci-before-after-grip-border-radius: 50%;--ci-before-after-grip-shadow: 0 2px 8px rgba(0, 0, 0, .2);--ci-before-after-grip-icon-color: #333333;--ci-before-after-grip-icon-size: 20px;--ci-before-after-grip-hover-bg: #f0f0f0;--ci-before-after-grip-hover-shadow: 0 4px 16px rgba(0, 0, 0, .25);--ci-before-after-grip-active-bg: #e0e0e0;--ci-before-after-grip-active-scale: .95;--ci-before-after-label-font-family: inherit;--ci-before-after-label-font-size: 14px;--ci-before-after-label-font-weight: 600;--ci-before-after-label-color: #ffffff;--ci-before-after-label-bg: rgba(0, 0, 0, .5);--ci-before-after-label-padding: 6px 14px;--ci-before-after-label-border-radius: 6px;--ci-before-after-label-offset-x: 12px;--ci-before-after-label-offset-y: 12px;--ci-before-after-label-backdrop-filter: blur(4px);--ci-before-after-handle-transition: .15s ease;--ci-before-after-slide-transition: 0ms;--ci-before-after-animate-duration: .8s;--ci-before-after-animate-easing: ease-out;--ci-before-after-zoom-controls-bg: rgba(255, 255, 255, .9);--ci-before-after-zoom-controls-color: #333333;--ci-before-after-zoom-controls-border-radius: 8px;--ci-before-after-zoom-controls-shadow: 0 2px 8px rgba(0, 0, 0, .15)}.ci-before-after-theme-dark{--ci-before-after-handle-color: #1a1a1a;--ci-before-after-handle-shadow: 0 0 8px rgba(255, 255, 255, .2);--ci-before-after-grip-bg: #1a1a1a;--ci-before-after-grip-border: 2px solid rgba(255, 255, 255, .2);--ci-before-after-grip-shadow: 0 2px 8px rgba(0, 0, 0, .5);--ci-before-after-grip-icon-color: #f0f0f0;--ci-before-after-grip-hover-bg: #2a2a2a;--ci-before-after-grip-active-bg: #333333;--ci-before-after-label-bg: rgba(0, 0, 0, .45);--ci-before-after-label-color: #f0f0f0;--ci-before-after-zoom-controls-bg: rgba(30, 30, 30, .9);--ci-before-after-zoom-controls-color: #f0f0f0}.ci-before-after-container{position:relative;overflow:hidden;width:100%;border-radius:var(--ci-before-after-border-radius, 0px);box-shadow:var(--ci-before-after-shadow, none);user-select:none;-webkit-user-select:none;touch-action:pan-y;line-height:0}.ci-before-after-container--vertical{touch-action:pan-x}.ci-before-after-container--fullscreen{background:#000;display:flex;align-items:center;justify-content:center;width:100vw;height:100vh}.ci-before-after-container--fullscreen .ci-before-after-wrapper{max-height:100vh}.ci-before-after-container--fullscreen .ci-before-after-image{object-fit:contain}.ci-before-after-container--dragging{cursor:ew-resize}.ci-before-after-container--vertical.ci-before-after-container--dragging{cursor:ns-resize}.ci-before-after-viewport{position:relative;width:100%;height:100%;transform-origin:0 0}.ci-before-after-viewport--zoomable{will-change:transform}.ci-before-after-wrapper{position:relative;width:100%;overflow:hidden}.ci-before-after-image{display:block;width:100%;height:100%;object-fit:cover}.ci-before-after-before{display:block;width:100%}.ci-before-after-after{position:absolute;top:0;left:0;width:100%;height:100%}.ci-before-after-clip{position:absolute;top:0;left:0;right:0;bottom:0}.ci-before-after-handle{position:absolute;top:0;bottom:0;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:10;transform:translate(-50%);cursor:ew-resize;outline:none}.ci-before-after-handle:focus-visible .ci-before-after-handle-grip{outline:3px solid #4d90fe;outline-offset:2px}.ci-before-after-container--vertical .ci-before-after-handle{top:auto;bottom:auto;left:0;right:0;flex-direction:row;transform:translateY(-50%);cursor:ns-resize}.ci-before-after-handle-line{flex:1;width:var(--ci-before-after-handle-width);background:var(--ci-before-after-handle-color);box-shadow:var(--ci-before-after-handle-shadow)}.ci-before-after-container--vertical .ci-before-after-handle-line{width:auto;height:var(--ci-before-after-handle-width);flex:1}.ci-before-after-handle-grip{display:flex;align-items:center;justify-content:center;width:var(--ci-before-after-grip-size);height:var(--ci-before-after-grip-size);background:var(--ci-before-after-grip-bg);border:var(--ci-before-after-grip-border);border-radius:var(--ci-before-after-grip-border-radius);box-shadow:var(--ci-before-after-grip-shadow);color:var(--ci-before-after-grip-icon-color);flex-shrink:0;transition:background .15s ease,box-shadow .15s ease,transform .15s ease}.ci-before-after-handle-grip svg{width:var(--ci-before-after-grip-icon-size);height:var(--ci-before-after-grip-icon-size)}.ci-before-after-handle-grip:hover,.ci-before-after-handle:hover .ci-before-after-handle-grip{background:var(--ci-before-after-grip-hover-bg);box-shadow:var(--ci-before-after-grip-hover-shadow);transform:scale(1.1)}.ci-before-after-container--dragging .ci-before-after-handle-grip{background:var(--ci-before-after-grip-active-bg);transform:scale(var(--ci-before-after-grip-active-scale))}.ci-before-after-handle--line .ci-before-after-handle-grip,.ci-before-after-handle--line .ci-before-after-handle-grip--pill{width:8px;height:32px;border-radius:4px}.ci-before-after-container--vertical .ci-before-after-handle--line .ci-before-after-handle-grip{width:32px;height:8px}.ci-before-after-handle--circle .ci-before-after-handle-line{display:none}.ci-before-after-label{position:absolute;z-index:5;font-family:var(--ci-before-after-label-font-family);font-size:var(--ci-before-after-label-font-size);font-weight:var(--ci-before-after-label-font-weight);color:var(--ci-before-after-label-color);background:var(--ci-before-after-label-bg);padding:var(--ci-before-after-label-padding);border-radius:var(--ci-before-after-label-border-radius);backdrop-filter:var(--ci-before-after-label-backdrop-filter);-webkit-backdrop-filter:var(--ci-before-after-label-backdrop-filter);pointer-events:none;line-height:1.2;transition:opacity .2s ease;opacity:1}.ci-before-after-label--hidden{opacity:0}.ci-before-after-container--horizontal .ci-before-after-label--top.ci-before-after-label-before{top:var(--ci-before-after-label-offset-y);left:25%;transform:translate(-50%)}.ci-before-after-container--horizontal .ci-before-after-label--top.ci-before-after-label-after{top:var(--ci-before-after-label-offset-y);left:75%;transform:translate(-50%)}.ci-before-after-container--horizontal .ci-before-after-label--bottom.ci-before-after-label-before{bottom:var(--ci-before-after-label-offset-y);left:25%;transform:translate(-50%)}.ci-before-after-container--horizontal .ci-before-after-label--bottom.ci-before-after-label-after{bottom:var(--ci-before-after-label-offset-y);left:75%;transform:translate(-50%)}.ci-before-after-container--vertical .ci-before-after-label--top.ci-before-after-label-before{top:var(--ci-before-after-label-offset-y);left:var(--ci-before-after-label-offset-x)}.ci-before-after-container--vertical .ci-before-after-label--top.ci-before-after-label-after{bottom:var(--ci-before-after-label-offset-y);left:var(--ci-before-after-label-offset-x)}.ci-before-after-container--vertical .ci-before-after-label--bottom.ci-before-after-label-before{top:var(--ci-before-after-label-offset-y);right:var(--ci-before-after-label-offset-x)}.ci-before-after-container--vertical .ci-before-after-label--bottom.ci-before-after-label-after{bottom:var(--ci-before-after-label-offset-y);right:var(--ci-before-after-label-offset-x)}.ci-before-after-container--vertical.ci-before-after-container--zoom-left .ci-before-after-label--top.ci-before-after-label-before,.ci-before-after-container--vertical.ci-before-after-container--zoom-left .ci-before-after-label--top.ci-before-after-label-after{left:calc(var(--ci-before-after-label-offset-x) + 44px)}.ci-before-after-zoom-controls{position:absolute;z-index:20;display:flex;gap:2px;background:var(--ci-before-after-zoom-controls-bg);border-radius:var(--ci-before-after-zoom-controls-border-radius);box-shadow:var(--ci-before-after-zoom-controls-shadow);padding:0;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}.ci-before-after-zoom-controls button{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:transparent;color:var(--ci-before-after-zoom-controls-color);cursor:pointer;border-radius:6px;padding:0;transition:background .15s ease}.ci-before-after-zoom-controls button:hover{background:#00000014}.ci-before-after-theme-dark .ci-before-after-zoom-controls button:hover{background:#ffffff1f}.ci-before-after-zoom-controls button:focus-visible{outline:2px solid #4d90fe;outline-offset:-2px}.ci-before-after-zoom-controls--top-left{top:12px;left:12px}.ci-before-after-zoom-controls--top-center{top:12px;left:50%;transform:translate(-50%)}.ci-before-after-zoom-controls--top-right{top:12px;right:12px}.ci-before-after-zoom-controls--bottom-left{bottom:12px;left:12px}.ci-before-after-zoom-controls--bottom-center{bottom:12px;left:50%;transform:translate(-50%)}.ci-before-after-zoom-controls--bottom-right{bottom:12px;right:12px}.ci-before-after-fullscreen-btn{position:absolute;top:12px;right:12px;z-index:20;display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;background:var(--ci-before-after-zoom-controls-bg);color:var(--ci-before-after-zoom-controls-color);border-radius:8px;cursor:pointer;box-shadow:var(--ci-before-after-zoom-controls-shadow);padding:0;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:background .15s ease}.ci-before-after-fullscreen-btn:hover{background:#e6e6e6f2}.ci-before-after-theme-dark .ci-before-after-fullscreen-btn:hover{background:#323232f2}.ci-before-after-fullscreen-btn:focus-visible{outline:2px solid #4d90fe;outline-offset:2px}.ci-before-after-container--zoom-top-right .ci-before-after-fullscreen-btn{right:132px}.ci-before-after-container--zoom-top.ci-before-after-container--horizontal .ci-before-after-label--top{top:auto;bottom:var(--ci-before-after-label-offset-y)}.ci-before-after-scroll-hint{position:absolute;bottom:50%;left:50%;transform:translate(-50%,50%);z-index:30;background:#000000bf;color:#fff;padding:8px 16px;border-radius:8px;font-size:13px;font-weight:500;white-space:nowrap;pointer-events:none;opacity:0;transition:opacity .2s ease;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);line-height:1.4}.ci-before-after-scroll-hint--visible{opacity:1}.ci-before-after-loading .ci-before-after-wrapper{min-height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0,#f0f0f0 75%);background-size:200% 100%;animation:ci-before-after-shimmer 1.5s infinite}.ci-before-after-theme-dark.ci-before-after-loading .ci-before-after-wrapper{background:linear-gradient(90deg,#2a2a2a 25%,#333,#2a2a2a 75%);background-size:200% 100%}@keyframes ci-before-after-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.ci-before-after-container--hover-mode{cursor:ew-resize}.ci-before-after-container--vertical.ci-before-after-container--hover-mode{cursor:ns-resize}.ci-before-after-container--click-mode{cursor:pointer}@media(prefers-reduced-motion:reduce){.ci-before-after-container,.ci-before-after-container *{animation:none!important;transition-duration:.01ms!important}}";
|
|
1191
|
+
class ge extends _e {
|
|
1192
|
+
static autoInit(e) {
|
|
1193
|
+
if (!S()) return [];
|
|
1194
|
+
U(ce);
|
|
1195
|
+
const i = (e || document).querySelectorAll("[data-ci-before-after-before-src]"), n = [];
|
|
1196
|
+
return i.forEach((r) => {
|
|
1197
|
+
const s = pe(r);
|
|
1198
|
+
n.push(new ge(r, s));
|
|
1199
|
+
}), n;
|
|
1200
|
+
}
|
|
1201
|
+
constructor(e, t) {
|
|
1202
|
+
U(ce), super(e, t);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
export {
|
|
1206
|
+
ge as CIBeforeAfter,
|
|
1207
|
+
_e as CIBeforeAfterCore,
|
|
1208
|
+
ge as default
|
|
1209
|
+
};
|
|
1210
|
+
//# sourceMappingURL=js-cloudimage-before-after.esm.js.map
|