vendor: 6,366 bytes, lines 1-177
1/* Modernizr 2.6.2 (Custom Build) | MIT & BSD 2 * Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes 3 */ 4;window.Modernizr = function(a, b, c) { 5 function z(a) { 6 j.cssText = a 7 } 8 function A(a, b) { 9 return z(m.join(a + ";") + (b || "")) 10 } 11 function B(a, b) { 12 return typeof a === b 13 } 14 function C(a, b) { 15 return !!~("" + a).indexOf(b) 16 } 17 function D(a, b) { 18 for (var d in a) { 19 var e = a[d]; 20 if (!C(e, "-") && j[e] !== c) 21 return b == "pfx" ? e : !0 22 } 23 return !1 24 } 25 function E(a, b, d) { 26 for (var e in a) { 27 var f = b[a[e]]; 28 if (f !== c) 29 return d === !1 ? a[e] : B(f, "function") ? f.bind(d || b) : f 30 } 31 return !1 32 } 33 function F(a, b, c) { 34 var d = a.charAt(0).toUpperCase() + a.slice(1) 35 , e = (a + " " + o.join(d + " ") + d).split(" "); 36 return B(b, "string") || B(b, "undefined") ? D(e, b) : (e = (a + " " + p.join(d + " ") + d).split(" "), 37 E(e, b, c)) 38 } 39 var d = "2.6.2", e = {}, f = !0, g = b.documentElement, h = "modernizr", i = b.createElement(h), j = i.style, k, l = {}.toString, m = " -webkit- -moz- -o- -ms- ".split(" "), n = "Webkit Moz O ms", o = n.split(" "), p = n.toLowerCase().split(" "), q = {}, r = {}, s = {}, t = [], u = t.slice, v, w = function(a, c, d, e) { 40 var f, i, j, k, l = b.createElement("div"), m = b.body, n = m || b.createElement("body"); 41 if (parseInt(d, 10)) 42 while (d--) 43 j = b.createElement("div"), 44 j.id = e ? e[d] : h + (d + 1), 45 l.appendChild(j); 46 return f = ["­", '<style id="s', h, '">', a, "</style>"].join(""), 47 l.id = h, 48 (m ? l : n).innerHTML += f, 49 n.appendChild(l), 50 m || (n.style.background = "", 51 n.style.overflow = "hidden", 52 k = g.style.overflow, 53 g.style.overflow = "hidden", 54 g.appendChild(n)), 55 i = c(l, a), 56 m ? l.parentNode.removeChild(l) : (n.parentNode.removeChild(n), 57 g.style.overflow = k), 58 !!i 59 }, x = {}.hasOwnProperty, y; 60 !B(x, "undefined") && !B(x.call, "undefined") ? y = function(a, b) { 61 return x.call(a, b) 62 } 63 : y = function(a, b) { 64 return b in a && B(a.constructor.prototype[b], "undefined") 65 } 66 , 67 Function.prototype.bind || (Function.prototype.bind = function(b) { 68 var c = this; 69 if (typeof c != "function") 70 throw new TypeError; 71 var d = u.call(arguments, 1) 72 , e = function() { 73 if (this instanceof e) { 74 var a = function() {}; 75 a.prototype = c.prototype; 76 var f = new a 77 , g = c.apply(f, d.concat(u.call(arguments))); 78 return Object(g) === g ? g : f 79 } 80 return c.apply(b, d.concat(u.call(arguments))) 81 }; 82 return e 83 } 84 ), 85 q.csstransforms = function() { 86 return !!F("transform") 87 } 88 , 89 q.csstransforms3d = function() { 90 var a = !!F("perspective"); 91 return a && "webkitPerspective"in g.style && w("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}", function(b, c) { 92 a = b.offsetLeft === 9 && b.offsetHeight === 3 93 }), 94 a 95 } 96 ; 97 for (var G in q) 98 y(q, G) && (v = G.toLowerCase(), 99 e[v] = q[G](), 100 t.push((e[v] ? "" : "no-") + v)); 101 return e.addTest = function(a, b) { 102 if (typeof a == "object") 103 for (var d in a) 104 y(a, d) && e.addTest(d, a[d]); 105 else { 106 a = a.toLowerCase(); 107 if (e[a] !== c) 108 return e; 109 b = typeof b == "function" ? b() : b, 110 typeof f != "undefined" && f && (g.className += " " + (b ? "" : "no-") + a), 111 e[a] = b 112 } 113 return e 114 } 115 , 116 z(""), 117 i = k = null, 118 function(a, b) { 119 function k(a, b) { 120 var c = a.createElement("p") 121 , d = a.getElementsByTagName("head")[0] || a.documentElement; 122 return c.innerHTML = "x<style>" + b + "</style>", 123 d.insertBefore(c.lastChild, d.firstChild) 124 } 125 function l() { 126 var a = r.elements; 127 return typeof a == "string" ? a.split(" ") : a 128 } 129 function m(a) { 130 var b = i[a[g]]; 131 return b || (b = {}, 132 h++, 133 a[g] = h, 134 i[h] = b), 135 b 136 } 137 function n(a, c, f) { 138 c || (c = b); 139 if (j) 140 return c.createElement(a); 141 f || (f = m(c)); 142 var g; 143 return f.cache[a] ? g = f.cache[a].cloneNode() : e.test(a) ? g = (f.cache[a] = f.createElem(a)).cloneNode() : g = f.createElem(a), 144 g.canHaveChildren && !d.test(a) ? f.frag.appendChild(g) : g 145 } 146 function o(a, c) { 147 a || (a = b); 148 if (j) 149 return a.createDocumentFragment(); 150 c = c || m(a); 151 var d = c.frag.cloneNode() 152 , e = 0 153 , f = l() 154 , g = f.length; 155 for (; e < g; e++) 156 d.createElement(f[e]); 157 return d 158 } 159 function p(a, b) { 160 b.cache || (b.cache = {}, 161 b.createElem = a.createElement, 162 b.createFrag = a.createDocumentFragment, 163 b.frag = b.createFrag()), 164 a.createElement = function(c) { 165 return r.shivMethods ? n(c, a, b) : b.createElem(c) 166 } 167 , 168 a.createDocumentFragment = Function("h,f", "return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&(" + l().join().replace(/\w+/g, function(a) { 169 return b.createElem(a), 170 b.frag.createElement(a), 171 'c("' + a + '")' 172 }) + ");return n}")(r, b.frag) 173 } 174 function q(a) { 175 a || (a = b); 176 var c = m(a); 177 return r.shivCSS && !f && !c.hasCSS && (c.hasCSS = !!k(a, "article,aside,figcaption,figure,footer,header,hgroup,nav,section{dis
177play:block}mark{background:#FF0;color:#000}")), 178 j || p(a, c), 179 a 180 } 181 var c = a.html5 || {}, d = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i, e = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i, f, g = "_html5shiv", h = 0, i = {}, j; 182 (function() { 183 try { 184 var a = b.createElement("a"); 185 a.innerHTML = "<xyz></xyz>", 186 f = "hidden"in a, 187 j = a.childNodes.length == 1 || function() { 188 b.createElement("a"); 189 var a = b.createDocumentFragment(); 190 return typeof a.cloneNode == "undefined" || typeof a.createDocumentFragment == "undefined" || typeof a.createElement == "undefined" 191 }() 192 } catch (c) { 193 f = !0, 194 j = !0 195 } 196 } 197 )(); 198 var r = { 199 elements: c.elements || "abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video", 200 shivCSS: c.shivCSS !== !1, 201 supportsUnknownElements: j, 202 shivMethods: c.shivMethods !== !1, 203 type: "default", 204 shivDocument: q, 205 createElement: n, 206 createDocumentFragment: o 207 }; 208 a.html5 = r, 209 q(b) 210 }(this, b), 211 e._version = d, 212 e._prefixes = m, 213 e._domPrefixes = p, 214 e._cssomPrefixes = o, 215 e.testProp = function(a) { 216 return D([a]) 217 } 218 , 219 e.testAllProps = F, 220 e.testStyles = w, 221 e.prefixed = function(a, b, c) { 222 return b ? F(a, b, c) : F(a, "pfx") 223 } 224 , 225 g.className = g.className.replace(/(^|\s)no-js(\s|$)/, "$1$2") + (f ? " js " + t.join(" ") : ""), 226 e 227}(this, this.document); 228 229// Add test for transform-style: preserve-3d; 230Modernizr.addTest('preserve3d', Modernizr.testAllProps('transformStyle', 'preserve-3d')); 231 232 233// =================next js file ================== // 234// Avoid `console` errors in browsers that lack a console. 235(function(){for(var a,e=function(){},b="assert clear count debug dir dirxml error exception group groupCollapsed groupEnd info log markTimeline profile profileEnd table time timeEnd timeStamp trace warn".split(" "),c=b.length,d=window.console=window.console||{};c--;)a=b[c],d[a]||(d[a]=e)})(); 236 237// LoremImages 238(function(b){b.fn.loremImages=function(e,d,j){var a=b.extend({},b.fn.loremImages.defaults,j);return this.each(function(c,k){var f=b(k),g="";for(c=0;c<a.count;c++){var h=e+Math.round(Math.random()*a.randomWidth),i=d+Math.round(Math.random()*a.randomHeight);g+=a.itemBuilder.call(f,c,"//lorempixel.com/"+(a.grey?"g/":"")+h+"/"+i+"/"+(a.category?a.category+"/":"")+"?"+Math.round(Math.random()*1E3),h,i)}f.append(g)})};b.fn.loremImages.defaults={count:10,grey:0,randomWidth:0,randomHeight:0,category:0,itemBuilder:function(e, 239d){return'<img src="'+d+'" alt="Lorempixel">'}}})(jQuery); 240 241// jQuery easing 1.3 242jQuery.easing.jswing=jQuery.easing.swing; 243jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,a,c,b,d){return jQuery.easing[jQuery.easing.def](e,a,c,b,d)},easeInQuad:function(e,a,c,b,d){return b*(a/=d)*a+c},easeOutQuad:function(e,a,c,b,d){return-b*(a/=d)*(a-2)+c},easeInOutQuad:function(e,a,c,b,d){return 1>(a/=d/2)?b/2*a*a+c:-b/2*(--a*(a-2)-1)+c},easeInCubic:function(e,a,c,b,d){return b*(a/=d)*a*a+c},easeOutCubic:function(e,a,c,b,d){return b*((a=a/d-1)*a*a+1)+c},easeInOutCubic:function(e,a,c,b,d){return 1>(a/=d/2)?b/2*a*a*a+c: 244b/2*((a-=2)*a*a+2)+c},easeInQuart:function(e,a,c,b,d){return b*(a/=d)*a*a*a+c},easeOutQuart:function(e,a,c,b,d){return-b*((a=a/d-1)*a*a*a-1)+c},easeInOutQuart:function(e,a,c,b,d){return 1>(a/=d/2)?b/2*a*a*a*a+c:-b/2*((a-=2)*a*a*a-2)+c},easeInQuint:function(e,a,c,b,d){return b*(a/=d)*a*a*a*a+c},easeOutQuint:function(e,a,c,b,d){return b*((a=a/d-1)*a*a*a*a+1)+c},easeInOutQuint:function(e,a,c,b,d){return 1>(a/=d/2)?b/2*a*a*a*a*a+c:b/2*((a-=2)*a*a*a*a+2)+c},easeInSine:function(e,a,c,b,d){return-b*Math.cos(a/ 245d*(Math.PI/2))+b+c},easeOutSine:function(e,a,c,b,d){return b*Math.sin(a/d*(Math.PI/2))+c},easeInOutSine:function(e,a,c,b,d){return-b/2*(Math.cos(Math.PI*a/d)-1)+c},easeInExpo:function(e,a,c,b,d){return 0==a?c:b*Math.pow(2,10*(a/d-1))+c},easeOutExpo:function(e,a,c,b,d){return a==d?c+b:b*(-Math.pow(2,-10*a/d)+1)+c},easeInOutExpo:function(e,a,c,b,d){return 0==a?c:a==d?c+b:1>(a/=d/2)?b/2*Math.pow(2,10*(a-1))+c:b/2*(-Math.pow(2,-10*--a)+2)+c},easeInCirc:function(e,a,c,b,d){return-b*(Math.sqrt(1-(a/=d)* 246a)-1)+c},easeOutCirc:function(e,a,c,b,d){return b*Math.sqrt(1-(a=a/d-1)*a)+c},easeInOutCirc:function(e,a,c,b,d){return 1>(a/=d/2)?-b/2*(Math.sqrt(1-a*a)-1)+c:b/2*(Math.sqrt(1-(a-=2)*a)+1)+c},easeInElastic:function(e,a,c,b,d){var e=1.70158,f=0,g=b;if(0==a)return c;if(1==(a/=d))return c+b;f||(f=0.3*d);g<Math.abs(b)?(g=b,e=f/4):e=f/(2*Math.PI)*Math.asin(b/g);return-(g*Math.pow(2,10*(a-=1))*Math.sin((a*d-e)*2*Math.PI/f))+c},easeOutElastic:function(e,a,c,b,d){var e=1.70158,f=0,g=b;if(0==a)return c;if(1== 247(a/=d))return c+b;f||(f=0.3*d);g<Math.abs(b)?(g=b,e=f/4):e=f/(2*Math.PI)*Math.asin(b/g);return g*Math.pow(2,-10*a)*Math.sin((a*d-e)*2*Math.PI/f)+b+c},easeInOutElastic:function(e,a,c,b,d){var e=1.70158,f=0,g=b;if(0==a)return c;if(2==(a/=d/2))return c+b;f||(f=d*0.3*1.5);g<Math.abs(b)?(g=b,e=f/4):e=f/(2*Math.PI)*Math.asin(b/g);return 1>a?-0.5*g*Math.pow(2,10*(a-=1))*Math.sin((a*d-e)*2*Math.PI/f)+c:0.5*g*Math.pow(2,-10*(a-=1))*Math.sin((a*d-e)*2*Math.PI/f)+b+c},easeInBack:function(e,a,c,b,d,f){void 0== 248f&&(f=1.70158);return b*(a/=d)*a*((f+1)*a-f)+c}
248,easeOutBack:function(e,a,c,b,d,f){void 0==f&&(f=1.70158);return b*((a=a/d-1)*a*((f+1)*a+f)+1)+c},easeInOutBack:function(e,a,c,b,d,f){void 0==f&&(f=1.70158);return 1>(a/=d/2)?b/2*a*a*(((f*=1.525)+1)*a-f)+c:b/2*((a-=2)*a*(((f*=1.525)+1)*a+f)+2)+c},easeInBounce:function(e,a,c,b,d){return b-jQuery.easing.easeOutBounce(e,d-a,0,b,d)+c},easeOutBounce:function(e,a,c,b,d){return(a/=d)<1/2.75?b*7.5625*a*a+c:a<2/2.75?b*(7.5625*(a-=1.5/2.75)*a+0.75)+c:a<2.5/2.75? 249b*(7.5625*(a-=2.25/2.75)*a+0.9375)+c:b*(7.5625*(a-=2.625/2.75)*a+0.984375)+c},easeInOutBounce:function(e,a,c,b,d){return a<d/2?0.5*jQuery.easing.easeInBounce(e,2*a,0,b,d)+c:0.5*jQuery.easing.easeOutBounce(e,2*a-d,0,b,d)+0.5*b+c}}); 250 251// jQuery throttle / debounce - v1.1 - 3/7/2010 252(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); 253 254// =================== next sly.js file ================= // 255/*! 256 * sly 1.6.1 - 8th Aug 2015 257 * https://github.com/darsain/sly 258 * 259 * Licensed under the MIT license. 260 * http://opensource.org/licenses/MIT 261 */ 262 263;(function ($, w, undefined) { 264 'use strict'; 265 266 var pluginName = 'sly'; 267 var className = 'Sly'; 268 var namespace = pluginName; 269 270 // Local WindowAnimationTiming interface 271 var cAF = w.cancelAnimationFrame || w.cancelRequestAnimationFrame; 272 var rAF = w.requestAnimationFrame; 273 274 // Support indicators 275 var transform, gpuAcceleration; 276 277 // Other global values 278 var $doc = $(document); 279 var dragInitEvents = 'touchstart.' + namespace + ' mousedown.' + namespace; 280 var dragMouseEvents = 'mousemove.' + namespace + ' mouseup.' + namespace; 281 var dragTouchEvents = 'touchmove.' + namespace + ' touchend.' + namespace; 282 var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel.' : 'mousewheel.') + namespace; 283 var clickEvent = 'click.' + namespace; 284 var mouseDownEvent = 'mousedown.' + namespace; 285 var interactiveElements = ['INPUT', 'SELECT', 'BUTTON', 'TEXTAREA']; 286 var tmpArray = []; 287 var time; 288 289 // Math shorthands 290 var abs = Math.abs; 291 var sqrt = Math.sqrt; 292 var pow = Math.pow; 293 var round = Math.round; 294 var max = Math.max; 295 var min = Math.min; 296 297 // Keep track of last fired global wheel event 298 var lastGlobalWheel = 0; 299 $doc.on(wheelEvent, function (event) { 300 var sly = event.originalEvent[namespace]; 301 var time = +new Date(); 302 // Update last global wheel time, but only when event didn't originate 303 // in Sly frame, or the origin was less than scrollHijack time ago 304 if (!sly || sly.options.scrollHijack < time - lastGlobalWheel) lastGlobalWheel = time; 305 }); 306 307 /** 308 * Sly. 309 * 310 * @class 311 * 312 * @param {Element} frame DOM element of sly container. 313 * @param {Object} options Object with options. 314 * @param {Object} callbackMap Callbacks map. 315 */ 316 function Sly(frame, options, callbackMap) { 317 if (!(this instanceof Sly)) return new Sly(frame, options, callbackMap); 318 319 // Extend options 320 var o = $.extend({}, Sly.defaults, options); 321 322 // Private variables 323 var self = this; 324 var parallax = isNumber(frame); 325 326 // Frame 327 var $frame = $(frame); 328 var $slidee = o.slidee ? $(o.slidee).eq(0) : $frame.children().eq(0); 329 var frameSize = 0; 330 var slideeSize = 0; 331 var pos = { 332 start: 0, 333 center: 0, 334 end: 0, 335 cur: 0, 336 dest: 0 337 }; 338 339 // Scrollbar 340 var $sb = $(o.scrollBar).eq(0); 341 var $handle = $sb.children().eq(0); 342 var sbSize = 0; 343 var handleSize = 0; 344 var hPos = { 345 start: 0, 346 end: 0, 347 cur: 0 348 }; 349 350 // Pagesbar 351 var $pb = $(o.pagesBar); 352 var $pages = 0; 353 var pages = []; 354 355 // Items 356 var $items = 0; 357 var items = []; 358 var rel = { 359 firstItem: 0, 360 lastItem: 0, 361 centerItem: 0, 362 activeItem: null, 363 activePage: 0 364 }; 365 366 // Styles 367 var frameStyles = new StyleRestorer($frame[0]); 368 var slideeStyles = new StyleRestorer($slidee[0]); 369 var sbStyles = new StyleRestorer($sb[0]); 370 var handleStyles = new StyleRestorer($handle[0]); 371 372 // Navigation type booleans 373 var basicNav = o.itemNav === 'basic'; 374 var forceCenteredNav = o.itemNav === 'forceCentered'; 375 var centeredNav = o.itemNav === 'centered' || forceCenteredNav; 376 var itemNav = !parallax && (basicNav || centeredNav || forceCenteredNav); 377 378 // Miscellaneous 379 var $scrollSource = o.scrollSource ? $(o.scrollSource) : $frame; 380 var $dragSource = o.dragSource ? $(o.dragSource) : $frame; 381 var $forwardButton = $(o.forward); 382 var $backwardButton = $(o.backward); 383 var $prevButton = $(o.prev); 384 var $nextButton = $(o.next); 385 var $prevPageButton = $(o.prevPage); 386 var $nextPageButton = $(o.nextPage); 387 var callbacks = {}; 388 var last = {}; 389 var animation = {}; 390 var move = {}; 391 var dragging = { 392 released: 1 393 }; 394 var scrolling = { 395 last: 0, 396 delta: 0, 397 resetTime: 200 398 }; 399 var renderID = 0; 400 var historyID = 0; 401 var cycleID = 0; 402 var continuousID = 0; 403 var i, l; 404 405 // Normalizing frame 406 if (!parallax) { 407 frame = $frame[0]; 408 } 409 410 // Expose properties 411 self.initialized = 0; 412 self.frame = frame; 413 self.slidee = $slidee[0]; 414 self.pos = pos; 415 self.rel = rel; 416 self.items = items; 417 self.pages = pages; 418 self.isPaused = 0; 419 self.options = o; 420 self.dragging = dragging; 421 422 /** 423 * Loading function. 424 * 425 * Populate arrays, set sizes, bind events, ... 426 * 427 * @param {Boolean} [isInit] Whether load is called from within self.init(). 428 * @return {Void} 429 */ 430 function load(isInit) { 431 // Local variables 432 var lastItemsCount = 0; 433 var lastPagesCount = pages.length; 434 435 // Save old position 436 pos.old = $.extend({}, pos); 437 438 // Reset global variables 439 frameSize = parallax ? 0 : $frame[o.horizontal ? 'width' : 'height'](); 440 sbSize = $sb[o.horizontal ? 'width' : 'height']();
441 slideeSize = parallax ? frame : $slidee[o.horizontal ? 'outerWidth' : 'outerHeight'](); 442 pages.length = 0; 443 444 // Set position limits & relatives 445 pos.start = 0; 446 pos.end = max(slideeSize - frameSize, 0); 447 448 // Sizes & offsets for item based navigations 449 if (itemNav) { 450 // Save the number of current items 451 lastItemsCount = items.length; 452 453 // Reset itemNav related variables 454 $items = $slidee.children(o.itemSelector); 455 items.length = 0; 456 457 // Needed variables 458 var paddingStart = getPx($slidee, o.horizontal ? 'paddingLeft' : 'paddingTop'); 459 var paddingEnd = getPx($slidee, o.horizontal ? 'paddingRight' : 'paddingBottom'); 460 var borderBox = $($items).css('boxSizing') === 'border-box'; 461 var areFloated = $items.css('float') !== 'none'; 462 var ignoredMargin = 0; 463 var lastItemIndex = $items.length - 1; 464 var lastItem; 465 466 // Reset slideeSize 467 slideeSize = 0; 468 469 // Iterate through items 470 $items.each(function (i, element) { 471 // Item 472 var $item = $(element); 473 var rect = element.getBoundingClientRect(); 474 var itemSize = round(o.horizontal ? rect.width || rect.right - rect.left : rect.height || rect.bottom - rect.top); 475 var itemMarginStart = getPx($item, o.horizontal ? 'marginLeft' : 'marginTop'); 476 var itemMarginEnd = getPx($item, o.horizontal ? 'marginRight' : 'marginBottom'); 477 var itemSizeFull = itemSize + itemMarginStart + itemMarginEnd; 478 var singleSpaced = !itemMarginStart || !itemMarginEnd; 479 var item = {}; 480 item.el = element; 481 item.size = singleSpaced ? itemSize : itemSizeFull; 482 item.half = item.size / 2; 483 item.start = slideeSize + (singleSpaced ? itemMarginStart : 0); 484 item.center = item.start - round(frameSize / 2 - item.size / 2); 485 item.end = item.start - frameSize + item.size; 486 487 // Account for slidee padding 488 if (!i) { 489 slideeSize += paddingStart; 490 } 491 492 // Increment slidee size for size of the active element 493 slideeSize += itemSizeFull; 494 495 // Try to account for vertical margin collapsing in vertical mode 496 // It's not bulletproof, but should work in 99% of cases 497 if (!o.horizontal && !areFloated) { 498 // Subtract smaller margin, but only when top margin is not 0, and this is not the first element 499 if (itemMarginEnd && itemMarginStart && i > 0) { 500 slideeSize -= min(itemMarginStart, itemMarginEnd); 501 } 502 } 503 504 // Things to be done on last item 505 if (i === lastItemIndex) { 506 item.end += paddingEnd; 507 slideeSize += paddingEnd; 508 ignoredMargin = singleSpaced ? itemMarginEnd : 0; 509 } 510 511 // Add item object to items array 512 items.push(item); 513 lastItem = item; 514 }); 515 516 // Resize SLIDEE to fit all items 517 $slidee[0].style[o.horizontal ? 'width' : 'height'] = (borderBox ? slideeSize: slideeSize - paddingStart - paddingEnd) + 'px'; 518 519 // Adjust internal SLIDEE size for last margin 520 slideeSize -= ignoredMargin; 521 522 // Set limits 523 if (items.length) { 524 pos.start = items[0][forceCenteredNav ? 'center' : 'start']; 525 pos.end = forceCenteredNav ? lastItem.center : frameSize < slideeSize ? lastItem.end : pos.start; 526 } else { 527 pos.start = pos.end = 0; 528 } 529 } 530 531 // Calculate SLIDEE center position 532 pos.center = round(pos.end / 2 + pos.start / 2); 533 534 // Update relative positions 535 updateRelatives(); 536 537 // Scrollbar 538 if ($handle.length && sbSize > 0) { 539 // Stretch scrollbar handle to represent the visible area 540 if (o.dynamicHandle) { 541 handleSize = pos.start === pos.end ? sbSize : round(sbSize * frameSize / slideeSize); 542 handleSize = within(handleSize, o.minHandleSize, sbSize); 543 $handle[0].style[o.horizontal ? 'width' : 'height'] = handleSize + 'px'; 544 } else { 545 handleSize = $handle[o.horizontal ? 'outerWidth' : 'outerHeight'](); 546 } 547 548 hPos.end = sbSize - handleSize; 549 550 if (!renderID) { 551 syncScrollbar(); 552 } 553 } 554 555 // Pages 556 if (!parallax && frameSize > 0) { 557 var tempPagePos = pos.start; 558 var pagesHtml = ''; 559 560 // Populate pages array 561 if (itemNav) { 562 $.each(items, function (i, item) { 563 if (forceCenteredNav) { 564 pages.push(item.center); 565 } else if (item.start + item.size > tempPagePos && tempPagePos <= pos.end) { 566 tempPagePos = item.start; 567 pages.push(tempPagePos); 568 tempPagePos += frameSize; 569 if (tempPagePos > pos.end && tempPagePos < pos.end + frameSize) { 570 pages.push(pos.end); 571 } 572 } 573 }); 574 } else { 575 while (tempPagePos - frameSize < pos.end) { 576 pages.push(tempPagePos); 577 tempPagePos += frameSize; 578 } 579 } 580 581 // Pages bar 582 if ($pb[0] && lastPagesCount !== pages.length) { 583 for (var i = 0; i < pages.length; i++) { 584 pagesHtml += o.pageBuilder.call(self, i); 585 } 586 $pages = $pb.html(pagesHtml).children(); 587 $pages.eq(rel.activePage).addClass(o.activeClass); 588 } 589 } 590 591 // Extend relative variables object with some useful info 592 rel.slideeSize = slideeSize; 593 rel.frameSize = frameSize; 594 rel.sbSize = sbSize; 595 rel.handleSize = handleSize; 596 597 // Activate requested position 598 if (itemNav) { 599 if (isInit && o.startAt != null) { 600 activate(o.startAt); 601 self[centeredNav ? 'toCenter' : 'toStart'](o.startAt); 602 } 603 // Fix possible overflowing 604 var activeItem = items[rel.activeItem]; 605 slideTo(centeredNav && activeItem ? activeItem.center : within(pos.dest, pos.start, pos.end)); 606 } else { 607 if (isInit) { 608 if (o.startAt != null) slideTo(o.startAt, 1); 609 } else { 610 // Fix possible overflowing 611 slideTo(within(pos.dest, pos.start, pos.end)); 612 } 613 } 614 615 // Trigger load event 616 trigger('load'); 617 } 618 self.reload = function () { load(); }; 619 620 /** 621 * Animate to a position. 622 * 623 * @param {Int} newPos New position. 624 * @param {Bool} immediate Reposition immediately without an animation. 625 * @param {Bool}
625 dontAlign Do not align items, use the raw position passed in first argument. 626 * 627 * @return {Void} 628 */ 629 function slideTo(newPos, immediate, dontAlign) { 630 // Align items 631 if (itemNav && dragging.released && !dontAlign) { 632 var tempRel = getRelatives(newPos); 633 var isNotBordering = newPos > pos.start && newPos < pos.end; 634 635 if (centeredNav) { 636 if (isNotBordering) { 637 newPos = items[tempRel.centerItem].center; 638 } 639 if (forceCenteredNav && o.activateMiddle) { 640 activate(tempRel.centerItem); 641 } 642 } else if (isNotBordering) { 643 newPos = items[tempRel.firstItem].start; 644 } 645 } 646 647 // Handle overflowing position limits 648 if (dragging.init && dragging.slidee && o.elasticBounds) { 649 if (newPos > pos.end) { 650 newPos = pos.end + (newPos - pos.end) / 6; 651 } else if (newPos < pos.start) { 652 newPos = pos.start + (newPos - pos.start) / 6; 653 } 654 } else { 655 newPos = within(newPos, pos.start, pos.end); 656 } 657 658 // Update the animation object 659 animation.start = +new Date(); 660 animation.time = 0; 661 animation.from = pos.cur; 662 animation.to = newPos; 663 animation.delta = newPos - pos.cur; 664 animation.tweesing = dragging.tweese || dragging.init && !dragging.slidee; 665 animation.immediate = !animation.tweesing && (immediate || dragging.init && dragging.slidee || !o.speed); 666 667 // Reset dragging tweesing request 668 dragging.tweese = 0; 669 670 // Start animation rendering 671 if (newPos !== pos.dest) { 672 pos.dest = newPos; 673 trigger('change'); 674 if (!renderID) { 675 render(); 676 } 677 } 678 679 // Reset next cycle timeout 680 resetCycle(); 681 682 // Synchronize states 683 updateRelatives(); 684 updateButtonsState(); 685 syncPagesbar(); 686 } 687 688 /** 689 * Render animation frame. 690 * 691 * @return {Void} 692 */ 693 function render() { 694 if (!self.initialized) { 695 return; 696 } 697 698 // If first render call, wait for next animationFrame 699 if (!renderID) { 700 renderID = rAF(render); 701 if (dragging.released) { 702 trigger('moveStart'); 703 } 704 return; 705 } 706 707 // If immediate repositioning is requested, don't animate. 708 if (animation.immediate) { 709 pos.cur = animation.to; 710 } 711 // Use tweesing for animations without known end point 712 else if (animation.tweesing) { 713 animation.tweeseDelta = animation.to - pos.cur; 714 // Fuck Zeno's paradox 715 if (abs(animation.tweeseDelta) < 0.1) { 716 pos.cur = animation.to; 717 } else { 718 pos.cur += animation.tweeseDelta * (dragging.released ? o.swingSpeed : o.syncSpeed); 719 } 720 } 721 // Use tweening for basic animations with known end point 722 else { 723 animation.time = min(+new Date() - animation.start, o.speed); 724 pos.cur = animation.from + animation.delta * $.easing[o.easing](animation.time/o.speed, animation.time, 0, 1, o.speed); 725 } 726 727 // If there is nothing more to render break the rendering loop, otherwise request new animation frame. 728 if (animation.to === pos.cur) { 729 pos.cur = animation.to; 730 dragging.tweese = renderID = 0; 731 } else { 732 renderID = rAF(render); 733 } 734 735 trigger('move'); 736 737 // Update SLIDEE position 738 if (!parallax) { 739 if (transform) { 740 $slidee[0].style[transform] = gpuAcceleration + (o.horizontal ? 'translateX' : 'translateY') + '(' + (-pos.cur) + 'px)'; 741 } else { 742 $slidee[0].style[o.horizontal ? 'left' : 'top'] = -round(pos.cur) + 'px'; 743 } 744 } 745 746 // When animation reached the end, and dragging is not active, trigger moveEnd 747 if (!renderID && dragging.released) { 748 trigger('moveEnd'); 749 } 750 751 syncScrollbar(); 752 } 753 754 /** 755 * Synchronizes scrollbar with the SLIDEE. 756 * 757 * @return {Void} 758 */ 759 function syncScrollbar() { 760 if ($handle.length) { 761 hPos.cur = pos.start === pos.end ? 0 : (((dragging.init && !dragging.slidee) ? pos.dest : pos.cur) - pos.start) / (pos.end - pos.start) * hPos.end; 762 hPos.cur = within(round(hPos.cur), hPos.start, hPos.end); 763 if (last.hPos !== hPos.cur) { 764 last.hPos = hPos.cur; 765 if (transform) { 766 $handle[0].style[transform] = gpuAcceleration + (o.horizontal ? 'translateX' : 'translateY') + '(' + hPos.cur + 'px)'; 767 } else { 768 $handle[0].style[o.horizontal ? 'left' : 'top'] = hPos.cur + 'px'; 769 } 770 } 771 } 772 } 773 774 /** 775 * Synchronizes pagesbar with SLIDEE. 776 * 777 * @return {Void} 778 */ 779 function syncPagesbar() { 780 if ($pages[0] && last.page !== rel.activePage) { 781 last.page = rel.activePage; 782 $pages.removeClass(o.activeClass).eq(rel.activePage).addClass(o.activeClass); 783 trigger('activePage', last.page); 784 } 785 } 786 787 /** 788 * Returns the position object. 789 * 790 * @param {Mixed} item 791 * 792 * @return {Object} 793 */ 794 self.getPos = function (item) { 795 if (itemNav) { 796 var index = getIndex(item); 797 return index !== -1 ? items[index] : false;
798 } else { 799 var $item = $slidee.find(item).eq(0); 800 801 if ($item[0]) { 802 var offset = o.horizontal ? $item.offset().left - $slidee.offset().left : $item.offset().top - $slidee.offset().top; 803 var size = $item[o.horizontal ? 'outerWidth' : 'outerHeight'](); 804 805 return { 806 start: offset, 807 center: offset - frameSize / 2 + size / 2, 808 end: offset - frameSize + size, 809 size: size 810 }; 811 } else { 812 return false; 813 } 814 } 815 }; 816 817 /** 818 * Continuous move in a specified direction. 819 * 820 * @param {Bool} forward True for forward movement, otherwise it'll go backwards. 821 * @param {Int} speed Movement speed in pixels per frame. Overrides options.moveBy value. 822 * 823 * @return {Void} 824 */ 825 self.moveBy = function (speed) { 826 move.speed = speed; 827 // If already initiated, or there is nowhere to move, abort 828 if (dragging.init || !move.speed || pos.cur === (move.speed > 0 ? pos.end : pos.start)) { 829 return; 830 } 831 // Initiate move object 832 move.lastTime = +new Date(); 833 move.startPos = pos.cur; 834 // Set dragging as initiated 835 continuousInit('button'); 836 dragging.init = 1; 837 // Start movement 838 trigger('moveStart'); 839 cAF(continuousID); 840 moveLoop(); 841 }; 842 843 /** 844 * Continuous movement loop. 845 * 846 * @return {Void} 847 */ 848 function moveLoop() { 849 // If there is nowhere to move anymore, stop 850 if (!move.speed || pos.cur === (move.speed > 0 ? pos.end : pos.start)) { 851 self.stop(); 852 } 853 // Request new move loop if it hasn't been stopped 854 continuousID = dragging.init ? rAF(moveLoop) : 0; 855 // Update move object 856 move.now = +new Date(); 857 move.pos = pos.cur + (move.now - move.lastTime) / 1000 * move.speed; 858 // Slide 859 slideTo(dragging.init ? move.pos : round(move.pos)); 860 // Normally, this is triggered in render(), but if there 861 // is nothing to render, we have to do it manually here. 862 if (!dragging.init && pos.cur === pos.dest) { 863 trigger('moveEnd'); 864 } 865 // Update times for future iteration 866 move.lastTime = move.now; 867 } 868 869 /** 870 * Stops continuous movement. 871 * 872 * @return {Void} 873 */ 874 self.stop = function () { 875 if (dragging.source === 'button') { 876 dragging.init = 0; 877 dragging.released = 1; 878 } 879 }; 880 881 /** 882 * Activate previous item. 883 * 884 * @return {Void} 885 */ 886 self.prev = function () { 887 self.activate(rel.activeItem == null ? 0 : rel.activeItem - 1); 888 }; 889 890 /** 891 * Activate next item. 892 * 893 * @return {Void} 894 */ 895 self.next = function () { 896 self.activate(rel.activeItem == null ? 0 : rel.activeItem + 1); 897 }; 898 899 /** 900 * Activate previous page. 901 * 902 * @return {Void} 903 */ 904 self.prevPage = function () { 905 self.activatePage(rel.activePage - 1); 906 }; 907 908 /** 909 * Activate next page. 910 * 911 * @return {Void} 912 */ 913 self.nextPage = function () {
914 self.activatePage(rel.activePage + 1); 915 }; 916 917 /** 918 * Slide SLIDEE by amount of pixels. 919 * 920 * @param {Int} delta Pixels/Items. Positive means forward, negative means backward. 921 * @param {Bool} immediate Reposition immediately without an animation. 922 * 923 * @return {Void} 924 */ 925 self.slideBy = function (delta, immediate) { 926 if (!delta) { 927 return; 928 } 929 if (itemNav) { 930 self[centeredNav ? 'toCenter' : 'toStart']( 931 within((centeredNav ? rel.centerItem : rel.firstItem) + o.scrollBy * delta, 0, items.length) 932 ); 933 } else { 934 slideTo(pos.dest + delta, immediate); 935 } 936 }; 937 938 /** 939 * Animate SLIDEE to a specific position. 940 * 941 * @param {Int} pos New position. 942 * @param {Bool} immediate Reposition immediately without an animation. 943 * 944 * @return {Void} 945 */ 946 self.slideTo = function (pos, immediate) { 947 slideTo(pos, immediate); 948 }; 949 950 /** 951 * Core method for handling `toLocation` methods. 952 * 953 * @param {String} location 954 * @param {Mixed} item 955 * @param {Bool} immediate 956 * 957 * @return {Void} 958 */ 959 function to(location, item, immediate) { 960 // Optional arguments logic 961 if (type(item) === 'boolean') { 962 immediate = item; 963 item = undefined; 964 } 965 966 if (item === undefined) { 967 slideTo(pos[location], immediate); 968 } else { 969 // You can't align items to sides of the frame 970 // when centered navigation type is enabled 971 if (centeredNav && location !== 'center') { 972 return; 973 } 974 975 var itemPos = self.getPos(item); 976 if (itemPos) { 977 slideTo(itemPos[location], immediate, !centeredNav); 978 } 979 } 980 } 981 982 /** 983 * Animate element or the whole SLIDEE to the start of the frame. 984 * 985 * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE. 986 * @param {Bool} immediate Reposition immediately without an animation. 987 * 988 * @return {Void} 989 */ 990 self.toStart = function (item, immediate) { 991 to('start', item, immediate); 992 }; 993 994 /** 995 * Animate element or the whole SLIDEE to the end of the frame. 996 * 997 * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE. 998 * @param {Bool} immediate Reposition immediately without an animation. 999 * 1000 * @return {Void} 1001 */ 1002 self.toEnd = function (item, immediate) { 1003 to('end', item, immediate); 1004 }; 1005 1006 /** 1007 * Animate element or the whole SLIDEE to the center of the frame. 1008 * 1009 * @param {Mixed} item Item DOM element, or index starting at 0. Omitting will animate SLIDEE. 1010 * @param {Bool} immediate Reposition immediately without an animation. 1011 * 1012 * @return {Void} 1013 */ 1014 self.toCenter = function (item, immediate) { 1015 to('center', item, immediate); 1016 }; 1017 1018 /** 1019 * Get the index of an item in SLIDEE. 1020 * 1021 * @param {Mixed} item Item DOM element. 1022 * 1023 * @return {Int} Item index, or -1 if not found. 1024 */ 1025 function getIndex(item) { 1026 return item != null ? 1027 isNumber(item) ? 1028 item >= 0 && item < items.length ? item : -1 : 1029 $items.index(item) : 1030 -1; 1031 } 1032 // Expose getIndex without lowering the compressibility of it, 1033 // as it is used quite often throughout Sly. 1034 self.getIndex = getIndex; 1035 1036 /** 1037 * Get index of an item in SLIDEE based on a variety of input types. 1038 * 1039 * @param {Mixed} item DOM element, positive or negative integer. 1040 * 1041 * @return {Int} Item index, or -1 if not found. 1042 */ 1043 function getRelativeIndex(item) { 1044 return getIndex(isNumber(item) && item < 0 ? item + items.length : item); 1045 } 1046 1047 /** 1048 * Activates an item. 1049 * 1050 * @param {Mixed} item Item DOM element, or index starting at 0. 1051 * 1052 * @return {Mixed} Activated item index or false on fail. 1053 */ 1054 function activate(item, force) { 1055 var index = getIndex(item); 1056 1057 if (!itemNav || index < 0) { 1058 return false; 1059 } 1060 1061 // Update classes, last active index, and trigger active event only when there 1062 // has been a change. Otherwise just return the current active index. 1063 if (last.active !== index || force) { 1064 // Update classes 1065 $items.eq(rel.activeItem).removeClass(o.activeClass); 1066 $items.eq(index).addClass(o.activeClass); 1067 1068 last.active = rel.activeItem = index; 1069 1070 updateButtonsState(); 1071 trigger('active', index); 1072 } 1073 1074 return index; 1075 } 1076 1077 /** 1078 * Activates an item and helps with further navigation when o.smart is enabled. 1079 * 1080 * @param {Mixed} item Item DOM element, or index starting at 0. 1081 * @param {Bool} immediate Whether to reposition immediately in smart navigation. 1082 * 1083 * @return {Void} 1084 */ 1085 self.activate = function (item, immediate) { 1086 var index = activate(item); 1087 1088 // Smart navigation 1089 if (o.smart && index !== false) { 1090 // When centeredNav is enabled, center the element. 1091 // Otherwise, determine where to position the element based on its current position. 1092 // If the element is currently on the far end side of the frame, assume that user is 1093 // moving forward and animate it to the start of the visible frame, and vice versa. 1094 if (centeredNav) { 1095 self.toCenter(index, immediate); 1096 } else if (index >= rel.lastItem) { 1097 self.toStart(index, immediate); 1098 } else if (index <= rel.firstItem) { 1099 self.toEnd(index, immediate); 1100 } else { 1101 resetCycle(); 1102 } 1103 } 1104 }; 1105 1106 /** 1107 * Activates a page. 1108 * 1109 * @param {Int} index Page index, starting from 0. 1110 * @param {Bool} immediate Whether to reposition immediately without animation. 1111 * 1112 * @return {Void} 1113 */ 1114 self.activatePage = function (index, immediate) { 1115 if (isNumber(index)) { 1116 slideTo(pages[within(index, 0, pages.length - 1)], immediate); 1117 } 1118 }; 1119 1120 /** 1121 * Return relative positions of items based on their visibility within FRAME. 1122 * 1123 * @param {Int} slideePos Position of SLIDEE. 1124 * 1125 * @return {Void} 1126 */ 1127 function getRelatives(slideePos) {
1128 slideePos = within(isNumber(slideePos) ? slideePos : pos.dest, pos.start, pos.end); 1129 1130 var relatives = {}; 1131 var centerOffset = forceCenteredNav ? 0 : frameSize / 2; 1132 1133 // Determine active page 1134 if (!parallax) { 1135 for (var p = 0, pl = pages.length; p < pl; p++) { 1136 if (slideePos >= pos.end || p === pages.length - 1) { 1137 relatives.activePage = pages.length - 1; 1138 break; 1139 } 1140 1141 if (slideePos <= pages[p] + centerOffset) { 1142 relatives.activePage = p; 1143 break; 1144 } 1145 } 1146 } 1147 1148 // Relative item indexes 1149 if (itemNav) { 1150 var first = false; 1151 var last = false; 1152 var center = false; 1153 1154 // From start 1155 for (var i = 0, il = items.length; i < il; i++) { 1156 // First item 1157 if (first === false && slideePos <= items[i].start + items[i].half) { 1158 first = i; 1159 } 1160 1161 // Center item 1162 if (center === false && slideePos <= items[i].center + items[i].half) { 1163 center = i; 1164 } 1165 1166 // Last item 1167 if (i === il - 1 || slideePos <= items[i].end + items[i].half) { 1168 last = i; 1169 break; 1170 } 1171 } 1172 1173 // Safe assignment, just to be sure the false won't be returned 1174 relatives.firstItem = isNumber(first) ? first : 0; 1175 relatives.centerItem = isNumber(center) ? center : relatives.firstItem; 1176 relatives.lastItem = isNumber(last) ? last : relatives.centerItem; 1177 } 1178 1179 return relatives; 1180 } 1181 1182 /** 1183 * Update object with relative positions. 1184 * 1185 * @param {Int} newPos 1186 * 1187 * @return {Void} 1188 */ 1189 function updateRelatives(newPos) { 1190 $.extend(rel, getRelatives(newPos)); 1191 } 1192 1193 /** 1194 * Disable navigation buttons when needed. 1195 * 1196 * Adds disabledClass, and when the button is <button> or <input>, activates :disabled state. 1197 * 1198 * @return {Void} 1199 */ 1200 function updateButtonsState() { 1201 var isStart = pos.dest <= pos.start; 1202 var isEnd = pos.dest >= pos.end; 1203 var slideePosState = (isStart ? 1 : 0) | (isEnd ? 2 : 0); 1204 1205 // Update paging buttons only if there has been a change in SLIDEE position 1206 if (last.slideePosState !== slideePosState) { 1207 last.slideePosState = slideePosState; 1208 1209 if ($prevPageButton.is('button,input')) { 1210 $prevPageButton.prop('disabled', isStart); 1211 } 1212 1213 if ($nextPageButton.is('button,input')) { 1214 $nextPageButton.prop('disabled', isEnd); 1215 } 1216 1217 $prevPageButton.add($backwardButton)[isStart ? 'addClass' : 'removeClass'](o.disabledClass); 1218 $nextPageButton.add($forwardButton)[isEnd ? 'addClass' : 'removeClass'](o.disabledClass); 1219 } 1220 1221 // Forward & Backward buttons need a separate state caching because we cannot "property disable" 1222 // them while they are being used, as disabled buttons stop emitting mouse events. 1223 if (last.fwdbwdState !== slideePosState && dragging.released) { 1224 last.fwdbwdState = slideePosState; 1225 1226 if ($backwardButton.is('button,input')) { 1227 $backwardButton.prop('disabled', isStart); 1228 } 1229 1230 if ($forwardButton.is('button,input')) { 1231 $forwardButton.prop('disabled', isEnd); 1232 } 1233 } 1234 1235 // Item navigation 1236 if (itemNav && rel.activeItem != null) { 1237 var isFirst = rel.activeItem === 0; 1238 var isLast = rel.activeItem >= items.length - 1; 1239 var itemsButtonState = (isFirst ? 1 : 0) | (isLast ? 2 : 0); 1240 1241 if (last.itemsButtonState !== itemsButtonState) { 1242 last.itemsButtonState = itemsButtonState; 1243 1244 if ($prevButton.is('button,input')) { 1245 $prevButton.prop('disabled', isFirst); 1246 } 1247 1248 if ($nextButton.is('button,input')) { 1249 $nextButton.prop('disabled', isLast); 1250 } 1251 1252 $prevButton[isFirst ? 'addClass' : 'removeClass'](o.disabledClass); 1253 $nextButton[isLast ? 'addClass' : 'removeClass'](o.disabledClass); 1254 } 1255 } 1256 } 1257 1258 /** 1259 * Resume cycling. 1260 * 1261 * @param {Int} priority Resume pause with priority lower or equal than this. Used internally for pauseOnHover. 1262 * 1263 * @return {Void} 1264 */ 1265 self.resume = function (priority) { 1266 if (!o.cycleBy || !o.cycleInterval || o.cycleBy === 'items' && (!items[0] || rel.activeItem == null) || priority < self.isPaused) { 1267 return; 1268 } 1269 1270 self.isPaused = 0; 1271 1272 if (cycleID) { 1273 cycleID = clearTimeout(cycleID); 1274 } else { 1275 trigger('resume'); 1276 } 1277 1278 cycleID = setTimeout(function () { 1279 trigger('cycle'); 1280 switch (o.cycleBy) { 1281 case 'items': 1282 self.activate(rel.activeItem >= items.length - 1 ? 0 : rel.activeItem + 1); 1283 break; 1284 1285 case 'pages': 1286 self.activatePage(rel.activePage >
1286= pages.length - 1 ? 0 : rel.activePage + 1); 1287 break; 1288 } 1289 }, o.cycleInterval); 1290 }; 1291 1292 /** 1293 * Pause cycling. 1294 * 1295 * @param {Int} priority Pause priority. 100 is default. Used internally for pauseOnHover. 1296 * 1297 * @return {Void} 1298 */ 1299 self.pause = function (priority) { 1300 if (priority < self.isPaused) { 1301 return; 1302 } 1303 1304 self.isPaused = priority || 100; 1305 1306 if (cycleID) { 1307 cycleID = clearTimeout(cycleID); 1308 trigger('pause'); 1309 } 1310 }; 1311 1312 /** 1313 * Toggle cycling. 1314 * 1315 * @return {Void} 1316 */ 1317 self.toggle = function () { 1318 self[cycleID ? 'pause' : 'resume'](); 1319 }; 1320 1321 /** 1322 * Updates a signle or multiple option values. 1323 * 1324 * @param {Mixed} name Name of the option that should be updated, or object that will extend the options. 1325 * @param {Mixed} value New option value. 1326 * 1327 * @return {Void} 1328 */ 1329 self.set = function (name, value) { 1330 if ($.isPlainObject(name)) { 1331 $.extend(o, name); 1332 } else if (o.hasOwnProperty(name)) { 1333 o[name] = value; 1334 } 1335 }; 1336 1337 /** 1338 * Add one or multiple items to the SLIDEE end, or a specified position index. 1339 * 1340 * @param {Mixed} element Node element, or HTML string. 1341 * @param {Int} index Index of a new item position. By default item is appended at the end. 1342 * 1343 * @return {Void} 1344 */ 1345 self.add = function (element, index) { 1346 var $element = $(element); 1347 1348 if (itemNav) { 1349 // Insert the element(s) 1350 if (index == null || !items[0] || index >= items.length) { 1351 $element.appendTo($slidee); 1352 } else if (items.length) { 1353 $element.insertBefore(items[index].el); 1354 } 1355 1356 // Adjust the activeItem index 1357 if (rel.activeItem != null && index <= rel.activeItem) { 1358 last.active = rel.activeItem += $element.length; 1359 } 1360 } else { 1361 $slidee.append($element); 1362 } 1363 1364 // Reload 1365 load(); 1366 }; 1367 1368 /** 1369 * Remove an item from SLIDEE. 1370 * 1371 * @param {Mixed} element Item index, or DOM element. 1372 * @param {Int} index Index of a new item position. By default item is appended at the end. 1373 * 1374 * @return {Void} 1375 */ 1376 self.remove = function (element) { 1377 if (itemNav) { 1378 var index = getRelativeIndex(element); 1379 1380 if (index > -1) { 1381 // Remove the element 1382 $items.eq(index).remove(); 1383 1384 // If the current item is being removed, activate new one after reload 1385 var reactivate = index === rel.activeItem; 1386 1387 // Adjust the activeItem index 1388 if (rel.activeItem != null && index < rel.activeItem) { 1389 last.active = --rel.activeItem; 1390 } 1391 1392 // Reload 1393 load(); 1394 1395 // Activate new item at the removed position 1396 if (reactivate) { 1397 last.active = null; 1398 self.activate(rel.activeItem); 1399 } 1400 } 1401 } else { 1402 $(element).remove(); 1403 load(); 1404 } 1405 }; 1406 1407 /** 1408 * Helps re-arranging items. 1409 * 1410 * @param {Mixed} item Item DOM element, or index starting at 0. Use negative numbers to select items from the end. 1411 * @param {Mixed} position Item insertion anchor. Accepts same input types as item argument. 1412 * @param {Bool} after Insert after instead of before the anchor. 1413 * 1414 * @return {Void} 1415 */ 1416 function moveItem(item, position, after) { 1417 item = getRelativeIndex(item); 1418 position = getRelativeIndex(position); 1419 1420 // Move only if there is an actual change requested 1421 if (item > -1 && position > -1 && item !== position && (!after || position !== item - 1) && (after || position !== item + 1)) { 1422 $items.eq(item)[after ? 'insertAfter' : 'insertBefore'](items[position].el); 1423 1424 var shiftStart = item < position ? item : (after ? position : position - 1); 1425 var shiftEnd = item > position ? item : (after ? position + 1 : position); 1426 var shiftsUp = item > position; 1427 1428 // Update activeItem index 1429 if (rel.activeItem != null) { 1430 if (item === rel.activeItem) { 1431 last.active = rel.activeItem = after ? (shiftsUp ? position + 1 : position) : (shiftsUp ? position : position - 1); 1432 } else if (rel.activeItem > shiftStart && rel.activeItem < shiftEnd) { 1433 last.active = rel.activeItem += shiftsUp ? 1 : -1; 1434 } 1435 } 1436 1437 // Reload 1438 load(); 1439 } 1440 } 1441 1442 /** 1443 * Move item after the target anchor. 1444 * 1445 * @param {Mixed} item Item to be moved. Can be DOM element or item index. 1446 * @param {Mixed} position Target position anchor. Can be DOM element or item index. 1447 * 1448 * @return {Void} 1449 */ 1450 self.moveAfter = function (item, position) { 1451 moveItem(item, position, 1); 1452 }; 1453 1454 /** 1455 * Move item before the target anchor. 1456 * 1457 * @param {Mixed} item Item to be moved. Can be DOM element or item index. 1458 * @param {Mixed} position Target position anchor. Can be DOM element or item index. 1459 * 1460 * @return {Void} 1461 */ 1462 self.moveBefore = function (item, position) { 1463 moveItem(item, position); 1464 }; 1465 1466 /** 1467 * Registers callbacks. 1468 * 1469 * @param {Mixed}
1469 name Event name, or callbacks map. 1470 * @param {Mixed} fn Callback, or an array of callback functions. 1471 * 1472 * @return {Void} 1473 */ 1474 self.on = function (name, fn) { 1475 // Callbacks map 1476 if (type(name) === 'object') { 1477 for (var key in name) { 1478 if (name.hasOwnProperty(key)) { 1479 self.on(key, name[key]); 1480 } 1481 } 1482 // Callback 1483 } else if (type(fn) === 'function') { 1484 var names = name.split(' '); 1485 for (var n = 0, nl = names.length; n < nl; n++) { 1486 callbacks[names[n]] = callbacks[names[n]] || []; 1487 if (callbackIndex(names[n], fn) === -1) { 1488 callbacks[names[n]].push(fn); 1489 } 1490 } 1491 // Callbacks array 1492 } else if (type(fn) === 'array') { 1493 for (var f = 0, fl = fn.length; f < fl; f++) { 1494 self.on(name, fn[f]); 1495 } 1496 } 1497 }; 1498 1499 /** 1500 * Registers callbacks to be executed only once. 1501 * 1502 * @param {Mixed} name Event name, or callbacks map. 1503 * @param {Mixed} fn Callback, or an array of callback functions. 1504 * 1505 * @return {Void} 1506 */ 1507 self.one = function (name, fn) { 1508 function proxy() { 1509 fn.apply(self, arguments); 1510 self.off(name, proxy); 1511 } 1512 self.on(name, proxy); 1513 }; 1514 1515 /** 1516 * Remove one or all callbacks. 1517 * 1518 * @param {String} name Event name. 1519 * @param {Mixed} fn Callback, or an array of callback functions. Omit to remove all callbacks. 1520 * 1521 * @return {Void} 1522 */ 1523 self.off = function (name, fn) { 1524 if (fn instanceof Array) { 1525 for (var f = 0, fl = fn.length; f < fl; f++) { 1526 self.off(name, fn[f]); 1527 } 1528 } else { 1529 var names = name.split(' '); 1530 for (var n = 0, nl = names.length; n < nl; n++) { 1531 callbacks[names[n]] = callbacks[names[n]] || []; 1532 if (fn == null) { 1533 callbacks[names[n]].length = 0; 1534 } else { 1535 var index = callbackIndex(names[n], fn); 1536 if (index !== -1) { 1537 callbacks[names[n]].splice(index, 1); 1538 } 1539 } 1540 } 1541 } 1542 }; 1543 1544 /** 1545 * Returns callback array index. 1546 * 1547 * @param {String} name Event name. 1548 * @param {Function} fn Function 1549 * 1550 * @return {Int} Callback array index, or -1 if isn't registered. 1551 */ 1552 function callbackIndex(name, fn) { 1553 for (var i = 0, l = callbacks[name].length; i < l; i++) { 1554 if (callbacks[name][i] === fn) { 1555 return i; 1556 } 1557 } 1558 return -1; 1559 } 1560 1561 /** 1562 * Reset next cycle timeout. 1563 * 1564 * @return {Void} 1565 */ 1566 function resetCycle() { 1567 if (dragging.released && !self.isPaused) { 1568 self.resume(); 1569 } 1570 } 1571 1572 /** 1573 * Calculate SLIDEE representation of handle position. 1574 * 1575 * @param {Int} handlePos 1576 * 1577 * @return {Int} 1578 */ 1579 function handleToSlidee(handlePos) { 1580 return round(within(handlePos, hPos.start, hPos.end) / hPos.end * (pos.end - pos.start)) + pos.start; 1581 } 1582 1583 /** 1584 * Keeps track of a dragging delta history. 1585 * 1586 * @return {Void} 1587 */ 1588 function draggingHistoryTick() { 1589 // Looking at this, I know what you're thinking :) But as we need only 4 history states, doing it this way 1590 // as opposed to a proper loop is ~25 bytes smaller (when minified with GCC), a lot faster, and doesn't 1591 // generate garbage. The loop version would create 2 new variables on every tick. Unexaptable! 1592 dragging.history[0] = dragging.history[1]; 1593 dragging.history[1] = dragging.history[2]; 1594 dragging.history[2] = dragging.history[3]; 1595 dragging.history[3] = dragging.delta; 1596 } 1597 1598 /** 1599 * Initialize continuous movement. 1600 * 1601 * @return {Void} 1602 */ 1603 function continuousInit(source) { 1604 dragging.released = 0; 1605 dragging.source = source; 1606 dragging.slidee = source === 'slidee'; 1607 } 1608 1609 /** 1610 * Dragging initiator. 1611 * 1612 * @param {Event} event 1613 * 1614 * @return {Void} 1615 */ 1616 function dragInit(event) { 1617 var isTouch = event.type === 'touchstart'; 1618 var source = event.data.source; 1619 var isSlidee = source === 'slidee'; 1620 1621 // Ignore when already in progress, or interactive element in non-touch navivagion 1622 if (dragging.init || !isTouch && isInteractive(event.target)) { 1623 return; 1624 } 1625 1626 // Handle dragging conditions 1627 if (source === 'handle' && (!o.dragHandle || hPos.start === hPos.end)) { 1628 return; 1629 } 1630 1631 // SLIDEE dragging conditions 1632 if (isSlidee && !(isTouch ? o.touchDragging : o.mouseDragging && event.which < 2)) { 1633 return; 1634 } 1635 1636 if (!isTouch) { 1637 // prevents native image dragging in Firefox 1638 stopDefault(event); 1639 } 1640 1641 // Reset dragging object
1642 continuousInit(source); 1643 1644 // Properties used in dragHandler 1645 dragging.init = 0; 1646 dragging.$source = $(event.target); 1647 dragging.touch = isTouch; 1648 dragging.pointer = isTouch ? event.originalEvent.touches[0] : event; 1649 dragging.initX = dragging.pointer.pageX; 1650 dragging.initY = dragging.pointer.pageY; 1651 dragging.initPos = isSlidee ? pos.cur : hPos.cur; 1652 dragging.start = +new Date(); 1653 dragging.time = 0; 1654 dragging.path = 0; 1655 dragging.delta = 0; 1656 dragging.locked = 0; 1657 dragging.history = [0, 0, 0, 0]; 1658 dragging.pathToLock = isSlidee ? isTouch ? 30 : 10 : 0; 1659 1660 // Bind dragging events 1661 $doc.on(isTouch ? dragTouchEvents : dragMouseEvents, dragHandler); 1662 1663 // Pause ongoing cycle 1664 self.pause(1); 1665 1666 // Add dragging class 1667 (isSlidee ? $slidee : $handle).addClass(o.draggedClass); 1668 1669 // Trigger moveStart event 1670 trigger('moveStart'); 1671 1672 // Keep track of a dragging path history. This is later used in the 1673 // dragging release swing calculation when dragging SLIDEE. 1674 if (isSlidee) { 1675 historyID = setInterval(draggingHistoryTick, 10); 1676 } 1677 } 1678 1679 /** 1680 * Handler for dragging scrollbar handle or SLIDEE. 1681 * 1682 * @param {Event} event 1683 * 1684 * @return {Void} 1685 */ 1686 function dragHandler(event) { 1687 dragging.released = event.type === 'mouseup' || event.type === 'touchend'; 1688 dragging.pointer = dragging.touch ? event.originalEvent[dragging.released ? 'changedTouches' : 'touches'][0] : event; 1689 dragging.pathX = dragging.pointer.pageX - dragging.initX; 1690 dragging.pathY = dragging.pointer.pageY - dragging.initY; 1691 dragging.path = sqrt(pow(dragging.pathX, 2) + pow(dragging.pathY, 2)); 1692 dragging.delta = o.horizontal ? dragging.pathX : dragging.pathY; 1693 1694 if (!dragging.released && dragging.path < 1) return; 1695 1696 // We haven't decided whether this is a drag or not... 1697 if (!dragging.init) { 1698 // If the drag path was very short, maybe it's not a drag? 1699 if (dragging.path < o.dragThreshold) { 1700 // If the pointer was released, the path will not become longer and it's 1701 // definitely not a drag. If not released yet, decide on next iteration 1702 return dragging.released ? dragEnd() : undefined; 1703 } 1704 else { 1705 // If dragging path is sufficiently long we can confidently start a drag 1706 // if drag is in different direction than scroll, ignore it 1707 if (o.horizontal ? abs(dragging.pathX) > abs(dragging.pathY) : abs(dragging.pathX) < abs(dragging.pathY)) { 1708 dragging.init = 1; 1709 } else { 1710 return dragEnd(); 1711 } 1712 } 1713 } 1714 1715 stopDefault(event); 1716 1717 // Disable click on a source element, as it is unwelcome when dragging 1718 if (!dragging.locked && dragging.path > dragging.pathToLock && dragging.slidee) { 1719 dragging.locked = 1; 1720 dragging.$source.on(clickEvent, disableOneEvent); 1721 } 1722 1723 // Cancel dragging on release 1724 if (dragging.released) { 1725 dragEnd(); 1726 1727 // Adjust path with a swing on mouse release 1728 if (o.releaseSwing && dragging.slidee) { 1729 dragging.swing = (dragging.delta - dragging.history[0]) / 40 * 300; 1730 dragging.delta += dragging.swing; 1731 dragging.tweese = abs(dragging.swing) > 10; 1732 } 1733 } 1734 1735 slideTo(dragging.slidee ? round(dragging.initPos - dragging.delta) : handleToSlidee(dragging.initPos + dragging.delta)); 1736 } 1737 1738 /** 1739 * Stops dragging and cleans up after it. 1740 * 1741 * @return {Void} 1742 */ 1743 function dragEnd() { 1744 clearInterval(historyID); 1745 dragging.released = true; 1746 $doc.off(dragging.touch ? dragTouchEvents : dragMouseEvents, dragHandler); 1747 (dragging.slidee ? $slidee : $handle).removeClass(o.draggedClass); 1748 1749 // Make sure that disableOneEvent is not active in next tick. 1750 setTimeout(function () { 1751 dragging.$source.off(clickEvent, disableOneEvent); 1752 }); 1753 1754 // Normally, this is triggered in render(), but if there 1755 // is nothing to render, we have to do it manually here. 1756 if (pos.cur === pos.dest && dragging.init) { 1757 trigger('moveEnd'); 1758 } 1759 1760 // Resume ongoing cycle 1761 self.resume(1); 1762 1763 dragging.init = 0; 1764 } 1765 1766 /** 1767 * Check whether element is interactive. 1768 * 1769 * @return {Boolean} 1770 */ 1771 function isInteractive(element) { 1772 return ~$.inArray(element.nodeName, interactiveElements) || $(element).is(o.interactive); 1773 } 1774 1775 /** 1776 * Continuous movement cleanup on mouseup. 1777 * 1778 * @return {Void} 1779 */ 1780 function movementReleaseHandler() { 1781 self.stop(); 1782 $doc.off('mouseup', movementReleaseHandler); 1783 } 1784 1785 /** 1786 * Buttons navigation handler. 1787 * 1788 * @param {Event} event 1789 * 1790 * @return {Void} 1791 */ 1792 function buttonsHandler(event) { 1793 /*jshint validthis:true */ 1794 stopDefault(event); 1795 switch (this) { 1796 case $forwardButton[0]: 1797 case $backwardButton[0]: 1798 self.moveBy($forwardButton.is(this) ? o.moveBy : -o.moveBy); 1799 $doc.on('mouseup', movementReleaseHandler); 1800 break; 1801
1802 case $prevButton[0]: 1803 self.prev(); 1804 break; 1805 1806 case $nextButton[0]: 1807 self.next(); 1808 break; 1809 1810 case $prevPageButton[0]: 1811 self.prevPage(); 1812 break; 1813 1814 case $nextPageButton[0]: 1815 self.nextPage(); 1816 break; 1817 } 1818 } 1819 1820 /** 1821 * Mouse wheel delta normalization. 1822 * 1823 * @param {Event} event 1824 * 1825 * @return {Int} 1826 */ 1827 function normalizeWheelDelta(event) { 1828 // wheelDelta needed only for IE8- 1829 scrolling.curDelta = ((o.horizontal ? event.deltaY || event.deltaX : event.deltaY) || -event.wheelDelta); 1830 scrolling.curDelta /= event.deltaMode === 1 ? 3 : 100; 1831 if (!itemNav) { 1832 return scrolling.curDelta; 1833 } 1834 time = +new Date(); 1835 if (scrolling.last < time - scrolling.resetTime) { 1836 scrolling.delta = 0; 1837 } 1838 scrolling.last = time; 1839 scrolling.delta += scrolling.curDelta; 1840 if (abs(scrolling.delta) < 1) { 1841 scrolling.finalDelta = 0; 1842 } else { 1843 scrolling.finalDelta = round(scrolling.delta / 1); 1844 scrolling.delta %= 1; 1845 } 1846 return scrolling.finalDelta; 1847 } 1848 1849 /** 1850 * Mouse scrolling handler. 1851 * 1852 * @param {Event} event 1853 * 1854 * @return {Void} 1855 */ 1856 function scrollHandler(event) { 1857 // Mark event as originating in a Sly instance 1858 event.originalEvent[namespace] = self; 1859 // Don't hijack global scrolling 1860 var time = +new Date(); 1861 if (lastGlobalWheel + o.scrollHijack > time && $scrollSource[0] !== document && $scrollSource[0] !== window) { 1862 lastGlobalWheel = time; 1863 return; 1864 } 1865 // Ignore if there is no scrolling to be done 1866 if (!o.scrollBy || pos.start === pos.end) { 1867 return; 1868 } 1869 var delta = normalizeWheelDelta(event.originalEvent); 1870 // Trap scrolling only when necessary and/or requested 1871 if (o.scrollTrap || delta > 0 && pos.dest < pos.end || delta < 0 && pos.dest > pos.start) { 1872 stopDefault(event, 1); 1873 } 1874 self.slideBy(o.scrollBy * delta); 1875 } 1876 1877 /** 1878 * Scrollbar click handler. 1879 * 1880 * @param {Event} event 1881 * 1882 * @return {Void} 1883 */ 1884 function scrollbarHandler(event) { 1885 // Only clicks on scroll bar. Ignore the handle. 1886 if (o.clickBar && event.target === $sb[0]) { 1887 stopDefault(event); 1888 // Calculate new handle position and sync SLIDEE to it 1889 slideTo(handleToSlidee((o.horizontal ? event.pageX - $sb.offset().left : event.pageY - $sb.offset().top) - handleSize / 2)); 1890 } 1891 } 1892 1893 /** 1894 * Keyboard input handler. 1895 * 1896 * @param {Event} event 1897 * 1898 * @return {Void} 1899 */ 1900 function keyboardHandler(event) { 1901 if (!o.keyboardNavBy) { 1902 return; 1903 } 1904 1905 switch (event.which) { 1906 // Left or Up 1907 case o.horizontal ? 37 : 38: 1908 stopDefault(event); 1909 self[o.keyboardNavBy === 'pages' ? 'prevPage' : 'prev'](); 1910 break; 1911 1912 // Right or Down 1913 case o.horizontal ? 39 : 40: 1914 stopDefault(event); 1915 self[o.keyboardNavBy === 'pages' ? 'nextPage' : 'next'](); 1916 break; 1917 } 1918 } 1919 1920 /** 1921 * Click on item activation handler. 1922 * 1923 * @param {Event} event 1924 * 1925 * @return {Void} 1926 */ 1927 function activateHandler(event) { 1928 /*jshint validthis:true */ 1929 1930 // Ignore clicks on interactive elements. 1931 if (isInteractive(this)) { 1932 event.originalEvent[namespace + 'ignore'] = true; 1933 return; 1934 } 1935 1936 // Ignore events that: 1937 // - are not originating from direct SLIDEE children 1938 // - originated from interactive elements 1939 if (this.parentNode !== $slidee[0] || event.originalEvent[namespace + 'ignore']) return; 1940 1941 self.activate(this); 1942 } 1943 1944 /** 1945 * Click on page button handler. 1946 * 1947 * @param {Event} event 1948 * 1949 * @return {Void} 1950 */ 1951 function activatePageHandler() { 1952 /*jshint validthis:true */ 1953 // Accept only events from direct pages bar children. 1954 if (this.parentNode === $pb[0]) { 1955 self.activatePage($pages.index(this)); 1956 } 1957 } 1958 1959 /** 1960 * Pause on hover handler. 1961 * 1962 * @param {Event} event 1963 * 1964 * @return {Void} 1965 */ 1966 function pauseOnHoverHandler(event) { 1967 if (o.pauseOnHover) { 1968 self[event.type === 'mouseenter' ? 'pause' : 'resume'](2); 1969 } 1970 } 1971 1972 /** 1973 * Trigger callbacks for event. 1974 * 1975 * @param {String} name Event name. 1976 * @param {Mixed} argX Arguments passed to callbacks. 1977 * 1978 * @return {Void} 1979 */ 1980 function trigger(name, arg1) { 1981 if (callbacks[name]) { 1982 l = callbacks[name].length; 1983 // Callbacks will be stored and executed from a temporary array to not
1984 // break the execution queue when one of the callbacks unbinds itself. 1985 tmpArray.length = 0; 1986 for (i = 0; i < l; i++) { 1987 tmpArray.push(callbacks[name][i]); 1988 } 1989 // Execute the callbacks 1990 for (i = 0; i < l; i++) { 1991 tmpArray[i].call(self, name, arg1); 1992 } 1993 } 1994 } 1995 1996 /** 1997 * Destroys instance and everything it created. 1998 * 1999 * @return {Void} 2000 */ 2001 self.destroy = function () { 2002 // Remove the reference to itself 2003 Sly.removeInstance(frame); 2004 2005 // Unbind all events 2006 $scrollSource 2007 .add($handle) 2008 .add($sb) 2009 .add($pb) 2010 .add($forwardButton) 2011 .add($backwardButton) 2012 .add($prevButton) 2013 .add($nextButton) 2014 .add($prevPageButton) 2015 .add($nextPageButton) 2016 .off('.' + namespace); 2017 2018 // Unbinding specifically as to not nuke out other instances 2019 $doc.off('keydown', keyboardHandler); 2020 2021 // Remove classes 2022 $prevButton 2023 .add($nextButton) 2024 .add($prevPageButton) 2025 .add($nextPageButton) 2026 .removeClass(o.disabledClass); 2027 2028 if ($items && rel.activeItem != null) { 2029 $items.eq(rel.activeItem).removeClass(o.activeClass); 2030 } 2031 2032 // Remove page items 2033 $pb.empty(); 2034 2035 if (!parallax) { 2036 // Unbind events from frame 2037 $frame.off('.' + namespace); 2038 // Restore original styles 2039 frameStyles.restore(); 2040 slideeStyles.restore(); 2041 sbStyles.restore(); 2042 handleStyles.restore(); 2043 // Remove the instance from element data storage 2044 $.removeData(frame, namespace); 2045 } 2046 2047 // Clean up collections 2048 items.length = pages.length = 0; 2049 last = {}; 2050 2051 // Reset initialized status and return the instance 2052 self.initialized = 0; 2053 return self; 2054 }; 2055 2056 /** 2057 * Initialize. 2058 * 2059 * @return {Object} 2060 */ 2061 self.init = function () { 2062 if (self.initialized) { 2063 return; 2064 } 2065 2066 // Disallow multiple instances on the same element 2067 if (Sly.getInstance(frame)) throw new Error('There is already a Sly instance on this element'); 2068 2069 // Store the reference to itself 2070 Sly.storeInstance(frame, self); 2071 2072 // Register callbacks map 2073 self.on(callbackMap); 2074 2075 // Save styles 2076 var holderProps = ['overflow', 'position']; 2077 var movableProps = ['position', 'webkitTransform', 'msTransform', 'transform', 'left', 'top', 'width', 'height']; 2078 frameStyles.save.apply(frameStyles, holderProps); 2079 sbStyles.save.apply(sbStyles, holderProps); 2080 slideeStyles.save.apply(slideeStyles, movableProps); 2081 handleStyles.save.apply(handleStyles, movableProps); 2082 2083 // Set required styles 2084 var $movables = $handle; 2085 if (!parallax) { 2086 $movables = $movables.add($slidee); 2087 $frame.css('overflow', 'hidden'); 2088 if (!transform && $frame.css('position') === 'static') { 2089 $frame.css('position', 'relative'); 2090 } 2091 } 2092 if (transform) { 2093 if (gpuAcceleration) { 2094 $movables.css(transform, gpuAcceleration); 2095 } 2096 } else { 2097 if ($sb.css('position') === 'static') { 2098 $sb.css('position', 'relative'); 2099 } 2100 $movables.css({ position: 'absolute' }); 2101 } 2102 2103 // Navigation buttons 2104 if (o.forward) { 2105 $forwardButton.on(mouseDownEvent, buttonsHandler); 2106 } 2107 if (o.backward) { 2108 $backwardButton.on(mouseDownEvent, buttonsHandler); 2109 } 2110 if (o.prev) { 2111 $prevButton.on(clickEvent, buttonsHandler); 2112 } 2113 if (o.next) { 2114 $nextButton.on(clickEvent, buttonsHandler); 2115 } 2116 if (o.prevPage) { 2117 $prevPageButton.on(clickEvent, buttonsHandler); 2118 } 2119 if (o.nextPage) { 2120 $nextPageButton.on(clickEvent, buttonsHandler); 2121 } 2122 2123 // Scrolling navigation 2124 $scrollSource.on(wheelEvent, scrollHandler); 2125 2126 // Clicking on scrollbar navigation 2127 if ($sb[0]) { 2128 $sb.on(clickEvent, scrollbarHandler); 2129 } 2130 2131 // Click on items navigation 2132 if (itemNav && o.activateOn) { 2133 $frame.on(o.activateOn + '.' + namespace, '*', activateHandler); 2134 } 2135 2136 // Pages navigation 2137 if ($pb[0] && o.activatePageOn) { 2138 $pb.on(o.activatePageOn + '.' + namespace, '*', activatePageHandler); 2139 } 2140 2141 // Dragging navigation 2142 $dragSource.on(dragInitEvents, { source: 'slidee' }, dragInit); 2143 2144 // Scrollbar dragging navigation 2145 if ($handle) { 2146 $handle.on(dragInitEvents, { source: 'handle' }, dragInit); 2147 } 2148 2149 // Keyboard navigation 2150 $doc.on('keydown', keyboardHandler); 2151 2152 if (!parallax) { 2153 // Pause on hover 2154 $frame.on('mouseenter.' + namespace + ' mouseleave.' + namespace, pauseOnHoverHandler); 2155 // Reset native FRAME element scroll 2156 $frame.on('scroll.' + namespace, resetScroll); 2157 } 2158 2159 // Mark instance as initialized 2160 self.initialized = 1; 2161 2162 // Load 2163 load(true); 2164 2165 // Initiate automatic cycling 2166 if (o.cycleBy && !parallax) { 2167 self[o.startPaused ? 'pause' : 'resume'](); 2168 } 2169 2170 // Return instance 2171 return self; 2172 }; 2173 } 2174 2175 Sly.getInstance = function (element) { 2176 return $.data(element, namespace); 2177 }; 2178 2179 Sly.storeInstance = function (element, sly) { 2180 return $.data(element, namespace, sly); 2181 }; 2182 2183 Sly.removeInstance = function (element) { 2184 return $.removeData(element, namespace); 2185 }; 2186 2187 /** 2188 * Return type of the value. 2189 * 2190 * @param {Mixed} value 2191 * 2192 * @return {String} 2193 */ 2194 function type(value) { 2195 if (value == null) { 2196 return String(value); 2197 } 2198 2199 if (typeof value === 'object' || typeof value === 'function') { 2200 return Object.prototype.toString.call(value).match(/\s([a-z]+)/i)[1].toLowerCase() || 'object'; 2201 } 2202 2203 return typeof value; 2204 } 2205 2206 /** 2207 * Event preventDefault & stopPropagation helper. 2208 * 2209 * @param {Event} event Event object. 2210 * @param {Bool} noBubbles Cancel event bubbling. 2211 * 2212 * @return {Void} 2213 */ 2214 function stopDefault(event, noBubbles) { 2215 event.preventDefault(); 2216 if (noBubbles) { 2217 event.stopPropagation(); 2218 } 2219 } 2220
2221 /** 2222 * Disables an event it was triggered on and unbinds itself. 2223 * 2224 * @param {Event} event 2225 * 2226 * @return {Void} 2227 */ 2228 function disableOneEvent(event) { 2229 /*jshint validthis:true */ 2230 stopDefault(event, 1); 2231 $(this).off(event.type, disableOneEvent); 2232 } 2233 2234 /** 2235 * Resets native element scroll values to 0. 2236 * 2237 * @return {Void} 2238 */ 2239 function resetScroll() { 2240 /*jshint validthis:true */ 2241 this.scrollLeft = 0; 2242 this.scrollTop = 0; 2243 } 2244 2245 /** 2246 * Check if variable is a number. 2247 * 2248 * @param {Mixed} value 2249 * 2250 * @return {Boolean} 2251 */ 2252 function isNumber(value) { 2253 return !isNaN(parseFloat(value)) && isFinite(value); 2254 } 2255 2256 /** 2257 * Parse style to pixels. 2258 * 2259 * @param {Object} $item jQuery object with element. 2260 * @param {Property} property CSS property to get the pixels from. 2261 * 2262 * @return {Int} 2263 */ 2264 function getPx($item, property) { 2265 return 0 | round(String($item.css(property)).replace(/[^\-0-9.]/g, '')); 2266 } 2267 2268 /** 2269 * Make sure that number is within the limits. 2270 * 2271 * @param {Number} number 2272 * @param {Number} min 2273 * @param {Number} max 2274 * 2275 * @return {Number} 2276 */ 2277 function within(number, min, max) { 2278 return number < min ? min : number > max ? max : number; 2279 } 2280 2281 /** 2282 * Saves element styles for later restoration. 2283 * 2284 * Example: 2285 * var styles = new StyleRestorer(frame); 2286 * styles.save('position'); 2287 * element.style.position = 'absolute'; 2288 * styles.restore(); // restores to state before the assignment above 2289 * 2290 * @param {Element} element 2291 */ 2292 function StyleRestorer(element) { 2293 var self = {}; 2294 self.style = {}; 2295 self.save = function () { 2296 if (!element || !element.nodeType) return; 2297 for (var i = 0; i < arguments.length; i++) { 2298 self.style[arguments[i]] = element.style[arguments[i]]; 2299 } 2300 return self; 2301 }; 2302 self.restore = function () { 2303 if (!element || !element.nodeType) return; 2304 for (var prop in self.style) { 2305 if (self.style.hasOwnProperty(prop)) element.style[prop] = self.style[prop]; 2306 } 2307 return self; 2308 }; 2309 return self; 2310 } 2311 2312 // Local WindowAnimationTiming interface polyfill 2313 (function (w) { 2314 rAF = w.requestAnimationFrame 2315 || w.webkitRequestAnimationFrame 2316 || fallback; 2317 2318 /** 2319 * Fallback implementation. 2320 */ 2321 var prev = new Date().getTime(); 2322 function fallback(fn) { 2323 var curr = new Date().getTime(); 2324 var ms = Math.max(0, 16 - (curr - prev)); 2325 var req = setTimeout(fn, ms); 2326 prev = curr; 2327 return req; 2328 } 2329 2330 /** 2331 * Cancel. 2332 */ 2333 var cancel = w.cancelAnimationFrame 2334 || w.webkitCancelAnimationFrame 2335 || w.clearTimeout; 2336 2337 cAF = function(id){ 2338 cancel.call(w, id); 2339 }; 2340 }(window)); 2341 2342 // Feature detects 2343 (function () { 2344 var prefixes = ['', 'Webkit', 'Moz', 'ms', 'O']; 2345 var el = document.createElement('div'); 2346 2347 function testProp(prop) { 2348 for (var p = 0, pl = prefixes.length; p < pl; p++) { 2349 var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop; 2350 if (el.style[prefixedProp] != null) { 2351 return prefixedProp; 2352 } 2353 } 2354 } 2355 2356 // Global support indicators 2357 transform = testProp('transform'); 2358 gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : ''; 2359 }()); 2360 2361 // Expose class globally 2362 w[className] = Sly; 2363 2364 // jQuery proxy 2365 $.fn[pluginName] = function (options, callbackMap) { 2366 var method, methodArgs; 2367 2368 // Attributes logic 2369 if (!$.isPlainObject(options)) { 2370 if (type(options) === 'string' || options === false) { 2371 method = options === false ? 'destroy' : options; 2372 methodArgs = Array.prototype.slice.call(arguments, 1); 2373 } 2374 options = {}; 2375 } 2376 2377 // Apply to all elements 2378 return this.each(function (i, element) { 2379 // Call with prevention against multiple instantiations 2380 var plugin = Sly.getInstance(element); 2381 2382 if (!plugin && !method) { 2383 // Create a new object if it doesn't exist yet 2384 plugin = new Sly(element, options, callbackMap).init(); 2385 } else if (plugin && method) { 2386 // Call method 2387 if (plugin[method]) { 2388 plugin[method].apply(plugin, methodArgs); 2389 } 2390 } 2391 }); 2392 }; 2393 2394 // Default options 2395 Sly.defaults = { 2396 slidee: null, // Selector, DOM element, or jQuery object with DOM element representing SLIDEE. 2397 horizontal: false, // Switch to horizontal mode. 2398 2399 // Item based navigation 2400 itemNav: null, // Item navigation type. Can be: 'basic', 'centered', 'forceCentered'. 2401 itemSelector: null, // Select only items that match this selector. 2402 smart: false, // Repositions the activated item to help with further navigation. 2403 activateOn: null, // Activate an item on this event. Can be: 'click', 'mouseenter', ... 2404 activateMiddle: false, // Always activate the item in the middle of the FRAME. forceCentered only. 2405 2406 // Scrolling 2407 scrollSource: null, // Element for catching the mouse wheel scrolling. Default is FRAME. 2408 scrollBy: 0, // Pixels or items to move per one mouse scroll. 0 to disable scrolling. 2409 scrollHijack: 300, // Milliseconds since last wheel event after which it is acceptable to hijack global scroll. 2410 scrollTrap: false, // Don't bubble scrolling when hitting scrolling limits. 2411 2412 // Dragging 2413 dragSource: null, // Selector or DOM element for catching dragging events. Default is FRAME. 2414 mouseDragging: false, // Enable navigation by dragging the SLIDEE with mouse cursor. 2415 touchDragging: false, // Enable navigation by dragging the SLIDEE with touch events. 2416 releaseSwing: false, // Ease out on dragging swing release. 2417 swingSpeed: 0.2, // Swing synchronization speed, where: 1 = instant, 0 = infinite. 2418 elasticBounds: false, // Stretch SLIDEE position limits when dragging past FRAME boundaries. 2419 dragThreshold: 3, // Distance in pixels before Sly recognizes dragging. 2420 interactive: null, // Selector for special interactive elements. 2421 2422 // Scrollbar 2423 scrollBar: null, // Selector or DOM element for scrollbar container. 2424 dragHandle: false, // Whether the scrollbar handle should be draggable. 2425 dynamicHandle: false, // Scrollbar handle represents the ratio between hidden and visible content. 2426 minHandleSize: 50, // Minimal height or width (depends on sly direction) of a handle in pixels. 2427 clickBar: false, // Enable navigation by clicking on scrollbar. 2428 syncSpeed: 0.5, // Handle =>
2428 SLIDEE synchronization speed, where: 1 = instant, 0 = infinite. 2429 2430 // Pagesbar 2431 pagesBar: null, // Selector or DOM element for pages bar container. 2432 activatePageOn: null, // Event used to activate page. Can be: click, mouseenter, ... 2433 pageBuilder: // Page item generator. 2434 function (index) { 2435 return '<li>' + (index + 1) + '</li>'; 2436 }, 2437 2438 // Navigation buttons 2439 forward: null, // Selector or DOM element for "forward movement" button. 2440 backward: null, // Selector or DOM element for "backward movement" button. 2441 prev: null, // Selector or DOM element for "previous item" button. 2442 next: null, // Selector or DOM element for "next item" button. 2443 prevPage: null, // Selector or DOM element for "previous page" button. 2444 nextPage: null, // Selector or DOM element for "next page" button. 2445 2446 // Automated cycling 2447 cycleBy: null, // Enable automatic cycling by 'items' or 'pages'. 2448 cycleInterval: 5000, // Delay between cycles in milliseconds. 2449 pauseOnHover: false, // Pause cycling when mouse hovers over the FRAME. 2450 startPaused: false, // Whether to start in paused sate. 2451 2452 // Mixed options 2453 moveBy: 300, // Speed in pixels per second used by forward and backward buttons. 2454 speed: 0, // Animations speed in milliseconds. 0 to disable animations. 2455 easing: 'swing', // Easing for duration based (tweening) animations. 2456 startAt: null, // Starting offset in pixels or items. 2457 keyboardNavBy: null, // Enable keyboard navigation by 'items' or 'pages'. 2458 2459 // Classes 2460 draggedClass: 'dragged', // Class for dragged elements (like SLIDEE or scrollbar handle). 2461 activeClass: 'active', // Class for active items and pages. 2462 disabledClass: 'disabled' // Class for disabled navigation elements. 2463 }; 2464}(jQuery, window)); 2465 2466// ==================== horisontal.js ================ 2467jQuery(function($){ 2468 'use strict'; 2469 2470 // ------------------------------------------------------------- 2471 // Basic Navigation 2472 // ------------------------------------------------------------- 2473 (function () { 2474 var $frame = $('#basic'); 2475 var $slidee = $frame.children('ul').eq(0); 2476 var $wrap = $frame.parent(); 2477 2478 // Call Sly on frame 2479 $frame.sly({ 2480 horizontal: 1, 2481 itemNav: 'basic', 2482 smart: 1, 2483 activateOn: 'click', 2484 mouseDragging: 1, 2485 touchDragging: 1, 2486 releaseSwing: 1, 2487 startAt: 3, 2488 scrollBar: $wrap.find('.scrollbar'), 2489 scrollBy: 1, 2490 pagesBar: $wrap.find('.pages'), 2491 activatePageOn: 'click', 2492 speed: 300, 2493 elasticBounds: 1, 2494 easing: 'easeOutExpo', 2495 dragHandle: 1, 2496 dynamicHandle: 1, 2497 clickBar: 1, 2498 2499 // Buttons 2500 forward: $wrap.find('.forward'), 2501 backward: $wrap.find('.backward'), 2502 prev: $wrap.find('.prev'), 2503 next: $wrap.find('.next'), 2504 prevPage: $wrap.find('.prevPage'), 2505 nextPage: $wrap.find('.nextPage') 2506 }); 2507 2508 // To Start button 2509 $wrap.find('.toStart').on('click', function () { 2510 var item = $(this).data('item'); 2511 // Animate a particular item to the start of the frame. 2512 // If no item is provided, the whole content will be animated. 2513 $frame.sly('toStart', item); 2514 }); 2515 2516 // To Center button 2517 $wrap.find('.toCenter').on('click', function () { 2518 var item = $(this).data('item'); 2519 // Animate a particular item to the center of the frame. 2520 // If no item is provided, the whole content will be animated. 2521 $frame.sly('toCenter', item); 2522 }); 2523 2524 // To End button 2525 $wrap.find('.toEnd').on('click', function () { 2526 var item = $(this).data('item'); 2527 // Animate a particular item to the end of the frame. 2528 // If no item is provided, the whole content will be animated. 2529 $frame.sly('toEnd', item); 2530 }); 2531 2532 // Add item 2533 $wrap.find('.add').on('click', function () { 2534 $frame.sly('add', '<li>' + $slidee.children().length + '</li>'); 2535 }); 2536 2537 // Remove item 2538 $wrap.find('.remove').on('click', function () { 2539 $frame.sly('remove', -1); 2540 }); 2541 }()); 2542 2543 // ------------------------------------------------------------- 2544 // Centered Navigation 2545 // ------------------------------------------------------------- 2546 (function () { 2547 var $frame = $('#centered'); 2548 var $wrap = $frame.parent(); 2549 2550 // Call Sly on frame 2551 $frame.sly({ 2552 horizontal: 1, 2553 itemNav: 'centered', 2554 smart: 1, 2555 activateOn: 'click', 2556 mouseDragging: 1, 2557 touchDragging: 1, 2558 releaseSwing: 1, 2559 startAt: 4, 2560 scrollBar: $wrap.find('.scrollbar'), 2561 scrollBy: 1, 2562 speed: 300, 2563 elasticBounds: 1, 2564 easing: 'easeOutExpo', 2565 dragHandle: 1, 2566 dynamicHandle: 1, 2567 clickBar: 1, 2568 2569 // Buttons 2570 prev: $wrap.find('.prev'), 2571 next: $wrap.find('.next') 2572 }); 2573 }()); 2574 2575 // ------------------------------------------------------------- 2576 // Force Centered Navigation 2577 // ------------------------------------------------------------- 2578 (function () { 2579 var $frame = $('#forcecentered'); 2580 var $wrap = $frame.parent(); 2581 2582 // Call Sly on frame 2583 $frame.sly({ 2584 horizontal: 1, 2585 itemNav: 'forceCentered', 2586 smart: 1, 2587 activateMiddle: 1, 2588 activateOn: 'click', 2589 mouseDragging: 1, 2590 touchDragging: 1, 2591 releaseSwing: 1, 2592 startAt: 2, 2593 scrollBar: $wrap.find('.scrollbar'), 2594 scrollBy: 1, 2595 speed: 300, 2596 elasticBounds: 1, 2597 easing: 'easeOutExpo', 2598 dragHandle: 1, 2599 dynamicHandle: 1, 2600 clickBar: 1, 2601 2602 // Buttons 2603 prev: $wrap.find('.prev'), 2604 next: $wrap.find('.next') 2605 }); 2606 }()); 2607 2608 // ------------------------------------------------------------- 2609 // Cycle By Items 2610 // ------------------------------------------------------------- 2611 (function () { 2612 var $frame = $('#cycleitems'); 2613 var $wrap = $frame.parent(); 2614 2615 // Call Sly on frame 2616 $frame.sly({ 2617 horizontal: 1, 2618 itemNav: 'basic', 2619 smart: 1, 2620 activateOn: 'click', 2621 mouseDragging: 1, 2622 touchDragging: 1, 2623 releaseSwing: 1, 2624 startAt: 0, 2625 scrollBar: $wrap.find('.scrollbar'), 2626 scrollBy: 1, 2627 speed: 300, 2628 elasticBounds: 1, 2629 easing: 'easeOutExpo', 2630 dragHandle: 1, 2631 dynamicHandle: 1, 2632 clickBar: 1, 2633 2634 // Cycling 2635 cycleBy: 'items', 2636 cycleInterval: 1000, 2637 pauseOnHover: 1, 2638 2639 // Buttons 2640 prev: $wrap.find('.prev'), 2641 next: $wrap.find('.next') 2642 }); 2643 2644 // Pause button 2645 $wrap.find('.pause').on('click', function () { 2646 $frame.sly('pause'); 2647 }); 2648 2649 // Resume button 2650 $wrap.find('.resume').on('click', function () { 2651 $frame.sly('resume'); 2652 }); 2653 2654 // Toggle button 2655 $wrap.find('.toggle').on('click', function () { 2656 $frame.sly('toggle'); 2657 }); 2658 }()); 2659 2660 // ------------------------------------------------------------- 2661 // Cycle By Pages 2662 // ------------------------------------------------------------- 2663 (function () { 2664 var $frame = $('#cyclepages'); 2665 var $wrap = $frame.parent(); 2666 2667 // Call Sly on frame 2668 $frame.sly({ 2669 horizontal: 1, 2670 itemNav: 'basic', 2671 smart: 1, 2672 activateOn: 'click', 2673 mouseDragging: 1, 2674 touchDragging: 1, 2675 releaseSwing: 1, 2676 startAt: 0, 2677 scrollBar: $wrap.find('.scrollbar'), 2678 scrollBy: 1, 2679 pagesBar: $wrap.find('.pages'), 2680 activatePageOn: 'click', 2681 speed: 300, 2682 elasticBounds: 1, 2683 easing: 'easeOutExpo', 2684 dragHandle: 1, 2685 dynamicHandle: 1, 2686 clickBar: 1, 2687 2688 // Cycling 2689 cycleBy: 'pages', 2690 cycleInterval: 1000, 2691 pauseOnHover: 1, 2692 startPaused: 1, 2693 2694 // Buttons 2695 prevPage: $wrap.find('.prevPage'), 2696 nextPage: $wrap.find('.nextPage') 2697 }); 2698 2699 // Pause button 2700 $wrap.find('.pause').on('click', function () { 2701 $frame.sly('pause'); 2702 }); 2703 2704 // Resume button 2705 $wrap.find('.resume').on('click', function () { 2706 $frame.sly('resume'); 2707 }); 2708 2709 // Toggle button 2710 $wrap.find('.toggle').on('click', function () { 2711 $frame.sly('toggle'); 2712 }); 2713 }()); 2714 2715 // ------------------------------------------------------------- 2716 // One Item Per Frame 2717 // ------------------------------------------------------------- 2718 (function () { 2719 var $frame = $('#oneperframe'); 2720 var $wrap = $frame.parent(); 2721 2722 // Call Sly on frame 2723 $frame.sly({ 2724 horizontal: 1, 2725 itemNav: 'forceCentered', 2726 smart: 1, 2727 activateMiddle: 1, 2728 mouseDragging: 1, 2729 touchDragging: 1, 2730 releaseSwing: 1, 2731 startAt: 0, 2732 scrollBar: $wrap.find('.scrollbar'), 2733 scrollBy: 1, 2734 speed: 300, 2735 elasticBounds: 1, 2736 easing: 'easeOutExpo', 2737 dragHandle: 1, 2738 dynamicHandle: 1, 2739 clickBar: 1, 2740 2741 // Buttons 2742 prev: $wrap.find('.prev'), 2743 next: $wrap.find('.next') 2744 }); 2745 }()); 2746 2747 // ------------------------------------------------------------- 2748 // Crazy 2749 // ------------------------------------------------------------- 2750 (function () { 2751 var $frame = $('#crazy'); 2752 var $slidee = $frame.children('ul').eq(0); 2753 var $wrap = $frame.parent(); 2754 2755 // Call Sly on frame 2756 $frame.sly({ 2757 horizontal: 1, 2758 itemNav: 'basic', 2759 smart: 1, 2760 activateOn: 'click', 2761 mouseDragging: 1, 2762 touchDragging: 1, 2763 releaseSwing: 1, 2764 startAt: 3, 2765 scrollBar: $wrap.find('.scrollbar'), 2766 scrollBy: 1, 2767 pagesBar: $wrap.find('.pages'), 2768 activatePageOn: 'click', 2769 speed: 300, 2770 elasticBounds: 1, 2771 easing: 'easeOutExpo', 2772 dragHandle: 1, 2773 dynamicHandle: 1, 2774 clickBar: 1, 2775 2776 // Buttons 2777 forward: $wrap.find('.forward'), 2778 backward: $wrap.find('.backward'), 2779 prev: $wrap.find('.prev'), 2780 next: $wrap.find('.next'), 2781 prevPage: $wrap.find('.prevPage'), 2782 nextPage: $wrap.find('.nextPage') 2783 }); 2784 2785 // To Start button 2786 $wrap.find('.toStart').on('click', function () { 2787 var item = $(this).data('item'); 2788 // Animate a particular item to the start of the frame. 2789 // If no item is provided, the whole content will be animated. 2790 $frame.sly('toStart', item); 2791 }); 2792 2793 // To Center button 2794 $wrap.find('.toCenter').on('click', function () { 2795 var item = $(this).data('item'); 2796 // Animate a particular item to the center of the frame. 2797 // If no item is provided, the whole content will be animated. 2798 $frame.sly('toCenter', item); 2799 }); 2800 2801 // To End button 2802 $wrap.find('.toEnd').on('click', function () { 2803 var item = $(this).data('item'); 2804 // Animate a particular item to the end of the frame. 2805 // If no item is provided, the whole content will be animated. 2806 $frame.sly('toEnd', item); 2807 }); 2808 2809 // Add item 2810 $wrap.find('.add').on('click', function () { 2811 $frame.sly('add', '<li>' + $slidee.children().length + '</li>'); 2812 }); 2813 2814 // Remove item 2815 $wrap.find('.remove').on('click', function () { 2816 $frame.sly('remove', -1); 2817 }); 2818 }()); 2819});
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.