PageSourceSearch

https://onthisspot.ca/js/before-after.js?v=22.2

js onthisspot.ca collected 2026-09-24 09:42:31 UTC 9,714 bytes, 312 lines download raw bytes

1function genBeforeAfters(target) {
2    let beforeAfters = target.getElementsByClassName("before-after");
3    let thumbButtonSize = 20;
4
5	//console.log("beforeAfters: ", beforeAfters)
6	Array.from(beforeAfters).forEach(elem => {
7		let imgs = elem.getElementsByTagName("img");
8		if (imgs.length == 2 && imgs[0].getAttribute('src') != "" && imgs[1].getAttribute('src') != "") {
9			//console.log("Generating before afters")
10			let [after, before] = imgs
11
12
13			Array.from(imgs).forEach((img)=>{
14				img.onload = function() {
15					const {
16						naturalWidth, naturalHeight, height, width
17					} = this;
18					if (naturalHeight > naturalWidth) {
19						if (height == 700) {
20							const ratio = naturalHeight / naturalWidth;
21							const newWidth = 700 / ratio;
22							// console.log('HERE', this);
23							// console.log('ratio', ratio);
24							// console.log('NEW WIDTH', newWidth)
25							// this.style.width = `${newWidth}px`;
26							const parent = $(this).parent();
27							const parents_parent = $(parent).parent();
28							// console.log('parent', parent);
29							$(parents_parent).width(newWidth);
30							$(parents_parent).css('margin-left', ($($(parents_parent).parent()).width() - newWidth) /2);
31						}	
32					}
33				}
34			});
35
36			// Get the loading placeholder to remove after the initial crop of the images
37			placeHolder = elem.children[0].children[2];
38
39			// Define variables used to create the slider
40			let slider, toggleBtn, imgSlider, sliderOverlayPressable, imgSliderBtn;
41			let containsSlider = elem.classList.contains("slider");
42			let containsToggle = elem.classList.contains("toggle");
43			let isHoriz = elem.classList.contains("slider-overlay-h");
44			let isVert = elem.classList.contains("slider-overlay-v");
45
46			if (containsSlider) {
47				// Generate the slider
48				slider = document.createElement("input");
49				slider.className = "fade-slider";
50				slider.setAttribute("type", "range");
51				slider.setAttribute("min", "0");
52				slider.setAttribute("max", "1");
53				slider.setAttribute("step", ".001");
54				slider.setAttribute("value", "1");
55				slider.setAttribute("style", "touch-action: none;");
56				slider.setAttribute("margin-bottom", "10px");
57				elem.appendChild(slider);
58
59				// Setup the slider for halfway
60				if (isHoriz) {
61					// Set then/now to half way
62					slider.value = 0.5;
63					// Set the slider so when it's moved it crops
64					slider.oninput = e => {moveSlideOverlay(slider.value, imgSlider, sliderOverlayPressable, imgSliderBtn, before, slider.value, isHoriz)};
65
66					// When the slider is used, fade the fade button
67					slider.onmousedown = function () {
68						// Fade the fade button
69						toggleBtn.classList.add('fade');
70					}
71					slider.ontouchstart = function () {
72						// Fade the fade button
73						toggleBtn.classList.add('fade');
74					}
75
76					// When the slidder stops being used, unfade the fade button
77					slider.onmouseup = function () {
78						// Fade the fade button
79						toggleBtn.classList.remove('fade');
80					}
81					slider.ontouchend = function () {
82						// Fade the fade button
83						toggleBtn.classList.remove('fade');
84					}
85				}
86			}
87
88			// Create the overlay slider and top button
89			if (isHoriz || isVert) {
90				let images_container = elem.children[0];
91				imgSlider = document.createElement("div");
92				imgSlider.className = "fade-slider-overlay";
93				imgSliderBtn = document.createElement("div");
94				imgSliderBtn.className = "slider-btn";
95				sliderOverlayPressable = document.createElement("div");
96				sliderOverlayPressable.className = 'slider-overlay-pressable'
97
98				imgSlider.style.opacity = 0.5;
99				imgSliderBtn.style.opacity = 0.75;
100
101				// Create an interactive overlay
102
103				images_container.appendChild(sliderOverlayPressable)
104
105				if (isHoriz) {
106					imgSlider.style.width = "4px";
107					imgSliderBtn.style.width = "20px";
108					imgSliderBtn.style.height = "15px";
109					imgSliderBtn.style.top = "-15px";
110
111					imgSliderBtn.style.borderTopLeftRadius = '5px';
112					imgSliderBtn.style.borderTopRightRadius = '5px';
113				} else {
114					imgSlider.style.height = "4px";
115					imgSliderBtn.style.width = "15px";
116					imgSliderBtn.style.height = "25px";
117					imgSliderBtn.style.left = "-15px";
118				}
119
120				// Add the elements to the dom
121				images_container.appendChild(imgSlider);
122				images_container.appendChild(imgSliderBtn);
123				images_container.appendChild(sliderOverlayPressable); // sliderOverlayPressable is styled in css
124			}
125
126			// If the slider exists, crop the starting posiiton
127			if (slider) {
128				moveSlideOverlay(slider.value, imgSlider, sliderOverlayPressable, imgSliderBtn, before, slider.value, isHoriz);
129			}
130			// Remove the loading image, if it exists
131			if (placeHolder) {
132				placeHolder.remove();
133			}
134
135
136			let images_container = elem.children[0];
137			// Make the fade button
138			if (containsToggle) {
139                toggleBtn = document.createElement("button");
140                toggleBtn.className = "fade-btn";
141                toggleBtn.innerText = "Fade";
142
143				// When the button is pressed
144				toggleBtn.onclick = function() {
145
146					// If the overlayed image has no fade
147					if (! before.classList.contains("fade")) {
148						// Add a fade to the overlayed image
149						before.classList.add("fade");
150
151						// Fade the slider if it exists
152						if (imgSlider) {imgSlider.style.opacity = "0"}
153					}
154
155					// Remove the fade effects
156					else {
157						// Crop the overlayed image to full size
158						clipImg(before, 1, isHoriz)
159
160						// Remove the fade om the overlayed image
161						before.classList.remove("fade");
162
163					}
164				}
165
166				images_container.appendChild(toggleBtn)
167			}
168
169			// Make the slider overlay draggable
170			if (imgSlider) {
171				makeDraggable(images_container, slider, imgSlider, sliderOverlayPressable, imgSliderBtn,
172					toggleBtn, before, after, isHoriz);
173			}
174		}
175
176		// If only one image, load it
177		else if (imgs.length == 2) {
178			//console.log("Generate solo image")
179
180			// Assign an image to display
181			var image
182			if (imgs[0].getAttribute('src') != "") {
183				image = imgs[0]
184			}
185			else {
186				image = imgs[1]
187			}
188			// Get the placeholder to remove one the image has loaded
189			placeHolder = elem.children[0].children[2];
190
191			image.style.position = "relative"
192
193			// Remove the loading image, if it exists
194			if (placeHolder) {
195				placeHolder.remove();
196			}
197
198		}
199
200	});
201
202	function makeDraggable(imgCont, slider, imgSlider, sliderOverlayPressable, imgSliderBtn, toggleBtn,
203		before, after, isHoriz) {
204		let upperLimit;
205
206		if (isHoriz) {
207			upperLimit = before.clientWidth - imgSlider.clientWidth;
208		} else {
209			upperLimit = before.clientHeight - imgSlider.clientHeight;
210		}
211
212		// Move the slideoverlay to the center
213		moveSlideOverlay(slider.value, imgSlider, sliderOverlayPressable, imgSliderBtn, before, 0.5, isHoriz);
214
215		let mouseOffset = 0;
216		sliderOverlayPressable.onmousedown = startDrag;
217		imgSliderBtn.onmousedown = startDrag;
218		sliderOverlayPressable.ontouchstart = startDrag;
219		imgSliderBtn.ontouchstart = startDrag;
220
221		function startDrag(e) {
222			if (toggleBtn) toggleBtn.classList.add("fade");
223
224			if (e.type == "touchstart") {
225				mouseOffset = isHoriz ? e.touches[0].clientX - imgSlider.offsetLeft :
226					e.touches[0].clientY - imgSlider.offsetTop;
227			}
228			else {
229				// Disable drag box
230				e.preventDefault();
231				mouseOffset = isHoriz ? e.clientX - imgSlider.offsetLeft :
232					e.clientY - imgSlider.offsetTop;
233			}
234
235			document.onmousemove = elemDrag;
236			document.onmouseup = stopDrag;
237			document.ontouchmove = elemDrag;
238			document.ontouchend = stopDrag;
239		}
240
241		function elemDrag(e) {
242
243			var moveTo
244			if (e.type == "touchmove") {
245				moveTo = (isHoriz ? e.touches[0].clientX : e.touches[0].clientY) - mouseOffset;
246			}
247			else {
248				// disable drag box
249				e.preventDefault();
250				moveTo = (isHoriz ? e.clientX : e.clientY) - mouseOffset;
251			}
252
253			moveTo = Math.max(0, Math.min(moveTo, upperLimit));
254			if (slider) {
255				slider.value = moveTo / upperLimit;
256			}
257			moveSlideOverlay(slider.value, imgSlider, sliderOverlayPressable, imgSliderBtn, before, moveTo, isHoriz);
258
259			//if (otherSlider) otherSlider.value = moveTo / upperLimit;
260		}
261
262		function stopDrag(e) {
263			if (toggleBtn) toggleBtn.classList.remove("fade");
264
265			document.onmouseup = null;
266			document.onmousemove = null;
267			document.ontouchmove = null;
268			document.ontouchup = null;
269		}
270	}
271
272	function moveSlideOverlay(sliderValue, sliderOverlay, sliderOverlayPressable, sliderBtn, img, moveTo, isHoriz) {
273
274		// If the image is faded, remove the fade
275		if (img.classList.contains("fade")) { img.classList.remove("fade")}
276
277		// If the slider is faded, remove the fade
278		if (sliderOverlay.style.opacity != "0.5") { sliderOverlay.style.opacity = "0.5"}
279
280        if (isHoriz) {
281			// Clip the image to match the slider
282			clipImg(img, sliderValue, isHoriz)
283
284			// Move the slider overlay
285			sliderOverlay.style.left = sliderValue*100 + "%";
286			// Move the slider overlays pressable section (- half of width)
287			sliderOverlayPressable.style.left = sliderValue*100 - 5 + "%";
288			// Move the slider overlay button
289			sliderBtn.style.left = sliderValue*100 + "%";
290
291        } else {
292            slider.style.top = moveTo + "px";
293            sliderBtn.style.top = slider.style.top;
294            // clipImg(img, slider.offsetTop, false);
295            clipImg(img, slider.offsetTop + slider.clientHeight / 2, false);
296        }
297    }
298
299	function clipImg(img, clipAt, isHoriz) {
300        if (isHoriz) {
301			img.style.clipPath = `polygon(0 0, ${clipAt * 100}% 0%, ${clipAt * 100}% 100%, 0% 100%)`
302        } else {
303            img.style.clip = `rect(${clipAt}px
304                ${img.width}px
305                ${img.height}px
306                0px)`;
307        }
308    }
309
310};
311
312document.addEventListener("DOMContentLoaded", e => genBeforeAfters(document));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.