Butochnikov
12/23/2014 - 10:04 PM

RoyalSlider thumbnails module

RoyalSlider thumbnails module

(function($) {

	"use strict";

	/**
	 *
	 * RoyalSlider thumbnails module
	 * @version 1.0.6:
	 *
	 * 1.0.1
	 * - Fixed bug with vertical thumbs caused by latest update
	 * 
	 * 1.0.2:
	 * - Dynamic adding/removing tabs.
	 *
	 * 1.0.3
	 * - Removed first transition at slider initialization
	 *
	 * 1.0.4
	 * - Added paddingTop & bottom
	 * - firstMargin now accepts number which is min distance of first/last thumbnail
	 *
	 * 1.0.5
	 * - IE10 touch support
	 *
	 * 1.0.6
	 * - Fix issue when autoHeight is enabled
	 *
	 */ 
	$.extend($.rsProto, {
		_initThumbs: function() {
			var self = this;
			if(self.st.controlNavigation === 'thumbnails') {

				self._thumbsDefaults = {
					drag: true,
					touch: true,
					orientation: 'horizontal',
					navigation: true,
					arrows: true,
					arrowLeft: null,
					arrowRight: null,
					spacing: 4,
					arrowsAutoHide: false,
					appendSpan: false,
					transitionSpeed:600,
					autoCenter: true,
					fitInViewport: true, 
					firstMargin: true,
					paddingTop: 0,
					paddingBottom: 0
				};

				self.st.thumbs = $.extend({}, self._thumbsDefaults, self.st.thumbs);
				self._firstThumbMoved = true;
				if(self.st.thumbs.firstMargin === false) { self.st.thumbs.firstMargin = 0; }
				else if(self.st.thumbs.firstMargin === true) { self.st.thumbs.firstMargin = self.st.thumbs.spacing; }

				self.ev.on('rsBeforeParseNode', function(e, content, obj) {
					content = $(content);
					obj.thumbnail = content.find('.rsTmb').remove();
					if(!obj.thumbnail.length) {
						obj.thumbnail = content.attr('data-rsTmb');
						if(!obj.thumbnail) {
							obj.thumbnail = content.find('.rsImg').attr('data-rsTmb');
						}
						if(!obj.thumbnail) {
							obj.thumbnail = '';
						} else {
							obj.thumbnail = '<img src="'+obj.thumbnail+'"/>';
						}
					} else {
						obj.thumbnail = $(document.createElement('div')).append(obj.thumbnail).html();
					}
				});

				self.ev.one('rsAfterPropsSetup', function() {
					self._createThumbs();
				});

				self._prevNavItem = null;
				
				self.ev.on('rsOnUpdateNav', function() {
					var currItem = $(self._controlNavItems[self.currSlideId]);
					if(currItem === self._prevNavItem) {
						return;
					}
					if(self._prevNavItem) {
						self._prevNavItem.removeClass('rsNavSelected');
						self._prevNavItem = null;
					}
					if(self._thumbsNavigation) {					
						self._setCurrentThumb(self.currSlideId);
					}
					self._prevNavItem = currItem.addClass('rsNavSelected');
				});

				self.ev.on('rsOnAppendSlide', function(e, parsedSlide, index) {
					var html = '<div'+self._thumbsMargin+' class="rsNavItem rsThumb">'+self._addThumbHTML+parsedSlide.thumbnail+'</div>';
					if(index >= self.numSlides) {
						self._thumbsContainer.append(html);
					} else {
						self._controlNavItems.eq(index).before(html);
					}
					self._controlNavItems = self._thumbsContainer.children();
					self.updateThumbsSize();
				});
				self.ev.on('rsOnRemoveSlide', function(e, index) {
					var itemToRemove = self._controlNavItems.eq(index);
					if(itemToRemove) {
						itemToRemove.remove();
						self._controlNavItems = self._thumbsContainer.children();
						self.updateThumbsSize();
					}
				});	
				

			}	
		},
		_createThumbs: function() {
			var self = this, 
				tText = 'rsThumbs',
				thumbSt = self.st.thumbs,
				out = '',
				style,
				item,
				spacing = thumbSt.spacing;
			
			self._controlNavEnabled = true;
			self._thumbsHorizontal = (thumbSt.orientation === 'vertical') ? false : true;
			
			self._thumbsMargin = style = spacing ? ' style="margin-' + (self._thumbsHorizontal ? 'right' : 'bottom') + ':'+ spacing+'px;"' : ''; 
			
			self._thumbsPosition = 0;
			self._isThumbsAnimating = false;
			self._thumbsDrag = false;
			self._thumbsNavigation = false;

			self._thumbsArrows = (thumbSt.arrows && thumbSt.navigation);

			var pl = (self._thumbsHorizontal ? 'Hor' : 'Ver');
			self.slider.addClass('rsWithThumbs' + ' rsWithThumbs'+ pl );
			
			out += '<div class="rsNav rsThumbs rsThumbs'+pl +'"><div class="'+tText+'Container">';
			self._addThumbHTML = thumbSt.appendSpan ? '<span class="thumbIco"></span>' : '';
			for(var i = 0; i < self.numSlides; i++) {
				item = self.slides[i];
				out += '<div'+style+' class="rsNavItem rsThumb">'+item.thumbnail+self._addThumbHTML+'</div>';
			}
			out = $(out +'</div></div>');

			var o = {};
			if(thumbSt.paddingTop) {
				o[self._thumbsHorizontal ? 'paddingTop' : 'paddingLeft'] = thumbSt.paddingTop;
			} 
			if(thumbSt.paddingBottom) {
				o[self._thumbsHorizontal ? 'paddingBottom' : 'paddingRight'] = thumbSt.paddingBottom;
			} 
			out.css(o);

			self._thumbsContainer = $(out).find('.' + tText + 'Container');

			var lol = $(out).find(".rsTmb");
		

			if(self._thumbsArrows) {
				tText += 'Arrow';
				if(thumbSt.arrowLeft) {
					self._thumbsArrowLeft = thumbSt.arrowLeft;
				} else {
					self._thumbsArrowLeft = $('<div class="'+ tText +' ' + tText +'Left"><div class="'+tText+'Icn"></div></div>');
					out.append(self._thumbsArrowLeft);
				}

				if(thumbSt.arrowRight) {
					self._thumbsArrowRight = thumbSt.arrowRight;
				} else {
					self._thumbsArrowRight = $('<div class="'+ tText +' ' + tText +'Right"><div class="'+tText+'Icn"></div></div>');
					out.append(self._thumbsArrowRight);
				}

				
				self._thumbsArrowLeft.click(function() {
					var viewportSize = Math.floor(self._thumbsViewportSize / self._thumbSize),
						thumbId = Math.floor(self._thumbsPosition / self._thumbSize),
						newPos = (thumbId + self._visibleThumbsPerView) * self._thumbSize + self._thumbsSpacing;
					self._animateThumbsTo( newPos > self._thumbsMinPosition ? self._thumbsMinPosition : newPos );
				});
				self._thumbsArrowRight.click(function() {
					var viewportSize = Math.floor(self._thumbsViewportSize / self._thumbSize),
						thumbId = Math.floor(self._thumbsPosition / self._thumbSize),
						newPos = (thumbId - self._visibleThumbsPerView) * self._thumbSize + self._thumbsSpacing;
					self._animateThumbsTo( newPos < self._thumbsMaxPosition ? self._thumbsMaxPosition : newPos );
				});
				if(thumbSt.arrowsAutoHide && !self.hasTouch) {
					self._thumbsArrowLeft.css('opacity', 0);
					self._thumbsArrowRight.css('opacity', 0);

					out.one("mousemove.rsarrowshover",function() {
						if(self._thumbsNavigation) {
							self._thumbsArrowLeft.css('opacity', 1);
							self._thumbsArrowRight.css('opacity', 1);		
						}		
					});

					out.hover(
						function() {
							if(self._thumbsNavigation) {
								self._thumbsArrowLeft.css('opacity', 1);
								self._thumbsArrowRight.css('opacity', 1);
							}
						},
						function() {
							if(self._thumbsNavigation) {
								self._thumbsArrowLeft.css('opacity', 0);
								self._thumbsArrowRight.css('opacity', 0);
							}
						}
					);	
				}	
			}

			self._controlNav = out;
			self._controlNavItems = self._thumbsContainer.children();
			

			if(self.msEnabled && self.st.thumbs.navigation) {
				self._thumbsContainer.css('-ms-touch-action', self._thumbsHorizontal ? 'pan-y' : 'pan-x');
			}

			self.slider.append(out);
			
			self._thumbsEnabled = true;
			self._thumbsSpacing = spacing;

			
			if(thumbSt.navigation) {
				if(self._useCSS3Transitions) {
					self._thumbsContainer.css(self._vendorPref + 'transition-property', self._vendorPref + 'transform');
				}
			}
			
			self._controlNav.on('click.rs','.rsNavItem',function(e) {
				if(!self._thumbsDrag ) {
					self.goTo( $(this).index() );
				}
			});

			self.ev.off('rsBeforeSizeSet.thumbs').on('rsBeforeSizeSet.thumbs', function() {
				self._realWrapSize = self._thumbsHorizontal ? self._wrapHeight : self._wrapWidth;
				self.updateThumbsSize(true);
			});
			self.ev.off('rsAutoHeightChange.thumbs').on('rsAutoHeightChange.thumbs', function(e, newHeight) {
				self.updateThumbsSize(true, newHeight);
			});
			
		},
		updateThumbsSize: function(isResize, newHeight) {
			var self = this,
				firstThumb = self._controlNavItems.first(),
				cssObj = {};

			var numItems = self._controlNavItems.length;
			self._thumbSize = ( self._thumbsHorizontal ? firstThumb.outerWidth() : firstThumb.outerHeight() ) + self._thumbsSpacing;
			self._thumbsContainerSize = numItems * self._thumbSize - self._thumbsSpacing;
			cssObj[self._thumbsHorizontal ? 'width' : 'height'] = self._thumbsContainerSize + self._thumbsSpacing;
			
			self._thumbsViewportSize = self._thumbsHorizontal ? self._controlNav.width() : (newHeight !== undefined ? newHeight : self._controlNav.height());
			

			if(self._thumbsEnabled && (self.isFullscreen || self.st.thumbs.fitInViewport)) {
				if(self._thumbsHorizontal) {
					self._wrapHeight = self._realWrapSize - self._controlNav.outerHeight();
				} else {
					self._wrapWidth = self._realWrapSize - self._controlNav.outerWidth();
				}
			}
			
			if(!self._thumbsViewportSize) {
				return;
			}

			self._thumbsMaxPosition = -(self._thumbsContainerSize - self._thumbsViewportSize) - (self.st.thumbs.firstMargin);
			self._thumbsMinPosition = self.st.thumbs.firstMargin;
			self._visibleThumbsPerView = Math.floor(self._thumbsViewportSize / self._thumbSize);

			if(self._thumbsContainerSize < self._thumbsViewportSize) {
				if(self.st.thumbs.autoCenter) {
					self._setThumbsPosition((self._thumbsViewportSize - self._thumbsContainerSize) / 2);
				}
				if(self.st.thumbs.arrows && self._thumbsArrowLeft) {
					var arrDisClass = 'rsThumbsArrowDisabled';
					self._thumbsArrowLeft.addClass(arrDisClass);
					self._thumbsArrowRight.addClass(arrDisClass);
				}
				self._thumbsNavigation = false;
				self._thumbsDrag = false;
				self._controlNav.off(self._downEvent);	

			} else if(self.st.thumbs.navigation && !self._thumbsNavigation) {
				self._thumbsNavigation = true;
				if( (!self.hasTouch && self.st.thumbs.drag) ||  (self.hasTouch && self.st.thumbs.touch)) {
					self._thumbsDrag = true;
					self._controlNav.on(self._downEvent, function(e) { self._onDragStart(e, true); });	
				}
			}

			

			

			

			self._thumbsContainer.css(cssObj);
			if(isResize && newHeight) {
				self._setCurrentThumb(self.currSlideId);
			}

			if(self._useCSS3Transitions) {
				cssObj[(self._vendorPref + 'transition-duration')] = '0ms';
			}


			
		},
		setThumbsOrientation: function(newPlacement, dontUpdateSize) {
			var self = this;
			if(self._thumbsEnabled) {
				self.st.thumbs.orientation = newPlacement;
				self._controlNav.remove();
				self.slider.removeClass('rsWithThumbsHor rsWithThumbsVer');
				self._createThumbs();
				self._controlNav.off(self._downEvent);	
				if(!dontUpdateSize) {
					self.updateSliderSize(true);
				}
			}
		},
		_setThumbsPosition: function(pos) {
			var self = this;
			self._thumbsPosition = pos;
			if(self._useCSS3Transitions) {
				self._thumbsContainer.css(self._xProp, self._tPref1 + ( self._thumbsHorizontal ? (pos + self._tPref2 + 0) : (0 + self._tPref2 + pos) ) + self._tPref3 );		
			} else {
				self._thumbsContainer.css(self._thumbsHorizontal ? self._xProp : self._yProp, pos);
			}
		},
		_animateThumbsTo: function(pos, speed, outEasing, bounceAnimPosition, bounceAnimSpeed) {
			var self = this;
			if(!self._thumbsNavigation) {
				return;
			}
			if(!speed) {
				speed = self.st.thumbs.transitionSpeed;
			}
			self._thumbsPosition = pos;
			if(self._thumbsAnimTimeout) {
				clearTimeout(self._thumbsAnimTimeout);
			}
			if(self._isThumbsAnimating) {
				if(!self._useCSS3Transitions) {
					self._thumbsContainer.stop();
				}
				outEasing = true;
			}
			var animObj = {};
			self._isThumbsAnimating = true;
			if(!self._useCSS3Transitions) {
				animObj[self._thumbsHorizontal ? self._xProp : self._yProp] = pos + 'px';
				self._thumbsContainer.animate(animObj, speed, outEasing ? 'easeOutCubic' : self.st.easeInOut);
			} else { 
				animObj[(self._vendorPref + 'transition-duration')] = speed+'ms';
				animObj[(self._vendorPref + 'transition-timing-function')] = outEasing ? $.rsCSS3Easing[self.st.easeOut] : $.rsCSS3Easing[self.st.easeInOut];
				self._thumbsContainer.css(animObj);
				self._setThumbsPosition(pos);
			}
			if(bounceAnimPosition) {
				self._thumbsPosition = bounceAnimPosition;
			}
			self._updateThumbsArrows();
			
			
			self._thumbsAnimTimeout = setTimeout(function() {
				self._isThumbsAnimating = false;
				if(bounceAnimSpeed) {
					self._animateThumbsTo(bounceAnimPosition, bounceAnimSpeed, true);
					bounceAnimSpeed = null;
				}
			}, speed);
		},
		_updateThumbsArrows: function() {
			var self = this;
			if(self._thumbsArrows) {
				var arrDisClass = 'rsThumbsArrowDisabled';
				
				if(self._thumbsPosition === self._thumbsMinPosition) {
					self._thumbsArrowLeft.addClass(arrDisClass);
				} else {
					self._thumbsArrowLeft.removeClass(arrDisClass);
				}
				if(self._thumbsPosition === self._thumbsMaxPosition) {
					self._thumbsArrowRight.addClass(arrDisClass);
				} else {
					self._thumbsArrowRight.removeClass(arrDisClass);
				}
			}
		},
		_setCurrentThumb: function(id, justSet) {
			
			var self = this,
				incr = 0,
				newPos,
				nextThumbEndPos = (id * self._thumbSize + self._thumbSize * 2 - self._thumbsSpacing + self._thumbsMinPosition),
				thumbId = Math.floor(self._thumbsPosition / self._thumbSize);
			
			if(!self._thumbsNavigation) {
				return;
			}
			if(self._firstThumbMoved) {
				justSet = true;
				self._firstThumbMoved = false;
			}

			if(nextThumbEndPos  + self._thumbsPosition > self._thumbsViewportSize) {
				if(id === self.numSlides - 1) {
					incr = 1;
				}
				thumbId = -id + self._visibleThumbsPerView - 2 + incr;
				newPos = thumbId * self._thumbSize + (self._thumbsViewportSize % self._thumbSize) + self._thumbsSpacing - self._thumbsMinPosition;
			} else {
				if(id !== 0) {
					if( (id-1) * self._thumbSize <= -self._thumbsPosition + self._thumbsMinPosition && (id-1) <= self.numSlides - self._visibleThumbsPerView) {
						thumbId = -id + 1;
						newPos = thumbId * self._thumbSize + self._thumbsMinPosition;
					}
				} else {
					thumbId = 0;
					newPos = self._thumbsMinPosition;
				}
			}

			if(newPos !== self._thumbsPosition) {
				var checkPos = (newPos === undefined) ? self._thumbsPosition : newPos;
				if(checkPos > self._thumbsMinPosition) {
					self._setThumbsPosition(self._thumbsMinPosition);
				} else if(checkPos < self._thumbsMaxPosition) {
					self._setThumbsPosition(self._thumbsMaxPosition);
				} else  if(newPos !== undefined) {
					if(!justSet) {
						self._animateThumbsTo(newPos);
					} else {
						self._setThumbsPosition(newPos);
					}
				}
			}
			self._updateThumbsArrows();
		}
	});
	$.rsModules.thumbnails = $.rsProto._initThumbs;
})(jQuery);