File size: 2,061 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
const RECENTER_DELAY = 1;
const RECENTER_ANIMATION_DURATION = 0.25;

window.addEventListener("DOMContentLoaded", initializeImageComparison);

function initializeImageComparison() {
	Array.from(document.querySelectorAll("[data-image-comparison]")).forEach((element) => {
		const moveHandler = (event) => {
			const factor = (event.clientX - element.getBoundingClientRect().left) / element.getBoundingClientRect().width;
			const capped = Math.max(0, Math.min(1, factor));

			if (!(element instanceof HTMLElement)) return;
			element.style.setProperty("--comparison-percent", `${capped * 100}%`);
			element.dataset.lastInteraction = "";
		};

		const leaveHandler = (event) => {
			moveHandler(event);

			const randomCode = Math.random().toString().substring(2);
			element.dataset.lastInteraction = randomCode;

			setTimeout(() => {
				if (element.dataset.lastInteraction === randomCode) {
					element.dataset.recenterStartTime = Date.now();
					element.dataset.recenterStartValue = parseFloat(element.style.getPropertyValue("--comparison-percent"));

					recenterAnimationStep();
				}
			}, RECENTER_DELAY * 1000);
		};

		const recenterAnimationStep = () => {
			if (element.dataset.lastInteraction === "") return;

			const completionFactor = (Date.now() - element.dataset.recenterStartTime) / (RECENTER_ANIMATION_DURATION * 1000);
			if (completionFactor > 1) {
				element.dataset.lastInteraction = "";
				return;
			}

			const factor = smootherstep(completionFactor);
			const newLocation = lerp(element.dataset.recenterStartValue, 50, factor);
			element.style.setProperty("--comparison-percent", `${newLocation}%`);

			requestAnimationFrame(recenterAnimationStep);
		};

		const lerp = (a, b, t) => (1 - t) * a + t * b;
		const smootherstep = (x) => x * x * x * (x * (x * 6 - 15) + 10);

		element.addEventListener("pointermove", moveHandler);
		element.addEventListener("pointerenter", moveHandler);
		element.addEventListener("pointerleave", leaveHandler);
		element.addEventListener("dragstart", (event) => event.preventDefault());
	});
}