1/* Gallery flipper which constantly loops in a circle 2* Author: TN 2011-10-18 3* Version 0.1 4* 5* Tested with jQuery 1.6.4 6* Dependencies: jQuery, jQueryUI with widget factory 7* uses .live() instead of .delegate() due to k2dn using 1.3.2, will not work with jQuery 1.7 as .live() has been deprecated 8* also unable to use .first(), .last() 9*/ 10(function($) { 11 "use strict"; 12 jQuery.widget('sim.flipper', { 13 _slideAnimating: false, 14 _slideWidth: 0, 15 _thumbWidth: 0, 16 _currentThumbPage: 0, 17 _currentThumbOffset: 0, 18 _flipIntervalId: null, 19 _hideDrawerId: null, 20 options: { 21 slideContainer: null, 22 scrollContainer: null, 23 visibleThumbs: 1, 24 autoFlipInterval: false, 25 flipSpeed: 400, 26 hideThumbList: true, 27 showPrevNextLink: true, 28 autoHideDrawer: false, 29 titleMaxLength:0, 30 subTitleMaxLength:0 31 }, 32 _create: function() { 33 var self = this; 34 35 if (this.options.slideContainer === null || this.options.scrollContainer === null) { 36 return(false); 37 } 38 39 /** 40 * size scroll container and add navigation links 41 */ 42 this._initView(); 43 44 /** 45 * add event listeners 46 */ 47 this._addEvents(); 48 49 /** 50 * autoflip if set as option 51 */ 52 if (this.options.autoFlipInterval) { 53 this.autoFlip(); 54 } 55 56 /** 57 * autohide thumb drawer if set as option 58 */ 59 if (this.options.autoHideDrawer) { 60 this._hideDrawerId = window.setTimeout(function() { 61 self._autoHideDrawer(); 62 }, self.options.autoHideDrawer); 63 } 64 65 if (this.options.titleMaxLength) { 66 this.element.find('.flpr-info-title').each(function() { 67 self._textOverflow($(this), self.options.titleMaxLength); 68 }); 69 } 70 71 if (this.options.subTitleMaxLength) { 72 this.element.find('.flpr-info-sub').each(function() { 73 self._textOverflow($(this), self.options.subTitleMaxLength); 74 }); 75 } 76 77 /** 78 * trigger callback after init 79 */ 80 this._trigger('initialized'); 81 }, 82 _initView: function() { 83 var self = this; 84 $('<div/>').addClass('flpr-thumb-scroller').append($('<ul/>').addClass('flpr-thumb-list')).appendTo(this.element); 85 this.element.find('.flpr-thumb').each(function() { 86 $('<li/>').append($(this)).appendTo(self.element.find('.flpr-thumb-list')); 87 }); 88 89 var slideContainers = this.element.find(this.options.scrollContainer).find(this.options.slideContainer), 90 slideOuterWidth = this.element.width(), 91 scrollWidth = slideContainers.length * parseInt(slideOuterWidth, 10), 92 thumbContainers = this.element.find('.flpr-thumb-list').find('li'), 93 thumbContainerFirst = thumbContainers.eq(0), 94 thumbOuterWidth = thumbContainerFirst.outerWidth(true), 95 thumbScrollWidth = thumbContainers.length * parseInt(thumbOuterWidth, 10); 96 97 this._slideWidth = slideOuterWidth; 98 this._thumbWidth = thumbOuterWidth; 99 100 // set container widths and add current class to current thumbnail 101 $(this.options.scrollContainer).css('width', scrollWidth); 102 thumbContainerFirst.addClass('current'); 103 slideContainers.css({height: this.element.height(), width: slideOuterWidth}); 104 105 if (slideContainers.length > this.options.visibleThumbs) { 106 $('.flpr-thumb-list').css('width', thumbScrollWidth); 107 } 108 109 if (slideContainers.length > 1) { 110 if (this.options.showPrevNextLink) { 111 // add slide links 112 $('<a href="#" class="flpr-sld-link flpr-sld-link-prev">previous</a><a href="#" class="flpr-sld-link flpr-sld-link-next">next</a>').prependTo(this.element); 113 } 114 115 // add thumbnail links 116 var thumbWrapper = $('<div/>').addClass('flpr-thumb-wrapper'); 117 if (this.options.visibleThumbs < thumbContainers.length) { 118 thumbWrapper.append('<a href="#" class="flpr-thumb-link flpr-thumb-lnk-prev disabled">previous</a><a href="#" class="flpr-thumb-link flpr-thumb-lnk-next">next</a>'); 119 } 120 thumbWrapper.append(self.element.find('.flpr-thumb-list').parent('div')).appendTo(this.element); 121
122 // add data-slidenum and data-thumbnum 123 slideContainers.each(function() { 124 $(this).attr('data-slidenum', slideContainers.index(this)); 125 }); 126 thumbContainers.each(function() { 127 $(this).attr('data-thumbnum', thumbContainers.index(this)); 128 }); 129 130 } 131 132 if (this.options.hideThumbList) { 133 this.element.append($('<div/>').addClass('flpr-thumb-drawer').append('<div class="flpr-thumb-handle open"><span></span></div>').append(this.element.find('.flpr-thumb-wrapper'))); 134 } 135 }, 136 _addEvents: function() { 137 var self = this; 138 // click on slide arrows 139 this.element.find('.flpr-sld-link').live('click', function(e) { 140 e.preventDefault(); 141 self._slideArrowClicked($(this)); 142 }); 143 144 // click on thumb arrows 145 this.element.find('.flpr-thumb-link').live('click', function(e) { 146 e.preventDefault(); 147 self._arrowClicked($(this)); 148 }); 149 150 // click on thumbnails 151 this.element.find('.flpr-thumb-list li').live('click', function(e) { 152 e.preventDefault(); 153 self._thumbClicked($(this)); 154 }); 155 156 if (this.options.hideThumbList) { 157 // click to show arrows and thumb list 158 this.element.find('.flpr-thumb-handle').live('click', function() { 159 self._toggleDrawer($(this)); 160 }); 161 162 // hover to show arrows and thumb list 163 this.element.find('.flpr-thumb-drawer').hover(function() { 164 self._hoverToggleDrawer(); 165 },function() { 166 self._hoverToggleDrawer(); 167 }); 168 } 169 }, 170 _slideArrowClicked: function($this) { 171 if (this._slideAnimating) { 172 return false; 173 } 174 this._slideAnimating = true; 175 var direction = ($this.hasClass('flpr-sld-link-prev') ? 'prev' : 'next'); 176 this.flipSlide(this,direction); 177 }, 178 _arrowClicked: function($this) { 179 var direction = ($this.hasClass('flpr-thumb-lnk-prev') ? 'prev' : 'next'); 180 this._hideDrawerId = null; 181 this._scrollThumbs(this, direction); 182 }, 183 _thumbClicked: function($this) { 184 if (this._slideAnimating || $this.hasClass('current')) { 185 return false; 186 } 187 window.clearInterval(this._flipIntervalId); 188 if (this.options.autoFlipInterval) { 189 this.autoFlip(); 190 } 191 this._slideAnimating = true; 192 var self = this, 193 indexToShow = $this.attr('data-thumbnum'), 194 scrollContainer = this.element.find(this.options.scrollContainer), 195 slideContainer = scrollContainer.find(this.options.slideContainer + '[data-slidenum=' + indexToShow + ']'), 196 slideOffset = slideContainer.offset(), 197 widgetOffset = this.element.offset(), 198 scrollAmount = slideOffset.left - widgetOffset.left, 199 currentIndex = this.element.find('.flpr-thumb-list').find('.current').attr('data-thumbnum'), 200 direction = (this.element.find('.flpr-thumb-list').find('li').eq(0).hasClass('current') || $this.prevAll('.current').length === 1) ? 'right' : 'left'; 201 this.element.find('.flpr-thumb-list').find('.current').removeClass('current'); 202 if (direction === 'right') { 203 scrollContainer.parent('div').animate({scrollLeft: scrollAmount}, this.options.flipSpeed, 'linear', function() { 204 slideContainer.nextAll(self.options.slideContainer).prependTo(scrollContainer); 205 slideContainer.prependTo(scrollContainer); 206 scrollContainer.parent('div').scrollLeft(0); 207 self._slideAnimating = false; 208 }); 209 } else { 210 scrollAmount = (currentIndex - indexToShow) * this._slideWidth; 211 for (var i=(currentIndex - 1); i>=indexToShow; i--) { 212 scrollContainer.prepend(scrollContainer.find('[data-slidenum=' + i + ']')); 213 } 214 scrollContainer.parent('div').scrollLeft(scrollAmount); 215 scrollContainer.parent('div').animate({scrollLeft: 0}, this.options.flipSpeed, 'linear', function() { 216 self._slideAnimating = false; 217 }); 218 } 219 $this.addClass('current'); 220 }, 221 _hoverToggleDrawer: function() { 222 if (this.element.find('.flpr-thumb-wrapper').filter(':animated').length === 0) { 223 if (event.type === 'mouseover') { 224 this._showDrawer(); 225 } else { 226 this._hideDrawer(); 227 } 228 } 229 }, 230 _toggleDrawer: function($this) { 231 if (this.element.find('.flpr-thumb-wrapper').filter(':animated').length === 0) { 232 if (!$this.hasClass('open')) { 233 this._showDrawer(); 234 } else { 235 this._hideDrawer(); 236 } 237 } 238 }, 239 _autoHideDrawer: function() { 240 if (this._hideDrawerId !== null) { 241 this.element.find('.flpr-thumb-handle').click(); 242 } 243 }, 244 _showDrawer: function() { 245 this._hideDrawerId = null; 246 this.element.find('.flpr-thumb-wrapper').stop().slideDown('fast'); 247 this.element.find('.flpr-thumb-list').parent('div').scrollLeft(this._currentThumbPage * this._thumbWidth * this.options.visibleThumbs); 248 this.element.find('.flpr-thumb-handle').addClass('open'); 249 }, 250 _hideDrawer: function() { 251 this._hideDrawerId = null; 252 this.element.find('.flpr-thumb-wrapper').stop().slideUp('fast'); 253 this.element.find('.flpr-thumb-handle').removeClass('open'); 254 }, 255 flipSlide: function(self, direction) { 256 var indexToShow, 257 currentThumb = self.element.find('.flpr-thumb-list').find('.current'), 258 currentIndex = parseInt(currentThumb.attr('data-thumbnum'), 10), 259 totalThumbs = self.element.find('.flpr-thumb-list').find('li').length; 260 currentThumb.removeClass('current'); 261 262 if (arguments[2] === undefined) { 263 window.clearInterval(self._flipIntervalId); 264 if (this.options.autoFlipInterval) { 265 self.autoFlip(); 266 } 267 } 268 269 if (direction === 'prev') { 270 indexToShow = (currentIndex <= 0) ? (totalThumbs - 1) : (currentIndex - 1); 271 self._prependLastToFirst(self.options.scrollContainer, self.options.slideContainer, self._slideWidth);
272 self.element.find(self.options.scrollContainer).parent('div').animate({scrollLeft: 0}, self.options.flipSpeed, 'linear', function() { 273 self._slideAnimating = false; 274 }); 275 if (indexToShow + 1 >= totalThumbs) { 276 self.element.find('.flpr-thumb-list').parent('div').animate({scrollLeft: (totalThumbs * self._thumbWidth)}, 400, 'swing'); 277 self._currentThumbPage = (Math.ceil(totalThumbs / self.options.visibleThumbs) - 1); 278 self.element.find('.flpr-thumb-lnk-next').addClass('disabled'); 279 self.element.find('.flpr-thumb-lnk-prev').removeClass('disabled'); 280 } else if ((Math.ceil((indexToShow + 1) / self.options.visibleThumbs) - 1) < self._currentThumbPage) { 281 self._scrollThumbs(self,'prev'); 282 self._currentThumbPage = self._currentThumbPage - 1; 283 } 284 } else { 285 indexToShow = (currentIndex + 1 >= totalThumbs) ? 0 : (currentIndex + 1); 286 self.element.find(self.options.scrollContainer).parent('div').animate({scrollLeft: self._slideWidth }, self.options.flipSpeed, 'linear', function() { 287 self._appendFirstToLast(self.options.scrollContainer, self.options.slideContainer, 0); 288 self._slideAnimating = false; 289 }); 290 if (indexToShow === 0) { 291 self.element.find('.flpr-thumb-list').parent('div').animate({scrollLeft: 0}, self.options.flipSpeed, 'swing'); 292 self._currentThumbPage = 0; 293 self.element.find('.flpr-thumb-lnk-prev').addClass('disabled'); 294 self.element.find('.flpr-thumb-lnk-next').removeClass('disabled'); 295 } else if ((Math.ceil((indexToShow + 1) / self.options.visibleThumbs) - 1) > self._currentThumbPage) { 296 self._scrollThumbs(self,'next'); 297 } 298 } 299 self.element.find('.flpr-thumb-list').find('[data-thumbnum=' + indexToShow + ']').addClass('current'); 300 }, 301 _appendFirstToLast: function(scrollContainer, slideContainer, scrollAmount) { 302 $(scrollContainer).find(slideContainer).eq(0).appendTo(scrollContainer); 303 $(scrollContainer).parent('div').scrollLeft(scrollAmount); 304 }, 305 _prependLastToFirst: function(scrollContainer, slideContainer, scrollAmount) { 306 $(scrollContainer).find(slideContainer).eq($(scrollContainer).find(slideContainer).length - 1).prependTo(scrollContainer); 307 $(scrollContainer).parent('div').scrollLeft(scrollAmount); 308 }, 309 _scrollThumbs: function(self, direction) { 310 var scrollAmount, 311 thumbScrollContainer = self.element.find('.flpr-thumb-list'), 312 numberOfThumbs = thumbScrollContainer.find('li').length; 313 if (direction === 'prev') { 314 if (self._currentThumbPage === 0) { 315 return false; 316 } 317 self._currentThumbPage = self._currentThumbPage - 1; 318 } else { 319 if (self._currentThumbPage + 1 >= Math.ceil(numberOfThumbs / self.options.visibleThumbs)) { 320 return false; 321 } 322 self._currentThumbPage = self._currentThumbPage + 1; 323 } 324 scrollAmount = self._currentThumbPage * self._thumbWidth * self.options.visibleThumbs; 325 self.element.find('.flpr-thumb-list').parent('div').animate({scrollLeft: scrollAmount}, self.options.flipSpeed, 'swing', function() { 326 self._currentThumbOffset = scrollAmount; 327 }); 328 329 if (self._currentThumbPage === 0) { 330 self.element.find('.flpr-thumb-lnk-prev').addClass('disabled'); 331 } else { 332 self.element.find('.flpr-thumb-lnk-prev').removeClass('disabled'); 333 } 334 335 if (self._currentThumbPage + 1 >= Math.ceil(numberOfThumbs / self.options.visibleThumbs)) { 336 self.element.find('.flpr-thumb-lnk-next').addClass('disabled'); 337 } else { 338 self.element.find('.flpr-thumb-lnk-next').removeClass('disabled'); 339 } 340 }, 341 _textOverflow: function(textNode, maxLength) { 342 var textString = textNode.find('span').text(); 343 if (textString.length > maxLength) { 344 textNode.find('span').text(textString.substr(0,(maxLength - 3)) + '...'); 345 } 346 }, 347 autoFlip: function() { 348 var self = this; 349 this._flipIntervalId = window.setInterval(function() { 350 self.element.flipper('flipSlide', self, 'next', true); 351 }, this.options.autoFlipInterval); 352 } 353 }); 354})(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.