PageSourceSearch

https://adaptationataltitude.org/wp-content/themes/weadapt/parts/g…/acf-hero-slideshow/index.js?ver=1784076863

js adaptationataltitude.org collected 2026-10-02 05:13:01 UTC 5,268 bytes, 218 lines download raw bytes

1(function($) {
2	'use strict';
3
4	$(document).ready(function() {
5		$('.hero-slideshow__slideshow').each(function() {
6			const $slideshow = $(this);
7			const $slides = $slideshow.find('.hero-slideshow__slide');
8			const $dots = $slideshow.find('.hero-slideshow__dot');
9			const $prevBtn = $slideshow.find('.hero-slideshow__control--prev');
10			const $nextBtn = $slideshow.find('.hero-slideshow__control--next');
11			const autoRotate = $slideshow.data('auto-rotate') === true;
12			const rotationSpeed = parseInt($slideshow.data('rotation-speed')) || 5000;
13			let currentSlide = 0;
14			let autoRotateInterval = null;
15			let isAnimating = false;
16
17			function hydrateSlide($slide) {
18				const bg = $slide.attr('data-bg');
19				if (bg) {
20					$slide.css('background-image', 'url("' + bg + '")').removeAttr('data-bg');
21				}
22			}
23
24			$(window).on('load', function() {
25				$slides.each(function() {
26					hydrateSlide($(this));
27				});
28			});
29
30			if ($slides.length <= 1) {
31				return;
32			}
33
34			function goToSlide(index, direction = 'next') {
35				if (isAnimating) return;
36
37				isAnimating = true;
38				const $currentSlide = $slides.eq(currentSlide);
39				const $targetSlide = $slides.eq(index);
40
41				hydrateSlide($targetSlide);
42
43				$currentSlide.removeClass('active');
44				$targetSlide.addClass('active');
45
46				$dots.eq(currentSlide).removeClass('active');
47				$dots.eq(index).addClass('active');
48
49				currentSlide = index;
50
51				setTimeout(function() {
52					isAnimating = false;
53				}, 800);
54
55				if (autoRotate) {
56					resetAutoRotate();
57				}
58			}
59
60			function nextSlide() {
61				const next = (currentSlide + 1) % $slides.length;
62				goToSlide(next, 'next');
63			}
64
65			function prevSlide() {
66				const prev = (currentSlide - 1 + $slides.length) % $slides.length;
67				goToSlide(prev, 'prev');
68			}
69
70			function startAutoRotate() {
71				if (autoRotate && !autoRotateInterval) {
72					autoRotateInterval = setInterval(nextSlide, rotationSpeed);
73				}
74			}
75
76			function stopAutoRotate() {
77				if (autoRotateInterval) {
78					clearInterval(autoRotateInterval);
79					autoRotateInterval = null;
80				}
81			}
82
83			function resetAutoRotate() {
84				stopAutoRotate();
85				startAutoRotate();
86			}
87
88			$nextBtn.on('click', function(e) {
89				e.preventDefault();
90				nextSlide();
91			});
92
93			$prevBtn.on('click', function(e) {
94				e.preventDefault();
95				prevSlide();
96			});
97
98			$dots.on('click', function(e) {
99				e.preventDefault();
100				const index = parseInt($(this).data('slide'));
101				if (index !== currentSlide) {
102					goToSlide(index);
103				}
104			});
105
106			$slideshow.on('mouseenter', function() {
107				stopAutoRotate();
108			});
109
110			$slideshow.on('mouseleave', function() {
111				if (autoRotate) {
112					startAutoRotate();
113				}
114			});
115
116			// Keyboard navigation
117			$(document).on('keydown', function(e) {
118				if (!$slideshow.is(':visible')) return;
119				
120				if (e.key === 'ArrowLeft') {
121					prevSlide();
122				} else if (e.key === 'ArrowRight') {
123					nextSlide();
124				}
125			});
126
127			// Touch/swipe support
128			let touchStartX = 0;
129			let touchEndX = 0;
130
131			$slideshow.on('touchstart', function(e) {
132				touchStartX = e.changedTouches[0].screenX;
133			});
134
135			$slideshow.on('touchend', function(e) {
136				touchEndX = e.changedTouches[0].screenX;
137				handleSwipe();
138			});
139
140			function handleSwipe() {
141				const swipeThreshold = 50;
142				const diff = touchStartX - touchEndX;
143
144				if (Math.abs(diff) > swipeThreshold) {
145					if (diff > 0) {
146						nextSlide();
147					} else {
148						prevSlide();
149					}
150				}
151			}
152
153		startAutoRotate();
154
155		// Animate inline stats numbers when the first slide loads
156		const $firstSlideStats = $slides.eq(0).find('.hero-slideshow__inline-stats');
157		if ($firstSlideStats.length) {
158			// Animate immediately for the first slide
159			$firstSlideStats.find('.hero-slideshow__inline-stat-number').each(function() {
160				animateNumber(this);
161			});
162		}
163
164			function animateNumber(element) {
165				const $element = $(element);
166				const finalText = $element.text();
167				
168				let numericValue, suffix = '';
169				if (finalText.includes('K')) {
170					numericValue = parseFloat(finalText.replace('K', '')) * 1000;
171					suffix = 'K';
172				} else if (finalText.includes('M')) {
173					numericValue = parseFloat(finalText.replace('M', '')) * 1000000;
174					suffix = 'M';
175				} else {
176					numericValue = parseInt(finalText.replace(/,/g, ''), 10);
177				}
178				
179				if (isNaN(numericValue)) return;
180				
181				const duration = 2000;
182				const startTime = performance.now();
183				
184				function easeOutExpo(t) {
185					return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
186				}
187				
188				function formatNumber(num) {
189					if (suffix === 'K') {
190						return Math.round(num / 1000) + 'K';
191					} else if (suffix === 'M') {
192						return (num / 1000000).toFixed(1) + 'M';
193					}
194					return Math.round(num).toLocaleString();
195				}
196				
197				function update(currentTime) {
198					const elapsed = currentTime - startTime;
199					const progress = Math.min(elapsed / duration, 1);
200					const easedProgress = easeOutExpo(progress);
201					const current = numericValue * easedProgress;
202					
203					$element.text(formatNumber(current));
204					
205					if (progress < 1) {
206						requestAnimationFrame(update);
207					} else {
208						$element.text(formatNumber(numericValue));
209					}
210				}
211				
212				requestAnimationFrame(update);
213			}
214		});
215	});
216
217})(jQuery);
218

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.