1(function () { 2 'use strict'; 3 4 var SPEED = 5; // seconds it takes for ONE slide to scroll past 5 var REVERSE = false; // false = standard (track moves left), true = reversed 6 function getMaxElevation() { 7 return window.innerWidth >= 768 ? 100 : 26; // desktop: 100px, below 768: 26px 8 } 9 10 function slideIntersectsContainer(containerRect, slideRect) { 11 return slideRect.right > containerRect.left && 12 slideRect.left < containerRect.right && 13 slideRect.bottom > containerRect.top && 14 slideRect.top < containerRect.bottom; 15 } 16 17 function updateSlidesAriaHidden(containerRect, slides) { 18 for (var i = 0; i < slides.length; i++) { 19 var slide = slides[i]; 20 var sr = slide.getBoundingClientRect(); 21 var visible = slideIntersectsContainer(containerRect, sr); 22 var next = visible ? 'false' : 'true'; 23 if (slide.getAttribute('aria-hidden') !== next) { 24 slide.setAttribute('aria-hidden', next); 25 } 26 } 27 } 28 29 function syncMotionToggleUi(toggle, paused) { 30 if (!toggle) return; 31 32 var pauseIcon = toggle.querySelector('.js-gallery-motion-icon-pause'); 33 var playIcon = toggle.querySelector('.js-gallery-motion-icon-play'); 34 var ariaPlaying = toggle.getAttribute('data-aria-when-playing'); 35 var ariaPaused = toggle.getAttribute('data-aria-when-paused'); 36 37 toggle.setAttribute('aria-pressed', paused ? 'true' : 'false'); 38 39 if (pauseIcon && playIcon) { 40 pauseIcon.hidden = paused; 41 playIcon.hidden = !paused; 42 } 43 44 if (ariaPlaying && ariaPaused) { 45 var label = paused ? ariaPaused : ariaPlaying; 46 toggle.setAttribute('aria-label', label); 47 toggle.setAttribute('title', label); 48 } 49 } 50 51 function initSlider(slider) { 52 var container = slider.closest('.js-gallery-container'); 53 if (!container) return; 54 55 // Editor preview: leave slides as a plain static row, skip the marquee/animation entirely. 56 if (container.classList.contains('gallery__container--static')) { 57 return; 58 } 59 60 var galleryRoot = container.closest('.ss.gallery'); 61 var motionToggle = galleryRoot ? galleryRoot.querySelector('.js-gallery-motion-toggle') : null; 62 63 var originals = Array.from(slider.querySelectorAll('.js-gallery-slide')); 64 var slideCount = originals.length; 65 if (!slideCount) return; 66 67 var track = document.createElement('div'); 68 track.className = 'gallery__slider-track'; 69 70 for (var s = 0; s < 3; s++) { 71 originals.forEach(function (el) { 72 track.appendChild(el.cloneNode(true)); 73 }); 74 } 75 76 slider.innerHTML = ''; 77 slider.appendChild(track); 78 79 var kfId = 'slider-kf-' + (Math.random().toString(36).slice(2)); 80 var kfStyle = document.createElement('style'); 81 kfStyle.id = kfId; 82 document.head.appendChild(kfStyle); 83 84 function getVisibleCount() { 85 if (window.innerWidth <= 767) return 1.79; 86 if (window.innerWidth <= 1199) return 3; 87 return 4.23; 88 } 89 90 var lastInnerWidth; 91 var lastContainerWidth; 92 var motionPaused = false; 93 94 function applyMotionState() { 95 track.style.animationPlayState = motionPaused ? 'paused' : 'running'; 96 syncMotionToggleUi(motionToggle, motionPaused); 97 } 98 99 function setMotionPaused(paused) { 100 motionPaused = paused; 101 applyMotionState(); 102 } 103 104 function setup() { 105 // Reserve top space so cards stay visible when translated up 106 container.style.paddingTop = getMaxElevation() + 'px'; 107 108 var count = getVisibleCount(); 109 var cw = container.offsetWidth; 110 var sw = cw / count; 111 112 track.querySelectorAll('.js-gallery-slide').forEach(function (s) { 113 s.style.width = sw + 'px'; 114 }); 115 116 var setW = sw * slideCount; 117 var duration = SPEED * slideCount; 118 119 var fromX = REVERSE ? -2 * setW : -setW; 120 var toX = REVERSE ? -setW : -2 * setW; 121 122 kfStyle.textContent = 123 '@keyframes slide-' + kfId + '{' + 124 'from{transform:translateX(' + fromX + 'px)}' + 125 'to{transform:translateX(' + toX + 'px)}' + 126 '}'; 127
128 track.style.animation = 'none'; 129 void track.offsetHeight; 130 track.style.animation = 'slide-' + kfId + ' ' + duration + 's linear infinite'; 131 applyMotionState(); 132 133 lastInnerWidth = window.innerWidth; 134 lastContainerWidth = container.offsetWidth; 135 } 136 137 setup(); 138 139 if (motionToggle) { 140 motionToggle.addEventListener('click', function () { 141 setMotionPaused(!motionPaused); 142 }); 143 } 144 145 if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 146 setMotionPaused(true); 147 } 148 149 function wave() { 150 var cr = container.getBoundingClientRect(); 151 var cx = cr.left + cr.width / 2; 152 var half = cr.width * 0.5; 153 var allSlides = track.querySelectorAll('.js-gallery-slide'); 154 155 updateSlidesAriaHidden(cr, allSlides); 156 157 for (var i = 0; i < allSlides.length; i++) { 158 var sr = allSlides[i].getBoundingClientRect(); 159 var card = allSlides[i].querySelector('.js-gallery-card'); 160 if (!card) continue; 161 162 if (sr.right < cr.left - sr.width || sr.left > cr.right + sr.width) { 163 card.style.transform = 'translateY(0)'; 164 continue; 165 } 166 167 var midX = sr.left + sr.width / 2; 168 var norm = Math.min(Math.abs(midX - cx) / half, 1); 169 var t = Math.cos(norm * Math.PI / 2); 170 171 var elevation = getMaxElevation() * t; 172 card.style.transform = 'translateY(-' + elevation + 'px)'; 173 } 174 175 requestAnimationFrame(wave); 176 } 177 178 requestAnimationFrame(wave); 179 180 var resizeTimer; 181 window.addEventListener('resize', function () { 182 clearTimeout(resizeTimer); 183 resizeTimer = setTimeout(function () { 184 var iw = window.innerWidth; 185 var cw = container.offsetWidth; 186 if (iw === lastInnerWidth && cw === lastContainerWidth) { 187 return; 188 } 189 setup(); 190 }, 150); 191 }); 192 } 193 194 function run() { 195 // Scope to gallery block so we don't conflict with other sliders 196 var sliders = document.querySelectorAll('.js-gallery-slider'); 197 if (!sliders.length) return; 198 sliders.forEach(function (slider) { 199 if (slider.dataset.galleryInitialized) return; 200 slider.dataset.galleryInitialized = '1'; 201 initSlider(slider); 202 }); 203 } 204 205 if (document.readyState === 'loading') { 206 document.addEventListener('DOMContentLoaded', run); 207 } else { 208 run(); 209 } 210 211 if (typeof window.acf !== 'undefined') { 212 window.acf.addAction('render_block_preview/type=gallery', function () { 213 setTimeout(run, 100); 214 }); 215 } 216})();
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.