1(function ($) { 2 function animate({ timing, draw, duration }) { 3 let start = performance.now(); 4 5 requestAnimationFrame(function animate(time) { 6 // timeFraction goes from 0 to 1 7 let timeFraction = (time - start) / duration; 8 if (timeFraction > 1) timeFraction = 1; 9 10 // calculate the current animation state 11 let progress = timing(timeFraction) 12 13 draw(progress); // draw it 14 15 if (timeFraction < 1) { 16 requestAnimationFrame(animate); 17 } 18 }); 19 } 20 21 function slider_sync() { 22 $('.module-slider,.module-background_slider').find('[data-sync-with]').each(function () { 23 const swiper = $($(this).data('sync-with')).find('.slider-wrapper .swiper-container')[0]; 24 if (this.swiper && swiper.swiper) { 25 this.swiper.controller.control = this.swiper.controller.control || []; 26 this.swiper.controller.control.push(swiper.swiper); 27 28 swiper.swiper.controller.control = swiper.swiper.controller.control || []; 29 swiper.swiper.controller.control.push(this.swiper); 30 } 31 }); 32 } 33 34 function slider(el) { 35 const sliderEl = el.querySelector('.slider-wrapper'); 36 const thumbsEl = el.querySelector('.slider-thumbs'); 37 38 if (sliderEl.querySelector('.swiper-container').swiper) { 39 return; 40 } 41 42 // main 43 const options = $.extend(true, { 44 init: false, 45 watchOverflow: true, 46 watchSlidesProgress: true, 47 slideToClickedSlide: true, 48 parallax: { 49 enabled: true 50 }, 51 fadeEffect: { 52 crossFade: true 53 }, 54 coverflowEffect: { 55 rotate: 50, 56 stretch: 0, 57 depth: 100, 58 modifier: 1, 59 slideShadows: false, 60 }, 61 keyboard: { 62 enabled: true, 63 onlyInViewport: true, 64 pageUpDown: false 65 }, 66 cardsEffect: { 67 slideShadows: false 68 }, 69 flipEffect: { 70 slideShadows: false, 71 }, 72 // mousewheel: { 73 // forceToAxis: true 74 // }, 75 pagination: { 76 el: sliderEl.querySelector('.swiper-pagination'), 77 clickable: true, 78 renderBullet(index, className) { 79 let html = ''; 80 81 html += '<span class="' + className + '" tabindex="' + index + '" role="button" aria-label="Go to slide ' + (index + 1) +'">'; 82 83 if (options.autoplay) { 84 if (options.bulletsType === 'dots') { 85 html += '<div class="swiper-timeline-dots"> <svg viewBox="0 0 40 40"> <circle fill="none" stroke-linecap="round" cx="20" cy="20" r="15.915494309"/></svg></div>'; 86 } else { 87 html += '<div class="swiper-timeline"></div>'; 88 } 89 } 90 91 html += '</span>'; 92 93 return html; 94 } 95 }, 96 navigation: { 97 nextEl: sliderEl.querySelector('.swiper-button-next'), 98 prevEl: sliderEl.querySelector('.swiper-button-prev') 99 }, 100 scrollbar: { 101 el: sliderEl.querySelector('.swiper-scrollbar'), 102 draggable: true, 103 }, 104 on: {} 105 }, $(sliderEl.querySelector('.swiper-wrapper')).data('options')); 106 107 if (options.slidesPerView === 'auto') { 108 options.effect = 'slide'; 109 options.on.reachEnd = function () { 110 this.snapGrid = [...this.slidesGrid]; 111 setTimeout(() => { 112 const $next = document.querySelector('.swiper-button-next'); 113 114 if ($next) { 115 $next.dispatchEvent(new MouseEvent('click', { 116 bubbles: false 117 })); 118 } 119 }, 1); 120 } 121 } 122 123 // thumbs 124 if (thumbsEl) { 125 const thumbsOptions = $.extend(true, { 126 slidesPerView: 'auto', 127 slideToClickedSlide: true, 128 observer: true, 129 resizeObserver: true, 130 freeMode: { 131 enabled: options.thumbsFreeMode, 132 sticky: false, 133 }, 134 }, $(thumbsEl).data('options')); 135 136 const thumbs = new SwiperLatest(thumbsEl.querySelector('.swiper-container'), thumbsOptions); 137 138 options.thumbs = { 139 swiper: thumbs, 140 slideThumbActiveClass: 'swiper-slide-active' 141 } 142 } 143 144 // timeline 145 if (options.autoplay && options.autoplay.delay) { 146 let $timeline = null; 147 148 function onProgress() { 149 if ($timeline === null) { 150 $timeline = el.querySelectorAll('.swiper-timeline, .swiper-timeline-dots'); 151 } 152 153 if (!$timeline.length) { 154 return; 155 } 156 157 return animate({ 158 duration: options.autoplay.delay, 159 timing: function (x) { 160 return x; 161 }, 162 draw: function (progress) { 163 $timeline.forEach(function ($el) { 164 $el.style.setProperty('--timeline-progress', progress); 165 $el.style.setProperty('--timeline-progress-circle', 100 - Math.round(progress * 100)); 166 // $el.style.transform = 'scaleX(' + progress + ')'; 167 }); 168 } 169 }) 170 } 171 172 options.on.init = onProgress; 173 options.on.slideChange = onProgress; 174 175 if (options.autoplay && options.autoplay.delay && options.pauseOnMouseEnter) { 176 options.on.autoplayStart = function (swiper) { 177 // el.classList.remove('swiper-autoplay-paused') 178 179 onProgress(); 180 }; 181 182 options.on.autoplayStop = function (swiper) { 183 // el.classList.add('swiper-autoplay-paused'); 184 } 185 } 186 } 187 188 const swiper = new SwiperLatest(sliderEl.querySelector('.swiper-container'), options); 189 190 if (thumbsEl && !options.thumbsFreeMode) { 191 swiper.on('snapIndexChange', function() { 192 options.thumbs.swiper.slideTo(swiper.activeIndex); 193 }); 194 195 options.thumbs.swiper.on('slideChangeTransitionStart', function() { 196 swiper.slideTo(options.thumbs.swiper.activeIndex); 197 }); 198 } 199 200 if (options.autoplay && options.autoplay.delay && options.pauseOnMouseEnter) { 201 $(el).on('mouseenter', function () { 202 swiper.autoplay.stop(); 203 }); 204 205 $(el).on('mouseleave', function () { 206 swiper.autoplay.start(); 207 }); 208 } 209 210 // video 211 const videos = sliderEl.querySelectorAll('video'); 212 213 if (videos.length) { 214 function videoStarted(event) { 215 swiper.slides[swiper.activeIndex].setAttribute('data-swiper-autoplay', Math.round(event.target.duration * 1000)); 216 217 if (swiper.params.autoplay.enabled && swiper.autoplay.running) { 218 swiper.autoplay.stop(); 219 swiper.autoplay.start(); 220 } 221 } 222 223 function videoEnded() { 224 // console.log('ended', swiper.autoplay); 225 // 226 // if (swiper.params.autoplay.enabled && !swiper.autoplay.running) { 227 // swiper.slideNext(); 228 // swiper.autoplay.start(); 229 // } 230 } 231 232 swiper.on('init slideChange', function (swiper) { 233 // pause previous video, if any 234 if (swiper.previousIndex !== undefined) { 235 const video = swiper.slides[swiper.previousIndex].querySelector('video'); 236 237 if (video) { 238 video.removeEventListener('playing', videoStarted); 239 video.removeEventListener('ended', videoEnded); 240 241 video.pause(); 242 video.currentTime = 0; 243 } 244 } 245 246 // play current video, if any 247 const video = swiper.slides[swiper.activeIndex].querySelector('video'); 248 249 if (video) { 250 video.addEventListener('playing', videoStarted); 251 video.addEventListener('ended', videoEnded); 252 253 if (!video.src && video.dataset.src) { 254 video.src = video.dataset.src; 255 } else { 256 video.play(); 257 } 258 } 259 }); 260 } 261 262 swiper.init(); 263 264 return swiper; 265 } 266 267 function background_slider(el) { 268 const sliderEl = el.querySelector('.slider-wrapper'); 269 const thumbsEl = el.querySelector('.slider-thumbs'); 270 271 if (sliderEl.querySelector('.swiper-container').swiper) { 272 return; 273 } 274 const options = $.extend(true, { 275 slidesPerView: 1, 276 fadeEffect: { 277 crossFade: true 278 } 279 }, $(sliderEl.querySelector('.swiper-wrapper')).data('options')); 280 281 return new SwiperLatest(sliderEl.querySelector('.swiper-container'), options); 282 } 283 284 Journal.lazy('slider', '.module-slider', { 285 load: function (el) { 286 Journal.load(Journal['assets']['swiper-latest'], 'swiper-latest', function () { 287 slider(el); 288 slider_sync(); 289 }); 290 } 291 }); 292 293 Journal.lazy('background_slider', '.module-background_slider', { 294 load: function (el) { 295 Journal.load(Journal['assets']['swiper-latest'], 'swiper-latest', function () { 296 background_slider(el); 297 slider_sync(); 298 }); 299 } 300 }); 301})(jQuery);
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.