1/** 2 * Carousello 3 * 4 * @version 1.0 5 * 6 * Copyright 2013, UpSolution 7 */ 8 9(function($) { 10 "use strict"; 11 12 var Carousello = function(container, options) 13 { 14 // Context 15 var that = this; 16 this.container = $(container); 17 // Apply options 18 options = $.extend({}, $.fn.carousello.defaults, typeof options === 'object' && options); 19 this.options = options; 20 // Grab the actual widget name (as carousello can be applied to different widgets) 21 this.widgetName = this.container.attr('class').split(' ')[0]; 22 // Grab dom elements 23 this.btnPrev = this.container.find('.'+this.widgetName+'-nav.to_prev'); 24 this.btnNext = this.container.find('.'+this.widgetName+'-nav.to_next'); 25 this.list = this.container.find('.'+this.widgetName+'-list'); 26 this.listH = this.container.find('.'+this.widgetName+'-list-h'); 27 this.items = this.container.find('.'+this.widgetName+'-item'); 28 // Count dimensions 29 this.count = this.items.length; 30 this.itemWidth = $(this.items).outerWidth(); 31 this.itemOffset = parseInt($(this.items).css('margin-right'), 10); 32 // 3D Effect 33 if (this.options.use3d){ 34 this.cssPrefix = this._get3DPrefix(); 35 if (this.cssPrefix === false) { 36 this.options.use3d = false; 37 } 38 } 39 // Current position 40 this.position = 0; 41 // Events 42 this.btnPrev.click(function(){ that.slidePrev(); }); 43 this.btnNext.click(function(){ that.slideNext(); }); 44 // Make responsive 45 $(window).resize(function(){ 46 clearTimeout(that._resizeTimer); 47 that._resizeTimer = setTimeout(function(){that.handleResize();}, that.options.resizeDelay); 48 }); 49 if (this.options.use3d){ 50 // Requires imagesloaded plugin 51 // http://github.com/desandro/imagesloaded 52 this.container.imagesLoaded(function(){ 53 that.list.height(that.items.outerHeight()); 54 that.handleResize(); 55 }); 56 }else{ 57 this.handleResize(); 58 } 59 }; 60 61 Carousello.prototype = { 62 63 autoScroll: false, 64 65 autoScrollHandler: function(){ 66 var newPosition = Math.min(this.count - this.perRow, this.position + this.perRow); 67 if (newPosition <= this.position) { 68 this.slideTo(0); 69 } else { 70 this.slideTo(newPosition); 71 } 72 }, 73 74 /** 75 * Obtain browser css3 prefix or false if 3d transforms are not supported 76 * Based on modernizer 77 * @link http://modernizr.com 78 * @private 79 * @return {String} Prefix or false 80 */ 81 _get3DPrefix: function() { 82 var div = document.createElement('div'), 83 ret = false, 84 properties = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective'], 85 prefixes = ['', '-o-', '-moz-', '-webkit-']; 86 for (var i = properties.length - 1; i >= 0; i--) { 87 ret = ret ? ret : div.style[properties[i]] !== undefined; 88 } 89 if (ret){ 90 var st = document.createElement('style'); 91 // webkit allows this media query to succeed only if the feature is enabled. 92 // "@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){#modernizr{height:3px}}" 93 document.getElementsByTagName('head')[0].appendChild(st); 94 div.id = 'test3d'; 95 document.body.appendChild(div); 96 for (var j = 0; j < prefixes.length; j++){ 97 st.textContent = '@media ('+prefixes[j]+'transform-3d){#test3d{height:3px}}'; 98 if (div.offsetHeight === 3){ 99 ret = prefixes[j]; 100 break; 101 } 102 } 103 st.parentNode.removeChild(st); 104 div.parentNode.removeChild(div); 105 } 106 if (ret === true) { 107 if (div.style.MozPerspective !== undefined) { 108 ret = '-moz-'; 109 } else 110 if (div.style.WebkitPerspective !== undefined) { 111 ret = '-webkit-'; 112 } else { 113 ret = ''; 114 } 115 } 116 return ret; 117 }, 118 119 slidePrev: function() 120 { 121 var newPosition = Math.max(0, this.position - this.perRow), 122 that = this; 123 this.slideTo(newPosition); 124 if (this.options.autoScroll) { 125 if (this.autoScroll !== false) { 126 window.clearTimeout(this.autoScroll); 127 } 128 this.autoScroll = window.setInterval(function(){ 129 that.autoScrollHandler(); 130 }, this.options.interval); 131 } 132 }, 133 134 slideNext: function() 135 { 136 var newPosition = Math.min(this.count - this.perRow, this.position + this.perRow), 137 that = this; 138 if (this.options.use3d) { 139 newPosition = this.position + this.perRow; 140 } 141 this.slideTo(newPosition); 142 if (this.options.autoScroll) { 143 if (this.autoScroll !== false) { 144 window.clearTimeout(this.autoScroll); 145 } 146 this.autoScroll = window.setInterval(function(){ 147 that.autoScrollHandler(); 148 }, this.options.interval); 149 } 150 }, 151 152 slideTo: function(position) 153 { 154 if (position === this.position) { 155 return; 156 } 157 if (this.options.use3d){ 158 // 3D transition 159 var showGroup = Math.min(Math.floor(position / this.perRow), this.groups.length-1), 160 that = this; 161 position = showGroup * this.perRow; 162 this.listH.animate({ 163 angle: -1 * this.baseAngle * showGroup 164 }, { 165 duration: this.options.duration, 166 easing: this.options.easing, 167 step: function(angle){ 168 angle = parseInt(angle * 100, 10) / 100; 169 that.listH.css(that.cssPrefix+'transform', 'translateZ(-'+that.translateZ+'px) rotateY('+angle+'deg)'); 170 }, 171 queue: false 172 }); 173 }else{ 174 // 2D transition 175 this.listH.animate({ 176 left: -1*position*(this.itemWidth+this.itemOffset) 177 }, { 178 duration: this.options.duration, 179 easing: this.options.easing, 180 queue: false 181 }); 182 } 183 this.btnPrev[(position === 0)?'addClass':'removeClass']('disabled'); 184 this.btnNext[(position >= (this.count - this.perRow))?'addClass':'removeClass']('disabled'); 185 this.position = position; 186 }, 187 188 handleResize: function() 189 { 190 var containerWidth = this.container.width(), 191 oldPerRow = this.perRow, 192 that = this; 193 this.perRow = Math.max(1, Math.floor((containerWidth + this.itemOffset) / (this.itemWidth + this.itemOffset))); 194 var listWidth = this.perRow * (this.itemWidth + this.itemOffset) - this.itemOffset; 195 this.list.width(listWidth);
196 if (this.options.use3d && (oldPerRow === undefined || this.perRow !== oldPerRow)){ 197 // Separate items into groups for 3d effect 198 this.listH.append(this.items); 199 this.listH.children('.'+this.widgetName+'-itemgroup').remove(); 200 for (var i = 0, l = Math.ceil(this.count / this.perRow); i < l; i++){ 201 var group = $('<div/>', {'class': this.widgetName+'-itemgroup'}).appendTo(this.listH); 202 for (var j = 0; j < this.perRow; j++){ 203 if (this.items[i*this.perRow + j] === undefined) { 204 break; 205 } 206 group.append(this.items[i*this.perRow + j]); 207 } 208 } 209 this.groups = this.container.find('.'+this.widgetName+'-itemgroup'); 210 this.baseAngle = Math.min(120, 360 / this.groups.length); 211 this.translateZ = Math.round( 0.5 * listWidth / Math.tan(Math.PI / Math.max(3, this.groups.length))); 212 this.list 213 .css({position: 'relative', 'overflow': (this.groups.length < 5) ? 'visible' : 'hidden'}) 214 .css(this.cssPrefix+'perspective', '800px'); 215 this.listH 216 .css({position: 'absolute', height: '100%', width: '100%'}) 217 .css(this.cssPrefix+'transform', 'rotateY(0deg) translateZ(-'+this.translateZ+'px)') 218 .css(this.cssPrefix+'transform-style', 'preserve-3d') 219 .css(this.cssPrefix+'perspective-origin', '50% 100px'); 220 this.list.height(this.items.outerHeight()); 221 this.groups.css({position: 'absolute', left: 0, width: '100%', height: '100%'}); 222 $.each(this.groups, function(k, group){ 223 $(group).css(that.cssPrefix+'transform', 'rotateY('+(that.baseAngle*k)+'deg) translateZ('+that.translateZ+'px)'); 224 }); 225 } 226 if (oldPerRow !== undefined && this.perRow !== oldPerRow){ 227 if (this.position > this.count - this.perRow) { 228 this.slideTo(this.count - this.perRow); 229 } 230 this.btnNext[(this.position >= (this.count - this.perRow))?'addClass':'removeClass']('disabled'); 231 } 232 // Hide arrows if there are too few items 233 if (this.perRow >= this.count) { 234 this.btnPrev.hide(); 235 this.btnNext.hide(); 236 } else { 237 this.btnPrev.show(); 238 this.btnNext.show(); 239 } 240 241 if (this.options.autoScroll) { 242 if (this.autoScroll !== false) { 243 window.clearTimeout(this.autoScroll); 244 } 245 this.autoScroll = window.setInterval(function(){ 246 that.autoScrollHandler(); 247 }, this.options.interval); 248 } 249 250 251 } 252 253 }; 254 255 /** 256 * Easings 257 * Original functions by George McGinley Smith 258 * @link http://gsgd.co.uk/sandbox/jquery/easing/ 259 */ 260 if ($.easing.easeOutBack === undefined) { 261 $.easing.easeOutBack = function (x, t, b, c, d, s){ 262 if (s === undefined) { 263 s = 1.70158; 264 } 265 return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; 266 }; 267 } 268 if ($.easing.easeInOutExpo === undefined) { 269 $.easing.easeInOutExpo = function(e, t, n, r, i){ 270 if (t === 0) { 271 return n; 272 } 273 if (t === i) { 274 return n+r; 275 } 276 if ((t /= i/2) < 1) { 277 return r/2*Math.pow(2,10*(t-1))+n; 278 } 279 return r/2*(-Math.pow(2,-10*--t) + 2) + n; 280 }; 281 } 282 283 $.fn.carousello = function(options){ 284 return this.each(function(){ 285 var $this = $(this), 286 data = $this.data('carousello'); 287 if ( ! data) { 288 $this.data('carousello', (data = new Carousello(this, options))); 289 } 290 }); 291 }; 292 293 $.fn.carousello.defaults = { 294 295 /** 296 * @var {Boolean} Try to use 3D if possible 297 */ 298 use3d: true, 299 300 /** 301 * @var {Number} Animation duration 302 */ 303 duration: 500, 304 305 /** 306 * @var {Function} Default animation easing 307 */ 308 easing: 'easeInOutExpo', 309 310 /** 311 * @var {Number} Resize delay to reduce resize event calls 312 */ 313 resizeDelay: 50, 314 315 /** 316 * @var {Boolean} AutoScroll the carousel 317 */ 318 autoScroll: true, 319 320 /** 321 * @var {Number} Interval between scroll when autoScroll is enabled 322 */ 323 interval: 2000 324 }; 325 326 $.fn.carousello.Constructor = Carousello; 327 328 329})(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.