PageSourceSearch

https://e2c-nimes.fr/wp-content/themes/course-builder/assets/js/libs/jquery.thim-content-slider.js?ver=3.7.1

js e2c-nimes.fr collected 2026-10-07 16:17:39 UTC 14,433 bytes, 560 lines download raw bytes

1/**
2 * jQuery Content Slider plugin
3 *
4 * @author ThimPress
5 */
6;
7(function ($) {
8	$.thimContentSlider = function (el, options) {
9		this.$el = $(el).addClass('thim-content-slider');
10		this.$items = [];
11		this.options = $.extend({}, $.fn.thimContentSlider.defaults, options);
12		var root = this,
13			$win = $(window),
14			$doc = $(document),
15			$body = $(document.body),
16			containerWidth = 0,
17			updateTimer = null,
18			playTimer = null,
19			midElement = 0,
20			activeElement = 0,
21			viewPortWidth = 0,
22			scrolling = false,
23			currentItem = 0,
24			maxItems = 0,
25			ratio = this.options.activeItemRatio || 2.5,
26			activeItemPadding = this.options.activeItemPadding,
27			itemWidth = 0,
28			midItemWidth = 0,
29			itemsVisible = this.options.itemsVisible || 7,
30			midPosition = 0,
31			navDuration = 250,
32			touch = {},
33			isTouch = "ontouchstart" in window || window.navigator.msMaxTouchPoints,
34			events = {
35				start: isTouch ? 'touchstart' : 'mousedown',
36				move : isTouch ? 'touchmove' : 'mousemove',
37				end  : isTouch ? 'touchend' : 'mouseup'
38			},
39			_speed = '',
40			_showContent = true;
41
42		function createItem(args) {
43			var $item = $(' \
44				<li> \
45					<div class="slide-content" style="margin: ' + _opt('itemPadding') + 'px;"> \
46						<img src="' + args.image + '" /> \
47					</div> \
48				</li> \
49			');
50			return $item;
51		}
52
53		function parseItems() {
54			var itemType = typeof root.options.items,
55				$items = null;
56			if (itemType == 'string') {
57				$items = $(root.options.items);
58			} else if (itemType == 'object') {
59				$items = $(root.options.items).children();
60			}
61			if ($items) {
62				root.options.items = [];
63				$items.each(function () {
64					var $item = $(this),
65						$img = $item.find('img' + root.options.imageSelector + ':first'),
66						$url = $img.parent();
67					root.options.items.push({
68						image  : $img.attr('src'),
69						url    : $url.is('a') ? $url.attr('href') : '',
70						content: $item.find(root.options.contentSelector)
71					});
72				});
73			}
74		}
75
76		function createHTML() {
77			var $html = $(' \
78					<div class="slides-content"></div>\
79					<div class="slides-wrapper"> \
80						<ul class="scrollable"></ul> \
81						<a href="prev" class="control-nav prev"></a> \
82						<a href="next" class="control-nav next"></a> \
83					</div> \
84				'),
85				items = root.options.items;
86			root.$el.html($html);
87			root.$slidesWrapper = root.$el.find('.slides-wrapper');
88			root.$scrollable = root.$el.find('.scrollable').css({
89				marginTop   : -_opt('itemPadding'),
90				marginBottom: -_opt('itemPadding')
91			});
92			root.$slideContent = root.$el.find('.slides-content');
93			for (var i = 0, n = items.length; i < n; i++) {
94				var $item = createItem({image: items[i].image}),
95					$content = $('<div class="slide-content" />').append(items[i].content);
96				root.$scrollable.append($item);
97				root.$slideContent.append($content);
98			}
99			root.$items = root.$scrollable.children();
100
101			itemsVisible = _opt('itemsVisible') <= _opt('items').length ? _opt('itemsVisible') : _opt('items').length;
102			midElement = Math.floor(itemsVisible / 2);
103			activeElement = midElement;
104			maxItems = root.$items.length;
105			currentItem = activeElement;
106
107			root.$el
108				.on('click', '.control-nav', _controlNav)
109				.on('click', '.scrollable > li', _controlNav);
110
111			if (root.options.mouseWheel) {
112				root.$el
113					.on('mousewheel', function (e, t, n, r) {
114						e.preventDefault();
115						if (t != -1) _prevItem();
116						else _nextItem();
117					});
118			}
119
120			if (root.options.autoPlay) {
121				_autoPlay();
122			}
123
124			if (root.options.pauseOnHover) {
125				root.$el.hover(function () {
126					_pause();
127				}, function () {
128					_restart();
129				});
130			}
131
132			root.$scrollable
133				.bind(events.start, _touchStart)
134				.bind(events.move, _touchMove)
135				.bind(events.end, _touchEnd)
136
137			_initNav();
138			root.$slideContent.children().eq(activeElement).css({opacity: 1}).addClass('current').siblings().removeClass('current');
139		}
140
141		function _touchStart() {
142			// TODO:
143		}
144
145		function _touchMove() {
146			// TODO:
147		}
148
149		function _touchEnd() {
150			// TODO:
151		}
152
153		function _showNav() {
154			var $nav = root.$nav,
155				navHeight = $nav.height(),
156				left = _opt('controlNav') == 'behind' ? (containerWidth - midItemWidth) / 2 - navHeight + 20 : 20;
157			$nav.show();
158			$nav.first().css({
159				left   : left,
160				opacity: 0
161			}).stop().animate({
162				opacity: 1,
163				left   : left - 20
164			}, navDuration);
165			$nav.last().css({
166				right  : left,
167				opacity: 0
168			}).stop().animate({
169				opacity: 1,
170				right  : left - 20
171			}, navDuration);
172		}
173
174		function _hideNav() {
175			var $nav = root.$nav;
176			$nav.first().stop().animate({
177				opacity: 0,
178				left   : '+=20'
179			}, navDuration);
180			$nav.last().stop().animate({
181				opacity: 0,
182				right  : '+=20'
183			}, navDuration);
184		}
185
186		function _initNav() {
187			var $nav = root.$el.find('.control-nav')
188			root.$el.hover(function () {
189				root.$el.addClass('hover');
190				//_showNav();
191			}, function () {
192				root.$el.removeClass('hover');
193				//_hideNav();
194			});
195			root.$nav = $nav;
196		}
197
198		function updateNav() {
199			var navHeight = root.$nav.height(),
200				css = {
201					top      : (midItemWidth - _opt('itemPadding') * 2) / 2,
202					marginTop: -navHeight / 2
203				};
204			if (_opt('controlNav') == 'behind') {
205
206			}
207			root.$nav.css(css);
208		}
209
210		function _getItemOffset(item) {
211			if (item.hasClass('mid-item')) {
212				return 0;
213			}
214			var itemIndex = root.$items.index(item),
215				midIndex = root.$items.index(root.$items.filter('.mid-item')),
216				offset = itemIndex - midIndex;
217			return offset;
218		}
219
220		function _controlNav(e) {
221			e.preventDefault();
222			var nav = $(this).attr('href');
223			switch (nav) {
224				case 'prev':
225					_prevItem();
226					break;
227				case 'next':
228					_nextItem();
229					break;
230				default:
231					var $item = $(e.target);
232					if (!$item.is('li')) {
233						$item = $item.closest('li');
234					}
235					_move(_getItemOffset($item));
236
237			}
238		}
239
240		function _animateDone(dir, callback) {
241			if (dir == 'prev') {
242				root.$items.last().remove();
243			} else {
244				root.$items.first().remove();
245			}
246			_getItems();
247			root.$items.eq(midElement).addClass('mid-item').siblings().removeClass('mid-item');
248			if (_showContent) {
249				root.$slideContent.children().eq(currentItem).stop().show().animate({opacity: 1}).siblings().hide();
250			}
251			scrolling = false;
252			_restart();
253			if (root.$el.hasClass('hover')) {
254				//_showNav();
255			}
256			$.isFunction(callback) && callback.apply(root);
257		}
258
259		function _move(offset) {
260			if (offset == 0) {
261				_speed = '';
262				_showContent = true;
263				return;
264			} else if (Math.abs(offset) == 1) {
265				_showContent = true;
266			} else {
267				_showContent = false;
268			}
269			//_hideNav();
270			_speed = 250;
271			var dir = offset < 0 ? _prevItem : _nextItem;
272			dir.call(this, function () {
273				_move(offset < 0 ? offset + 1 : offset - 1);
274			})
275		}
276
277		function _prevItem(callback) {
278			if (scrolling) return;
279			_pause();
280			//_hideNav();
281			scrolling = true;
282			root.$slideContent.children().eq(currentItem).stop().animate({opacity: 0});
283			currentItem--;
284			if (currentItem < 0) {
285				currentItem = maxItems - 1;
286			}
287			var itemPadding = _opt('itemPadding'),
288				top = parseInt( ( midItemWidth - itemWidth ) / 2 ),
289				start = 0,
290				end = root.$items.length,
291				count = 0,
292				_done = function () {
293					count++;
294					if (count == end) {
295						_animateDone('prev', callback);
296					}
297				};
298			var $clone = root.$items.last().clone();
299			$clone.insertBefore(root.$items.first()).css({
300				left: parseInt(root.$items.first().css('left')) - itemWidth
301			});
302			_getItems();
303			root.$el.find('.mid-item').removeClass('mid-item');
304			root.$items.eq(activeElement + 1).addClass('mid-item');
305			for (var i = start; i <= end; i++) {
306				var animation = {
307					left : midPosition - ( activeElement - i ) * itemWidth,
308					width: itemWidth,
309					top  : top
310				}
311				if (i < activeElement) {
312					animation.left -= activeItemPadding;
313				} else if (i == activeElement) {
314					animation.left = midPosition;
315					animation.top = 0;
316					animation.width = midItemWidth
317				} else if (i == activeElement + 1) {
318					animation.left = midPosition + midItemWidth + activeItemPadding;
319					animation.top = top;
320					animation.width = itemWidth
321				} else {
322					animation.left += (midItemWidth - itemWidth) + activeItemPadding;
323				}
324				root.$items.eq(i).stop().show().animate(animation, _speed, _done);
325			}
326		}
327
328		function _nextItem(callback) {
329			if (scrolling) return;
330			_pause();
331			//_hideNav();
332			scrolling = true;
333			root.$slideContent.children().eq(currentItem).stop().animate({opacity: 0});
334			currentItem++;
335			if (currentItem >= maxItems) {
336				currentItem = 0;
337			}
338			var itemPadding = _opt('itemPadding'),
339				top = parseInt( ( midItemWidth - itemWidth ) / 2 ),
340				start = 0,
341				end = root.$items.length,
342				count = 0,
343				_done = function () {
344					count++;
345					if (count == end) {
346						_animateDone('next', callback);
347					}
348				};
349			var $clone = root.$items.first().clone();
350			$clone.insertAfter(root.$items.last()).css({
351				left: parseInt(root.$items.last().css('left')) + itemWidth
352			});
353			_getItems();
354			root.$el.find('.mid-item').removeClass('mid-item');
355			root.$items.eq(activeElement + 1).addClass('mid-item');
356			for (var i = start; i <= end; i++) {
357				var animation = {
358					left : midPosition - ( activeElement - i ) * itemWidth,
359					width: itemWidth,
360					top  : top
361				}
362				if (i < activeElement) {
363					animation.left -= itemWidth + activeItemPadding;
364				} else if (i == activeElement) {
365					animation.left -= itemWidth + activeItemPadding;
366					animation.top = top;
367					animation.width = itemWidth;
368				} else if (i == activeElement + 1) {
369					animation.left = midPosition;
370					animation.top = 0;
371					animation.width = midItemWidth;
372				} else {
373					animation.left = midPosition + midItemWidth + ( i - activeElement - 2 ) * itemWidth + activeItemPadding
374				}
375				root.$items.eq(i).stop().show().animate(animation, _speed, _done);
376			}
377		}
378
379		function _getItems() {
380			root.$items = root.$scrollable.children();
381		}
382
383		function _opt(key) {
384			return root.options[key];
385		}
386
387		function _autoPlay() {
388			playTimer && clearTimeout(playTimer);
389			playTimer = setTimeout(function () {
390				_autoPlay();
391				_nextItem();
392			}, _opt('pauseTime'))
393		}
394
395		function _pause() {
396			playTimer && clearTimeout(playTimer);
397		}
398
399		function _restart() {
400			if (_opt('autoPlay')) {
401				_autoPlay();
402			}
403		}
404
405		function calculate(args) {
406			root.$scrollable.css("width", "");
407			args = $.extend({
408				itemPadding : _opt('itemPadding'),
409				itemMaxWidth: _opt('itemMaxWidth'),
410				itemsVisible: itemsVisible,
411				itemMinWidth: _opt('itemMinWidth')
412			}, args || {});
413			containerWidth = root.$el.width();
414			midItemWidth = parseInt( args.itemMaxWidth + 2 * args.itemPadding );
415			itemWidth = parseInt( midItemWidth / ratio );
416			viewPortWidth = itemWidth * ( args.itemsVisible - 1 ) + midItemWidth + 2 * activeItemPadding;
417
418			if (viewPortWidth > containerWidth) {
419				var mod = viewPortWidth - containerWidth,
420					dx = mod / ( args.itemsVisible + ratio - 1 );
421				if (midItemWidth - dx * ratio < args.itemMinWidth) {
422					if (args.itemsVisible - 2 >= 1) {
423						args.itemsVisible -= 2;
424						calculate({
425							itemsVisible: args.itemsVisible,
426						});
427						return;
428					}
429				} else {
430					midItemWidth -= dx * ratio;
431					itemWidth -= dx;
432				}
433				viewPortWidth = containerWidth;//???
434			} else {
435				root.$scrollable.width(viewPortWidth);
436			}
437			midPosition = parseInt( ( viewPortWidth - midItemWidth ) / 2 );
438		}
439
440		function _update() {
441			calculate();
442			updateNav();
443			var itemPadding = _opt('itemPadding');
444			root.$scrollable.height(midItemWidth);
445			var left = 0,
446				top = parseInt( ( midItemWidth - itemWidth ) / 2 ),
447				start = 0,
448				end = root.$items.length - 1;
449			root.$items.hide();
450			for (var i = start; i <= end; i++) {
451				root.$items.eq(i).show();
452				if (i == activeElement) {
453					root.$items.eq(i)
454						.css({
455							left : parseInt( midPosition ),
456							width: parseInt( midItemWidth ),
457						})
458						.addClass('mid-item')
459						.find('.slide-content').css({
460							margin: itemPadding
461						});
462				} else {
463					left = midPosition - ( activeElement - i ) * itemWidth;
464					if (i > activeElement) {
465						left += ( midItemWidth - itemWidth ) + activeItemPadding;
466					} else {
467						left -= activeItemPadding;
468					}
469					root.$items.eq(i).css({
470						width: parseInt( itemWidth ),
471						left : parseInt( left ),
472						top  : parseInt( top )
473					}).removeClass('mid-item');
474				}
475			}
476		}
477
478		function update(force) {
479			if (force) {
480				_update();
481			} else {
482				updateTimer && clearTimeout(updateTimer);
483				updateTimer = setTimeout(function () {
484					_update();
485				}, 350)
486			}
487		}
488
489		function init() {
490			parseItems();
491			createHTML();
492			$win.on('resize.thim-content-slider', function () {
493				update();
494			}).trigger('resize.thim-content-slider');
495			_update();
496		}
497
498		// global function
499		this.pause = _pause;
500		this.restart = _restart;
501		this.prev = _prevItem;
502		this.next = _nextItem;
503		this.update = _update;
504		this.move = _move;
505
506		init();
507	}
508
509	$.fn.thimContentSlider = function (opt) {
510		var method = false,
511			args = [];
512		if (arguments.length > 0) {
513			if (typeof arguments[0] == 'string') {
514				method = arguments[0];
515				for (var i = 1; i < arguments.length; i++) {
516					args[i - 1] = arguments[i];
517				}
518			}
519		}
520		return $.each(this, function () {
521			var $el = $(this),
522				contentSlider = $el.data('thim-content-slider');
523			if (!contentSlider) {
524				contentSlider = new $.thimContentSlider(this, opt);
525				$el.data('thim-content-slider', contentSlider);
526			}
527			if (method) {
528				if ($.isFunction(contentSlider[method])) {
529					return contentSlider[method].apply(contentSlider, args);
530				}
531				throw 'Method thimContentSlider.' + method + '() does not exists';
532			} else {
533				return $el;
534			}
535		});
536	}
537
538	$.fn.thimContentSlider.defaults = {
539		items            : [
540			{
541				image: '', // thumb of user or product
542				url  : '', // full image of user or product to display in the light-box
543				html : '' // the content to display beside item
544			}
545		],
546		itemMaxWidth     : 200,
547		itemMinWidth     : 150,
548		itemsVisible     : 7,
549		itemPadding      : 10,
550		activeItemRatio  : 2,
551		activeItemPadding: 0,
552		mouseWheel       : true,
553		autoPlay         : true,
554		pauseTime        : 3000,
555		pauseOnHover     : true,
556		imageSelector    : '',
557		contentSelector  : '.content',
558		controlNav       : 'behind'
559	}
560})(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.