PageSourceSearch

https://estorilpraia.pt/store/catalog/view/theme/journal3/js/slider.js?v=dbc52b11

js estorilpraia.pt collected 2026-10-02 10:03:57 UTC 7,740 bytes, 301 lines download raw bytes

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.