1/* 2== malihu jquery thumbnail scroller plugin == 3Version: 2.0.3 4Plugin URI: http://manos.malihu.gr/jquery-thumbnail-scroller 5Author: malihu 6Author URI: http://manos.malihu.gr 7License: MIT License (MIT) 8*/ 9 10/* 11Copyright 2010 Manos Malihutsakis (email: [email protected]) 12 13Permission is hereby granted, free of charge, to any person obtaining a copy 14of this software and associated documentation files (the "Software"), to deal 15in the Software without restriction, including without limitation the rights 16to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17copies of the Software, and to permit persons to whom the Software is 18furnished to do so, subject to the following conditions: 19 20The above copyright notice and this permission notice shall be included in 21all copies or substantial portions of the Software. 22 23THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29THE SOFTWARE. 30*/ 31 32/* 33The code below is fairly long, fully commented and should be normally used in development. 34For production, use the minified jquery.mThumbnailScroller.min.js script. 35*/ 36 37;(function($,window,document){ 38 39 /* 40 ---------------------------------------- 41 PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) 42 ---------------------------------------- 43 */ 44 45 var pluginNS="mThumbnailScroller", 46 pluginPfx="mTS", 47 defaultSelector=".mThumbnailScroller", 48 49 50 51 52 53 /* 54 ---------------------------------------- 55 DEFAULT OPTIONS 56 ---------------------------------------- 57 */ 58 59 defaults={ 60 /* 61 set element/content width/height programmatically 62 values: boolean, pixels, percentage 63 option default 64 ------------------------------------- 65 setWidth false 66 setHeight false 67 */ 68 /* 69 set the initial css top property of content 70 values: string (e.g. "-100px", "10%" etc.) 71 */ 72 setTop:0, 73 /* 74 set the initial css left property of content 75 values: string (e.g. "-100px", "10%" etc.) 76 */ 77 setLeft:0, 78 /* 79 set the scrolling type 80 values (string): "hover-0"/"hover-100" (number indicating percentage), "hover-precise", "click-0"/"click-100" (number indicating percentage), "click-thumb" 81 */ 82 type:"hover-50", 83 /* 84 scroller axis (vertical and/or horizontal) 85 values (string): "y", "x", "yx" 86 */ 87 axis:"x", 88 /* 89 scrolling speed 90 values: integer (higher=faster) 91 */ 92 speed:15, 93 /* 94 enable content touch-swipe scrolling 95 values: boolean, integer, string (number) 96 integer values define the axis-specific minimum amount required for scrolling momentum 97 */ 98 contentTouchScroll:25, 99 /* 100 markup option parameters 101 */ 102 markup:{ 103 /* 104 thumbnailsContainer sets the element containing your thumbnails. By default this is an unordered list ("ul") 105 thumbnailContainer sets the element containing each thumbnail. By default this is a list-item ("li") 106 thumbnailElement sets the actual thumbnail element. By default this is an image tag ("img") 107 values: boolean, string 108 option default 109 ------------------------------------- 110 thumbnailsContainer null 111 thumbnailContainer null 112 thumbnailElement null 113 114 */ 115 /* 116 set the placeholder element of the buttons 117 values: boolean, string 118 */ 119 buttonsPlaceholder:false, 120 /* 121 set buttons HTML 122 */ 123 buttonsHTML:{ 124 up:"SVG set 1", 125 down:"SVG set 1", 126 left:"SVG set 1", 127 right:"SVG set 1" 128 } 129 }, 130 /* 131 advanced option parameters 132 */ 133 advanced:{ 134 /* 135 auto-expand content horizontally (for "x" or "yx" axis) 136 values: boolean 137 */ 138 autoExpandHorizontalScroll:true, 139 /* 140 auto-update scrollers on content, element or viewport resize 141 should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. 142 values: boolean 143 */ 144 updateOnContentResize:true, 145 /* 146 auto-update scrollers each time each image inside the element is fully loaded 147 values: boolean 148 */ 149 updateOnImageLoad:true 150 /* 151 auto-update scrollers based on the amount and size changes of specific selectors 152 useful when you need to update the scroller(s) automatically, each time a type of element is added, removed or changes its size 153 values: boolean, string (e.g. "ul li" will auto-update the scroller each time list-items inside the element are changed) 154 a value of true (boolean) will auto-update the scroller each time any element is changed 155 option default 156 ------------------------------------- 157 updateOnSelectorChange null 158 */ 159 }, 160 /* 161 scroller theme 162 values: string 163 */ 164 theme:"none", 165 /* 166 user defined callback functions 167 */ 168 callbacks:{ 169 /* 170 Available callbacks: 171 callback default 172 ------------------------------------- 173 onInit null 174 onScrollStart null 175 onScroll null 176 onTotalScroll null 177 onTotalScrollBack null 178 whileScrolling null 179 */ 180 onTotalScrollOffset:0, 181 onTotalScrollBackOffset:0, 182 alwaysTriggerOffsets:true 183 } 184 /* 185 add scroller(s) on all elements matching the current selector, now and in the future 186 values: boolean, string 187 string values: "on" (enable), "once" (disable after first invocation), "off" (disable) 188 liveSelector values: string (selector) 189 option default 190 ------------------------------------- 191 live false 192 liveSelector null 193 */ 194 }, 195 196 197 198 199 200 /* 201 ---------------------------------------- 202 VARS, CONSTANTS
203 ---------------------------------------- 204 */ 205 206 totalInstances=0, /* plugin instances amount */ 207 liveTimers={}, /* live option timers */ 208 oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */ 209 touchActive=false, /* global touch state (for touch and pointer events) */ 210 touchi, /* touch interface */ 211 /* general plugin classes */ 212 classes=["mTS_disabled","mTS_destroyed","mTS_no_scroll"], 213 214 215 216 217 218 /* 219 ---------------------------------------- 220 METHODS 221 ---------------------------------------- 222 */ 223 224 methods={ 225 226 /* 227 plugin initialization method 228 creates the scroller(s), plugin data object and options 229 ---------------------------------------- 230 */ 231 232 init:function(options){ 233 234 var options=$.extend(true,{},defaults,options), 235 selector=_selector.call(this); /* validate selector */ 236 237 /* 238 if live option is enabled, monitor for elements matching the current selector and 239 apply scroller(s) when found (now and in the future) 240 */ 241 if(options.live){ 242 var liveSelector=options.liveSelector || this.selector || defaultSelector, /* live selector(s) */ 243 $liveSelector=$(liveSelector); /* live selector(s) as jquery object */ 244 if(options.live==="off"){ 245 /* 246 disable live if requested 247 usage: $(selector).mThumbnailScroller({live:"off"}); 248 */ 249 removeLiveTimers(liveSelector); 250 return; 251 } 252 liveTimers[liveSelector]=setTimeout(function(){ 253 /* call mThumbnailScroller fn on live selector(s) every half-second */ 254 $liveSelector.mThumbnailScroller(options); 255 if(options.live==="once" && $liveSelector.length){ 256 /* disable live after first invocation */ 257 removeLiveTimers(liveSelector); 258 } 259 },500); 260 }else{ 261 removeLiveTimers(liveSelector); 262 } 263 264 /* options normalization */ 265 options.speed=options.speed===0 ? 100 : options.speed; 266 267 _theme(options); /* theme-specific options */ 268 269 /* plugin constructor */ 270 return $(selector).each(function(){ 271 272 var $this=$(this); 273 274 if(!$this.data(pluginPfx)){ /* prevent multiple instantiations */ 275 276 /* store options and create objects in jquery data */ 277 $this.data(pluginPfx,{ 278 idx:++totalInstances, /* instance index */ 279 opt:options, /* options */ 280 html:null, /* element original html */ 281 overflowed:null, /* overflowed axis */ 282 bindEvents:false, /* object to check if events are bound */ 283 tweenRunning:false, /* object to check if tween is running */ 284 langDir:$this.css("direction"), /* detect/store direction (ltr or rtl) */ 285 cbOffsets:null, /* object to check whether callback offsets always trigger */ 286 /* 287 object to check how scrolling events where last triggered 288 "internal" (default - triggered by this script), "external" (triggered by other scripts, e.g. via scrollTo method) 289 usage: object.data("mTS").trigger 290 */ 291 trigger:null 292 }); 293 294 /* HTML data attributes */ 295 var o=$this.data(pluginPfx).opt, 296 htmlDataAxis=$this.data("mts-axis"),htmlDataType=$this.data("mts-type"),htmlDataTheme=$this.data("mts-theme"); 297 if(htmlDataAxis){o.axis=htmlDataAxis;} /* usage example: data-mts-axis="y" */ 298 if(htmlDataType){o.type=htmlDataType;} /* usage example: data-mts-type="hover-50" */ 299 if(htmlDataTheme){ /* usage example: data-mts-theme="theme-name" */ 300 o.theme=htmlDataTheme; 301 _theme(o); /* theme-specific options */ 302 } 303 304 _pluginMarkup.call(this); /* add plugin markup */ 305 306 methods.update.call(null,$this); /* call the update method */ 307 308 } 309 310 }); 311 312 }, 313 /* ---------------------------------------- */ 314 315 316 317 /* 318 plugin update method 319 updates content and scroller values, events and status 320 ---------------------------------------- 321 usage: $(selector).mThumbnailScroller("update"); 322 */ 323 324 update:function(el){ 325 326 var selector=el || _selector.call(this); /* validate selector */ 327 328 return $(selector).each(function(){ 329 330 var $this=$(this); 331 332 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 333 334 var d=$this.data(pluginPfx),o=d.opt, 335 mTS_container=$("#mTS_"+d.idx+"_container"); 336 337 if(!mTS_container.length){return;} 338 339 if(d.tweenRunning){_stop($this);} /* stop any running tweens while updating */ 340 341 /* if element was disabled or destroyed, remove class(es) */
342 if($this.hasClass(classes[0])){$this.removeClass(classes[0]);} 343 if($this.hasClass(classes[1])){$this.removeClass(classes[1]);} 344 345 _maxHeight.call(this); /* detect/set css max-height value */ 346 347 _expandContentHorizontally.call(this); /* expand content horizontally */ 348 349 d.overflowed=_overflowed.call(this); /* determine if scrolling is required */ 350 351 _buttonsVisibility.call(this); /* show/hide buttons */ 352 353 _bindEvents.call(this); /* bind scroller events */ 354 355 /* reset scrolling position and/or events */ 356 var to=[(mTS_container[0].offsetTop),(mTS_container[0].offsetLeft)]; 357 if(o.axis!=="x"){ /* y/yx axis */ 358 if(!d.overflowed[0]){ /* y scrolling is not required */ 359 _resetContentPosition.call(this); /* reset content position */ 360 if(o.axis==="y"){ 361 _scrollTo($this,"0",{dir:"y",dur:0,overwrite:"none"}); 362 _unbindEvents.call(this); 363 }else if(o.axis==="yx" && d.overflowed[1]){ 364 _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); 365 } 366 }else{ /* y scrolling is required */ 367 _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); 368 } 369 } 370 if(o.axis!=="y"){ /* x/yx axis */ 371 if(!d.overflowed[1]){ /* x scrolling is not required */ 372 _resetContentPosition.call(this); /* reset content position */ 373 if(o.axis==="x"){ 374 _scrollTo($this,"0",{dir:"x",dur:0,overwrite:"none"}); 375 _unbindEvents.call(this); 376 }else if(o.axis==="yx" && d.overflowed[0]){ 377 _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); 378 } 379 }else{ /* x scrolling is required */ 380 _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); 381 } 382 } 383 384 /* no scroll class */ 385 if(!d.overflowed[0] && !d.overflowed[1]){
386 $this.addClass(classes[2]); 387 }else{ 388 $this.removeClass(classes[2]); 389 } 390 391 _autoUpdate.call(this); /* initialize automatic updating (for dynamic content, fluid layouts etc.) */ 392 393 } 394 395 }); 396 397 }, 398 /* ---------------------------------------- */ 399 400 401 402 /* 403 plugin scrollTo method 404 triggers a scrolling event to a specific value 405 ---------------------------------------- 406 usage: $(selector).mThumbnailScroller("scrollTo",value,options); 407 */ 408 409 scrollTo:function(val,options){ 410 411 /* prevent silly things like $(selector).mThumbnailScroller("scrollTo",undefined); */ 412 if(typeof val=="undefined" || val==null){return;} 413 414 var selector=_selector.call(this); /* validate selector */ 415 416 return $(selector).each(function(){ 417 418 var $this=$(this); 419 420 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 421 422 var d=$this.data(pluginPfx),o=d.opt, 423 /* method default options */ 424 methodDefaults={ 425 trigger:"external", /* method is by default triggered externally (e.g. from other scripts) */ 426 speed:o.speed, /* scrolling speed */ 427 duration:1000, /* animation duration */ 428 easing:"easeInOut", /* animation easing */ 429 timeout:60, /* scroll-to delay */ 430 callbacks:true, /* enable/disable callbacks */ 431 onStart:true, 432 onUpdate:true, 433 onComplete:true 434 }, 435 methodOptions=$.extend(true,{},methodDefaults,options), 436 to=_arr.call(this,val),dur=methodOptions.duration ? methodOptions.duration : 7000/(methodOptions.speed || 1); 437 438 /* translate yx values to actual scroll-to positions */ 439 to[0]=_to.call(this,to[0],"y"); 440 to[1]=_to.call(this,to[1],"x"); 441 442 methodOptions.dur=dur>0 && dur<17 ? 17 : dur; 443 444 setTimeout(function(){ 445 /* do the scrolling */ 446 if(to[0]!==null && typeof to[0]!=="undefined" && o.axis!=="x" && d.overflowed[0]){ /* scroll y */ 447 methodOptions.dir="y"; 448 methodOptions.overwrite="all"; 449 _scrollTo($this,-to[0].toString(),methodOptions); 450 } 451 if(to[1]!==null && typeof to[1]!=="undefined" && o.axis!=="y" && d.overflowed[1]){ /* scroll x */ 452 methodOptions.dir="x"; 453 methodOptions.overwrite="none"; 454 _scrollTo($this,-to[1].toString(),methodOptions); 455 } 456 },methodOptions.timeout); 457 458 } 459 460 }); 461 462 }, 463 /* ---------------------------------------- */ 464 465 466 467 /* 468 plugin stop method 469 stops scrolling animation 470 ---------------------------------------- 471 usage: $(selector).mThumbnailScroller("stop"); 472 */ 473 stop:function(){ 474 475 var selector=_selector.call(this); /* validate selector */ 476 477 return $(selector).each(function(){ 478 479 var $this=$(this); 480 481 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 482 483 _stop($this); 484 485 } 486 487 }); 488 489 }, 490 /* ---------------------------------------- */ 491 492 493 494 /* 495 plugin disable method 496 temporarily disables the scroller 497 ---------------------------------------- 498 usage: $(selector).mThumbnailScroller("disable",reset); 499 reset (boolean): resets content position to 0 500 */ 501 disable:function(r){ 502 503 var selector=_selector.call(this); /* validate selector */ 504 505 return $(selector).each(function(){ 506 507 var $this=$(this); 508 509 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 510 511 var d=$this.data(pluginPfx),o=d.opt; 512 513 _autoUpdate.call(this,"remove"); /* remove automatic updating */ 514 515 _unbindEvents.call(this); /* unbind events */ 516 517 if(r){_resetContentPosition.call(this);} /* reset content position */ 518 519 _buttonsVisibility.call(this,true); /* show/hide buttons */ 520
vendor: 1,822 bytes, lines 521-569
521 $this.addClass(classes[0]); /* add disable class */ 522 523 } 524 525 }); 526 527 }, 528 /* ---------------------------------------- */ 529 530 531 532 /* 533 plugin destroy method 534 completely removes the scrollber and returns the element to its original state 535 ---------------------------------------- 536 usage: $(selector).mThumbnailScroller("destroy"); 537 */ 538 destroy:function(){ 539 540 var selector=_selector.call(this); /* validate selector */ 541 542 return $(selector).each(function(){ 543 544 var $this=$(this); 545 546 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 547 548 var d=$this.data(pluginPfx),o=d.opt, 549 mTS_wrapper=$("#mTS_"+d.idx), 550 mTS_container=$("#mTS_"+d.idx+"_container"), 551 mTS_buttons=$("#mTS_"+d.idx+"_buttonUp,#mTS_"+d.idx+"_buttonDown,#mTS_"+d.idx+"_buttonLeft,#mTS_"+d.idx+"_buttonRight"); 552 553 if(o.live){removeLiveTimers(selector);} /* remove live timer */ 554 555 _autoUpdate.call(this,"remove"); /* remove automatic updating */ 556 557 _unbindEvents.call(this); /* unbind events */ 558 559 _resetContentPosition.call(this); /* reset content position */ 560 561 $this.removeData(pluginPfx); /* remove plugin data object */ 562 563 _delete(this,"mts"); /* delete callbacks object */ 564 565 /* remove plugin markup */ 566 mTS_buttons.remove(); /* remove buttons first (those can be either inside or outside plugin's inner wrapper) */ 567 mTS_wrapper.replaceWith(d.html); /* replace plugin's inner wrapper with the original content */ 568 /* remove plugin classes from the element and add destroy class */ 569 $this.removeClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" "+pluginPfx+"-"+o.theme+" "+classes[2]+" "+classes[0]).addClass(classe
569s[1]); 570 571 } 572 573 }); 574 575 } 576 /* ---------------------------------------- */ 577 578 }, 579 580 581 582 583 584 /* 585 ---------------------------------------- 586 FUNCTIONS 587 ---------------------------------------- 588 */ 589 590 /* validates selector (if selector is invalid or undefined uses the default one) */ 591 _selector=function(){ 592 return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this; 593 }, 594 /* -------------------- */ 595 596 /* changes options according to theme */ 597 _theme=function(obj){ 598 var buttonsPlaceholderOutside=["buttons-out"], 599 buttonsHtmlSet2=["buttons-in"], 600 buttonsHtmlSet3=["buttons-out"], 601 typeHover85=["hover-classic"], 602 typeHoverPrecise=["hover-full"]; 603 obj.markup.buttonsPlaceholder=$.inArray(obj.theme,buttonsPlaceholderOutside) > -1 ? "outside" : obj.markup.buttonsPlaceholder; 604 obj.markup.buttonsHTML=$.inArray(obj.theme,buttonsHtmlSet2) > -1 ? {up:"SVG set 2",down:"SVG set 2",left:"SVG set 2",right:"SVG set 2"} : $.inArray(obj.theme,buttonsHtmlSet3) > -1 ? {up:"SVG set 3",down:"SVG set 3",left:"SVG set 3",right:"SVG set 3"} : obj.markup.buttonsHTML; 605 obj.type=$.inArray(obj.theme,typeHover85) > -1 ? "hover-85" : $.inArray(obj.theme,typeHoverPrecise) > -1 ? "hover-precise" : obj.type; 606 obj.speed=$.inArray(obj.theme,typeHover85) > -1 ? 60 : $.inArray(obj.theme,typeHoverPrecise) > -1 ? 10 : obj.speed; 607 }, 608 /* -------------------- */ 609 610 611 /* live option timers removal */ 612 removeLiveTimers=function(selector){ 613 if(liveTimers[selector]){ 614 clearTimeout(liveTimers[selector]); 615 _delete(liveTimers,selector); 616 } 617 }, 618 /* -------------------- */ 619 620 621 /* generates plugin markup */ 622 _pluginMarkup=function(){ 623 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 624 wrapperClass=o.axis==="yx" ? "mTS_vertical_horizontal" : o.axis==="x" ? "mTS_horizontal" : "mTS_vertical", 625 thumbsContainer=o.markup.thumbnailsContainer || "ul", 626 thumbContainer=o.markup.thumbnailContainer || "li", 627 thumbElement=o.markup.thumbnailElement || "img"; 628 d.html=$this.children().clone(true,true); /* store element original html to restore when destroy method is called */ 629 if(!$this.find(thumbsContainer).length){ /* create images container automatically if not present */ 630 var thumbsAutoContainer=$this.find("li").length ? "<ul class='"+pluginPfx+"AutoContainer' />" : "<div class='"+pluginPfx+"AutoContainer' />"; 631 $this.wrapInner(thumbsAutoContainer); 632 thumbsContainer="."+pluginPfx+"AutoContainer"; 633 } 634 if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */ 635 if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */ 636 o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "-989999px" : o.setLeft; /* adjust left position for rtl direction */ 637 $this .addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" "+pluginPfx+"-"+o.theme) 638 .find(thumbsContainer).wrap("<div id='mTS_"+d.idx+"' class='mTSWrapper "+wrapperClass+"' />") 639 .addClass(pluginPfx+"Container").attr("id","mTS_"+d.idx+"_container") 640 .css({"position":"relative","top":o.setTop,"left":o.setLeft}) 641 .find(thumbContainer).addClass(pluginPfx+"ThumbContainer") 642 .find(thumbElement).addClass(pluginPfx+"Thumb"); 643 _scrollButtons.call(this); /* add scroller buttons */ 644 }, 645 /* -------------------- */ 646 647 648 /* expands content horizontally */ 649 _expandContentHorizontally=function(){ 650 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 651 mTS_container=$("#mTS_"+d.idx+"_container"); 652 if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){ 653 /* 654 wrap content with an infinite width div and set its position to absolute and width to auto. 655 Setting width to auto before calculating the actual width is important! 656 We must let the browser set the width as browser zoom values are impossible to calculate. 657 */ 658 mTS_container.css({"position":"absolute","width":"auto"}) 659 .wrap("<div class='mTS_h_wrapper' style='position:relative; left:0; width:999999px;' />") 660 .css({ /* set actual width, original position and un-wrap */ 661 /* 662 get the exact width (with decimals) and then round-up.
663 Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width 664 */ 665 "width":(Math.ceil(mTS_container[0].getBoundingClientRect().right)-Math.floor(mTS_container[0].getBoundingClientRect().left)), 666 "position":"relative" 667 }).unwrap(); 668 } 669 }, 670 /* -------------------- */ 671 672 673 /* adds scroller buttons */ 674 _scrollButtons = function () { 675 try { 676 var $this = $(this), d = $this.data(pluginPfx), o = d.opt, 677 placeholder = !o.markup.buttonsPlaceholder ? $("#mTS_" + d.idx) : o.markup.buttonsPlaceholder === "outside" ? $this : $(o.markup.buttonsPlaceholder), 678 btnHTML = [ 679 "<a href='#' id='mTS_" + d.idx + "_buttonUp' class='mTSButton mTSButtonUp'><span class='mTSButtonIconContainer'>" + _scrollButtonsIcons.call(this, "up") + "</span></a>", 680 "<a href='#' id='mTS_" + d.idx + "_buttonDown' class='mTSButton mTSButtonDown'><span class='mTSButtonIconContainer'>" + _scrollButtonsIcons.call(this, "down") + "</span></a>", 681 "<a href='#' id='mTS_" + d.idx + "_buttonLeft' class='mTSButton mTSButtonLeft'><span class='mTSButtonIconContainer'>" + _scrollButtonsIcons.call(this, "left") + "</span></a>", 682 "<a href='#' id='mTS_" + d.idx + "_buttonRight' class='mTSButton mTSButtonRight'><span class='mTSButtonIconContainer'>" + _scrollButtonsIcons.call(this, "right") + "</span></a>" 683 ], 684 btn = [(o.axis === "x" ? btnHTML[2] : btnHTML[0]), (o.axis === "x" ? btnHTML[3] : btnHTML[1])]; 685 if (placeholder.hasClass(pluginNS) && placeholder.css("position") === "static") { /* requires elements with non-static position */ 686 placeholder.css("position", "relative"); 687 } 688 if (o.type.indexOf("click") !== -1) { 689 if (o.axis !== "x") { 690 placeholder.append(btnHTML[0] + btnHTML[1]); 691 } 692 if (o.axis !== "y") { 693 placeholder.append(btnHTML[2] + btnHTML[3]); 694 } 695 } 696 } 697 catch (err) { console.log(err);} 698 }, 699 /* -------------------- */ 700 701 702 /* sets scroller buttons icons */ 703 _scrollButtonsIcons=function(b){ 704 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 705 btn=o.markup.buttonsHTML, 706 i=btn[b]==="SVG set 1" ? 0 : btn[b]==="SVG set 2" ? 1 : btn[b]==="SVG set 3" ? 2 : btn[b]==="SVG set 4" ? 3 : btn[b]==="SVG set 5" ? 4 : null; 707 switch(b){ 708 case "up": 709 return i===null ? btn[b] : oldIE ? "↑" : _icons(btn[b])[i][0]; 710 break; 711 case "down": 712 return i===null ? btn[b] : oldIE ? "↓" : _icons(btn[b])[i][1]; 713 break; 714 case "left": 715 return i===null ? btn[b] : oldIE ? "←" : _icons(btn[b])[i][2]; 716 break; 717 case "right": 718 return i===null ? btn[b] : oldIE ? "→" : _icons(btn[b])[i][3]; 719 break; 720 } 721 }, 722 /* -------------------- */ 723 724 725 /* icons */ 726 _icons=function(){ 727 /* SVG */ 728 var svgo="<svg version='1.1' viewBox='0 0 24 24' preserveAspectRatio='xMinYMin meet' class='mTSButtonIcon'><g><line stroke-width='1' x1='' y1='' x2='' y2='' stroke='#449FDB' opacity=''></line></g>", 729 svgc="</svg>"; 730 return [ 731 /* set 1 */ 732 [svgo+"<path d='M20.561 9.439l-7.5-7.5c-0.586-0.586-1.535-0.586-2.121 0l-7.5 7.5c-0.586 0.586-0.586 1.536 0 2.121s1.536 0.586 2.121 0l4.939-4.939v14.379c0 0.828 0.672 1.5 1.5 1.5s1.5-0.672 1.5-1.5v-14.379l4.939 4.939c0.293 0.293 0.677 0.439 1.061 0.439s0.768-0.146 1.061-0.439c0.586-0.586 0.586-1.535 0-2.121z'></path>"+svgc,svgo+"<path d='M3.439 14.561l7.5 7.5c0.586 0.586 1.536 0.586 2.121 0l7.5-7.5c0.586-0.586 0.586-1.536 0-2.121s-1.536-0.586-2.121 0l-4.939 4.939v-14.379c0-0.828-0.672-1.5-1.5-1.5s-1.5 0.672-1.5 1.5v14.379l-4.939-4.939c-0.293-0.293-0.677-0.439-1.061-0.439s-0.768 0.146-1.061 0.439c-0.586 0.586-0.586 1.536 0 2.121z'></path>"+svgc,svgo+"<path d='M9.439 3.439l-7.5 7.5c-0.586 0.586-0.586 1.536 0 2.121l7.5 7.5c0.586 0.586 1.536 0.586 2.121 0s0.586-1.536 0-2.121l-4.939-4.939h14.379c0.828 0 1.5-0.672 1.5-1.5s-0.672-1.5-1.5-1.5h-14.379l4.939-4.939c0.293-0.293 0.439-0.677 0.439-1.061s-0.146-0.768-0.439-1.061c-0.586-0.586-1.536-0.586-2.121 0z'></path>"+svgc,svgo+"<path d='M14.561 20.561l7.5-7.5c0.586-0.586 0.586-1.536 0-2.121l-7.5-7.5c-0.586-0.586-1.536-0.586-2.121 0s-0.586 1.536 0 2.121l4.939 4.939h-14.379c-0.828 0-1.5 0.672-1.5 1.5s0.672 1.5 1.5 1.5h14.379l-4.939 4.939c-0.293 0.293-0.439 0.677-0.439 1.061s0.146 0.768 0.439 1.061c0.586 0.586 1.536 0.586 2.121 0z'></path>"+svgc], 733 /* set 2 */ 734 [svgo+"<path d='M18.58 13.724c-0.488-0.502-5.634-5.402-5.634-5.402-0.262-0.268-0.604-0.402-0.946-0.402-0.343 0-0.685 0.134
734-0.946 0.402 0 0-5.146 4.901-5.635 5.402-0.488 0.502-0.522 1.404 0 1.939 0.523 0.534 1.252 0.577 1.891 0l4.69-4.496 4.688 4.496c0.641 0.577 1.37 0.534 1.891 0 0.523-0.536 0.491-1.439 0-1.939z'</path>"+svgc,svgo+"<path d='M18.58 10.276c-0.488 0.502-5.634 5.404-5.634 5.404-0.262 0.268-0.604 0.401-0.946 0.401-0.343 0-0.685-0.133-0.946-0.401 0 0-5.146-4.902-5.635-5.404-0.488-0.502-0.522-1.403 0-1.939 0.523-0.535 1.252-0.577 1.891 0l4.69 4.498 4.688-4.496c0.641-0.577 1.37-0.535 1.891 0 0.523 0.535 0.491 1.438 0 1.938z'></path>"+svgc,svgo+"<path d='M13.724 5.419c-0.502 0.49-5.402 5.635-5.402 5.635-0.268 0.262-0.401 0.604-0.401 0.946s0.133 0.684 0.401 0.946c0 0 4.901 5.146 5.402 5.634 0.502 0.49 1.404 0.523 1.939 0 0.534-0.522 0.576-1.25-0.001-1.89l-4.496-4.69 4.496-4.69c0.577-0.641 0.535-1.369 0.001-1.891-0.536-0.522-1.439-0.49-1.939 0z'></path>"+svgc,svgo+"<path d='M10.276 5.419c0.502 0.49 5.402 5.635 5.402 5.635 0.269 0.262 0.402 0.604 0.402 0.946s-0.133 0.684-0.402 0.946c0 0-4.901 5.146-5.402 5.634-0.502 0.49-1.403 0.523-1.939 0-0.535-0.522-0.577-1.25 0-1.89l4.498-4.69-4.496-4.69c-0.577-0.641-0.535-1.369 0-1.891s1.438-0.49 1.938 0z'></path>"+svgc], 735 /* set 3 */ 736 [svgo+"<path d='M20.902 17.279c0.325 0.322 0.851 0.322 1.175 0 0.325-0.322 0.325-0.841 0-1.163l-9.49-9.396c-0.324-0.322-0.85-0.322-1.174 0l-9.49 9.396c-0.324 0.322-0.325 0.841 0 1.163s0.85 0.322 1.175 0l8.902-8.569 8.902 8.569z'></path>"+svgc,svgo+"<path d='M3.098 6.721c-0.325-0.322-0.851-0.322-1.175 0-0.324 0.32-0.324 0.841 0 1.163l9.49 9.396c0.325 0.322 0.85 0.322 1.175 0l9.49-9.396c0.324-0.322 0.325-0.841 0-1.163s-0.852-0.322-1.175-0.001l-8.903 8.569-8.902-8.568z'></path>"+svgc,svgo+"<path d='M17.279 20.902c0.322 0.325 0.322 0.85 0 1.175s-0.841 0.325-1.163 0l-9.396-9.488c-0.322-0.325-0.322-0.851 0-1.175l9.396-9.49c0.322-0.325 0.841-0.325 1.163 0s0.322 0.85 0 1.175l-8.568 8.902 8.568 8.902z'</path>"+svgc,svgo+"<path d='M6.72 20.902c-0.322 0.325-0.322 0.85 0 1.175s0.841 0.325 1.163 0l9.396-9.488c0.322-0.325 0.322-0.851 0-1.175l-9.396-9.49c-0.322-0.325-0.841-0.325-1.163 0s-0.322 0.85 0 1.175l8.568 8.902-8.568 8.902z'</path>"+svgc], 737 /* set 4 */ 738 [svgo+"<path d='M12 0l-12 12h7.5v12l9 0v-12h7.5z'></path>"+svgc,svgo+"<path d='M12 24l12-12h-7.5v-12l-9-0v12h-7.5z'></path>"+svgc,svgo+"<path d='M0 12l12 12v-7.5h12l0-9h-12v-7.5z'></path>"+svgc,svgo+"<path d='M24 12l-12-12v7.5h-12l-0 9h12v7.5z'></path>"+svgc], 739 /* set 5 */ 740 [svgo+"<path d='M6.48 16.8h11.040l-5.521-9.6z'></path>"+svgc,svgo+"<path d='M17.52 7.201l-11.040-0.001 5.52 9.6z'></path>"+svgc,svgo+"<path d='M16.799 6.48l0.001 11.040-9.6-5.52z'></path>"+svgc,svgo+"<path d='M7.201 6.48l-0.001 11.040 9.6-5.52z'></path>"+svgc] 741 ]; 742 }, 743 /* -------------------- */ 744 745 746 /* detects/sets css max-height value */ 747 _maxHeight=function(){ 748 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 749 mTS_wrapper=$("#mTS_"+d.idx), 750 mh=$this.css("max-height"),pct=mh.indexOf("%")!==-1, 751 bs=$this.css("box-sizing"); 752 if(mh!=="none"){ 753 var val=pct ? $this.parent().height()*parseInt(mh)/100 : parseInt(mh); 754 /* if element's css box-sizing is "border-box", subtract any paddings and/or borders from max-height value */ 755 if(bs==="border-box"){val-=(($this.innerHeight()-$this.height())+($this.outerHeight()-$this.innerHeight()));} 756 mTS_wrapper.css("max-height",Math.round(val)); 757 } 758 }, 759 /* -------------------- */ 760 761 762 /* checks if content overflows its container to determine if scrolling is required */ 763 _overflowed=function(){ 764 var $this=$(this),d=$this.data(pluginPfx), 765 mTS_wrapper=$("#mTS_"+d.idx), 766 mTS_container=$("#mTS_"+d.idx+"_container"); 767 return [mTS_container.height()>mTS_wrapper.height(),mTS_container.width()>mTS_wrapper.width()]; 768 }, 769 /* -------------------- */ 770 771 772 /* resets content position to 0 */ 773 _resetContentPosition=function(){ 774 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 775 mTS_wrapper=$("#mTS_"+d.idx), 776 mTS_container=$("#mTS_"+d.idx+"_container"); 777 _stop($this); /* stop any current scrolling before resetting */ 778 if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){mTS_container.css("top",0);} /* reset y */ 779 if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */ 780 var rp=d.langDir==="rtl" ? mTS_wrapper.width()-mTS_container.width() : 0; 781 mTS_container.css("left",rp); 782 } 783 }, 784 /* -------------------- */ 785 786 787 /* binds scroller events */ 788 _bindEvents=function(){ 789 var $this=$(this),d=$this.data(pluginPfx),o=d.opt; 790 if(!d.bindEvents){ /* check if events are already bound */ 791 if(o.contentTouchScroll){_contentDraggable.call(this);} 792 if(o.type.indexOf("hover")!==-1){ 793 if(o.type==="hover-precise"){ 794 _hoverPrecise.call(this); 795 }else{ 796 _hover.call(this); 797 } 798 }else if(o.type.indexOf("click")!==-1){ 799 _click.call(this); 800 } 801 d.bindEvents=true; 802 } 803 }, 804 /* -------------------- */ 805 806 807 /* unbinds scroller events */ 808 _unbindEvents=function(){ 809 var $this=$(this),d=$this.data(pluginPfx), 810 namespace=pluginPfx+"_"+d.idx, 811 sel=$("#mTS_"+d.idx+",#mTS_"+d.idx+"_container,#mTS_"+d.idx+"_buttonUp,#mTS_"+d.idx+"_buttonDown,#mTS_"+d.idx+"_buttonLeft,#mTS_"+d.idx+"_buttonRight"), 812 mTS_container=$("#mTS_"+d.idx+"_container"); 813 if(d.bindEvents){ /* check if events are bound */ 814 /* unbind namespaced events from selectors */ 815 sel.each(function(){ 816 $(this).unbind("."+namespace); 817 }); 818 /* clear and delete timeouts/objects */ 819 clearTimeout(mTS_container[0].onCompleteTimeout); _delete(mTS_container[0],"onCompleteTimeout"); 820 d.bindEvents=false; 821 } 822 }, 823 /* -------------------- */ 824 825 826 /* toggles scroller buttons visibility */ 827 _buttonsVisibility=function(disabled,hideBtn,dir){ 828 var $this=$(this),d=$this.data(pluginPfx),o=d.opt; 829 if(o.type.indexOf("click")!==-1){ 830 if(!dir){dir=o.axis;} 831 var mTS_buttons=[$("#mTS_"+d.idx+"_buttonUp"),$("#mTS_"+d.idx+"_buttonDown"),$("#mTS_"+d.idx+"_buttonLeft"),$("#mTS_"+d.idx+"_buttonRight")], 832 hideClass=pluginPfx+"-hidden"; 833 if(dir!=="x"){ 834 if(d.overflowed[0] && !disabled && !hideBtn){ 835 sel=[!d.overflowed[1] ? mTS_buttons[2].add(mTS_buttons[3]) : null,mTS_buttons[0].add(mTS_buttons[1])]; 836 }else{ 837 sel=hideBtn===1 ? [mTS_buttons[0],mTS_buttons[1]] : hideBtn===2 ? [mTS_buttons[1],mTS_buttons[0]] : [mTS_buttons[0].add(mTS_buttons[1]),null]; 838 } 839 } 840 if(dir!=="y"){ 841 if(d.overflowed[1] && !disabled && !hideBtn){ 842 sel=[!d.overflowed[0] ? mTS_buttons[0].add(mTS_buttons[1]) : null,mTS_buttons[2].add(mTS_buttons[3])]; 843 }else{ 844 sel=hideBtn===1 ? [mTS_buttons[2],mTS_buttons[3]] : hideBtn===2 ? [mTS_buttons[3],mTS_buttons[2]] : [mTS_buttons[2].add(mTS_buttons[3]),null]; 845 } 846 } 847 if(sel[0]){sel[0].addClass(hideClass);} 848 if(sel[1]){sel[1].removeClass(hideClass);} 849 } 850 }, 851 /* -------------------- */ 852 853 854 /* returns input coordinates of pointer, touch and mouse events (relative to document) */ 855 _coordinates=function(e){
856 var t=e.type; 857 switch(t){ 858 case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp": 859 return [e.originalEvent.pageY,e.originalEvent.pageX]; 860 break; 861 case "touchstart": case "touchmove": case "touchend": 862 var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; 863 return [touch.pageY,touch.pageX]; 864 break; 865 default: 866 return [e.pageY,e.pageX]; 867 } 868 }, 869 /* -------------------- */ 870 871 /* returns input type */ 872 _inputType=function(e){ 873 return touchi || e.type.indexOf("touch")!==-1 || (typeof e.pointerType!=="undefined" && (e.pointerType===2 || e.pointerType==="touch")) ? "touch" : "mouse"; 874 }, 875 /* -------------------- */ 876 877 878 /* 879 TOUCH SWIPE EVENTS 880 scrolls content via touch swipe 881 Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices 882 */ 883 _contentDraggable=function(){ 884 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 885 namespace=pluginPfx+"_"+d.idx, 886 mTS_wrapper=$("#mTS_"+d.idx), 887 mTS_container=$("#mTS_"+d.idx+"_container"), 888 dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount, 889 durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[]; 890 mTS_container.bind("touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 891 if(!_pointerTouch(e) || touchActive){return;} 892 $this.removeClass("mTS_touch_action"); 893 var offset=mTS_container.offset(); 894 dragY=_coordinates(e)[0]-offset.top; 895 dragX=_coordinates(e)[1]-offset.left; 896 touchIntent=[_coordinates(e)[0],_coordinates(e)[1]]; 897 }).bind("touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){ 898 if(!_pointerTouch(e) || touchActive){return;} 899 e.stopImmediatePropagation(); 900 runningTime=_getTime(); 901 var offset=mTS_wrapper.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, 902 easing="linearOut"; 903 touchMoveY.push(y); 904 touchMoveX.push(x); 905 touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]); 906 if(d.overflowed[0]){ 907 var limit=mTS_wrapper.height()-mTS_container.height(), 908 prevent=((dragY-y)>0 && (y-dragY)>limit && (touchIntent[3]*2<touchIntent[2])); 909 } 910 if(d.overflowed[1]){ 911 var limitX=mTS_wrapper.width()-mTS_container.width(), 912 preventX=((dragX-x)>0 && (x-dragX)>limitX && (touchIntent[2]*2<touchIntent[3])); 913 } 914 if(prevent || preventX){e.preventDefault();}else{$this.addClass("mTS_touch_action");} /* prevent native document scrolling */ 915 amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null]; 916 mTS_container[0].idleTimer=250; 917 if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all");} 918 if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite);} 919 }); 920 mTS_wrapper.bind("touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 921 if(!_pointerTouch(e) || touchActive){return;} 922 e.stopImmediatePropagation(); 923 touchi=true; 924 _stop($this); 925 startTime=_getTime(); 926 var offset=mTS_wrapper.offset(); 927 touchStartY=_coordinates(e)[0]-offset.top; 928 touchStartX=_coordinates(e)[1]-offset.left; 929 touchMoveY=[]; touchMoveX=[]; 930 }).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ 931 if(!_pointerTouch(e) || touchActive){return;} 932 e.stopImmediatePropagation(); 933 endTime=_getTime(); 934 var offset=mTS_wrapper.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 935 if((endTime-runningTime)>30){return;} 936 speed=1000/(endTime-startTime); 937 var easing="easeOut",slow=speed<2.5, 938 diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0]; 939 distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX]; 940 var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])]; 941 speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed]; 942 var a=[ 943 Math.abs(mTS_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])), 944 Math.abs(mTS_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1])) 945 ]; 946 amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null]; 947 durB=[(absDistance[0]*4)+(o.speed*60),(absDistance[1]*4)+(o.speed*60)];
948 var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */ 949 amount[0]=absDistance[0]>md ? amount[0] : 0; 950 amount[1]=absDistance[1]>md ? amount[1] : 0; 951 if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite);} 952 if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite);} 953 }); 954 function _m(ds,s){ 955 var r=[s*1.5,s*2,s/1.5,s/2]; 956 if(ds>90){ 957 return s>4 ? r[0] : r[3]; 958 }else if(ds>60){ 959 return s>3 ? r[3] : r[2]; 960 }else if(ds>30){ 961 return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2]; 962 }else{ 963 return s>8 ? s : r[3]; 964 } 965 } 966 function _drag(amount,dur,easing,dir,overwrite){ 967 if(!amount){return;} 968 _scrollTo($this,-amount.toString(),{dur:dur,easing:easing,dir:dir,overwrite:overwrite}); 969 } 970 }, 971 /* -------------------- */ 972 973 974 /* 975 HOVER PRECISE EVENT 976 scrolls content via cursor movement 977 */ 978 _hoverPrecise=function(){ 979 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 980 namespace=pluginPfx+"_"+d.idx, 981 mTS_wrapper=$("#mTS_"+d.idx), 982 mTS_container=$("#mTS_"+d.idx+"_container"), 983 evt=window.navigator.pointerEnabled ? "pointermove" : window.navigator.msPointerEnabled ? "MSPointerMove" : "mousemove", 984 cursor,dest,to; 985 mTS_wrapper.bind(evt+"."+namespace,function(e){ 986 if(_inputType(e.originalEvent || e)==="touch" || (!d.overflowed[0] && !d.overflowed[1])){return;} 987 e.preventDefault(); 988 var wrapperHeight=mTS_wrapper.height(),containerHeight=mTS_container.height(), 989 wrapperWidth=mTS_wrapper.width(),containerWidth=mTS_container.width(), 990 speed=((containerWidth/wrapperWidth)*7000)/(o.speed || 1); 991 cursor=[_coordinates(e)[0]-mTS_wrapper.offset().top,_coordinates(e)[1]-mTS_wrapper.offset().left]; 992 dest=[cursor[0]/mTS_wrapper.height(),cursor[1]/mTS_wrapper.width()]; 993 to=[Math.round(-((containerHeight-wrapperHeight)*(dest[0]))),Math.round(-((containerWidth-wrapperWidth)*(dest[1])))]; 994 if(o.axis!=="x" && d.overflowed[0]){ 995 _scrollTo($this,to[0].toString(),{dir:"y",dur:speed,easing:"easeOut"}); 996 } 997 if(o.axis!=="y" && d.overflowed[1]){ 998 _scrollTo($this,to[1].toString(),{dir:"x",dur:speed,easing:"easeOut"}); 999 } 1000 }); 1001 }, 1002 /* -------------------- */ 1003 1004 1005 /* 1006 HOVER EVENT 1007 scrolls content via cursor movement 1008 */ 1009 _hover=function(){ 1010 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1011 namespace=pluginPfx+"_"+d.idx, 1012 mTS_wrapper=$("#mTS_"+d.idx), 1013 mTS_container=$("#mTS_"+d.idx+"_container"), 1014 evt=window.navigator.pointerEnabled ? ["pointerover","pointermove","pointerout"] : 1015 window.navigator.msPointerEnabled ? ["MSPointerOver","MSPointerMove","MSPointerOut"] : 1016 ["mouseenter","mousemove","mouseleave"], 1017 rAF,cursor,dest,to,fps,delay=(!window.requestAnimationFrame) ? 17 : 0, 1018 speed=o.speed,pct=parseInt(o.type.split("hover-")[1]) || 1,idle=speed*pct/100, 1019 _pause=[0,0]; 1020 mTS_wrapper.bind(evt[0]+"."+namespace,function(e){ 1021 if(_inputType(e.originalEvent || e)==="touch" || (!d.overflowed[0] && !d.overflowed[1])){return;} 1022 _on(); 1023 }).bind(evt[1]+"."+namespace,function(e){ 1024 if(_inputType(e.originalEvent || e)==="touch" || (!d.overflowed[0] && !d.overflowed[1])){return;} 1025 cursor=[_coordinates(e)[0]-mTS_wrapper.offset().top,_coordinates(e)[1]-mTS_wrapper.offset().left]; 1026 dest=[Math.round((Math.cos((cursor[0]/mTS_wrapper.height())*Math.PI))*speed),Math.round((Math.cos((cursor[1]/mTS_wrapper.width())*Math.PI))*speed)]; 1027 dest[0]=dest[0]<=-idle ? dest[0]+=idle : dest[0]>=idle ? dest[0]-=idle : dest[0]=0; 1028 dest[1]=dest[1]<=-idle ? dest[1]+=idle : dest[1]>=idle ? dest[1]-=idle : dest[1]=0; 1029 _pause=[0,0]; 1030 }).bind(evt[2]+"."+namespace,function(e){ 1031 if(_inputType(e.originalEvent || e)==="touch" || (!d.overflowed[0] && !d.overflowed[1])){return;} 1032 _off(); 1033 }); 1034 function _on(){ 1035 if(mTS_wrapper[0].rAF){return;} 1036 rAF=(!window.requestAnimationFrame) ? function(f){return setTimeout(f,17);} : window.requestAnimationFrame; 1037 mTS_wrapper[0].rAF=rAF(_anim); 1038 } 1039 function _off(){ 1040 if(mTS_wrapper[0].rAF==null){return;} 1041 if(!window.requestAnimationFrame){ 1042 clearTimeout(mTS_wrapper[0].rAF); 1043 }else{ 1044 window.cancelAnimationFrame(mTS_wrapper[0].rAF); 1045 } 1046 clearTimeout(fps); 1047 mTS_wrapper[0].rAF=null; 1048 } 1049 function _anim(){ 1050 if(touchi){return;} /* this is for android native browser (at least for version 4.1.2) */ 1051 to=[dest[0]+mTS_container[0].offsetTop,dest[1]+mTS_container[0].offsetLeft]; 1052 var limit=[mTS_wrapper.height()-mTS_container.height(),mTS_wrapper.width()-mTS_container.width()]; 1053 if(o.axis!=="x" && d.overflowed[0]){ 1054 to[0]=to[0]>0 ? 0 : to[0]<limit[0] ? limit[0] : to[0]; 1055 if(dest[0] && !_pause[0]){ 1056 _scrollTo($this,to[0],{dir:"y",dur:0,easing:"linear"}); 1057 } 1058 if(to[0]>=0 || to[0]<=limit[0]){ 1059 _pause[0]=1; 1060 } 1061 } 1062 if(o.axis!=="y" && d.overflowed[1]){ 1063 to[1]=to[1]>0 ? 0 : to[1]<limit[1] ? limit[1] : to[1]; 1064 if(dest[1] && !_pause[1]){ 1065 _scrollTo($this,to[1],{dir:"x",dur:0,easing:"linear"}); 1066 } 1067 if(to[1]>=0 || to[1]<=limit[1]){ 1068 _pause[1]=1; 1069 } 1070 } 1071 fps=setTimeout(function(){mTS_wrapper[0].rAF=rAF(_anim);},delay); 1072 } 1073 }, 1074 /* -------------------- */ 1075 1076 1077 /* 1078 CLICK EVENT 1079 scrolls content via scrolling buttons 1080 */ 1081 _click=function(){ 1082 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1083 namespace=pluginPfx+"_"+d.idx, 1084 mTS_wrapper=$("#mTS_"+d.idx), 1085 mTS_container=$("#mTS_"+d.idx+"_container"), 1086 mTS_buttons=[$("#mTS_"+d.idx+"_buttonUp"),$("#mTS_"+d.idx+"_buttonDown"),$("#mTS_"+d.idx+"_buttonLeft"),$("#mTS_"+d.idx+"_buttonRight")], 1087 sel=mTS_buttons[0].add(mTS_buttons[1]).add(mTS_buttons[2]).add(mTS_buttons[3]); 1088 sel.bind("click."+namespace,function(e){
1089 if(!_mouseBtnLeft(e) || (!d.overflowed[0] && !d.overflowed[1])){return;} 1090 e.preventDefault(); 1091 if(d.tweenRunning){return;} 1092 if(o.axis!=="x" && d.overflowed[0]){ 1093 var h=mTS_wrapper.height(),dir=o.type==="click-thumb" ? 0 : $(this).hasClass("mTSButtonUp") ? "+=" : $(this).hasClass("mTSButtonDown") ? "-=" : 0; 1094 if(o.type!=="click-thumb"){ 1095 var pct=parseInt(o.type.split("click-")[1]) || 1,amount=dir ? [dir+(h*pct/100),null] : 0; 1096 }else{ 1097 var firstThumb=_firstLast.call($this[0])[0],lastThumb=_firstLast.call($this[0])[1]; 1098 if($(this).hasClass("mTSButtonDown")){ 1099 var amount=lastThumb ? (lastThumb[0].offsetTop-parseInt(lastThumb.css("margin-bottom")))-h : 989999; 1100 }else if($(this).hasClass("mTSButtonUp")){ 1101 var amount=firstThumb ? firstThumb[0].offsetTop-parseInt(firstThumb.css("margin-top")) : 0; 1102 if(mTS_container[0].offsetTop===0){return;} 1103 } 1104 } 1105 } 1106 if(o.axis!=="y" && d.overflowed[1]){ 1107 var w=mTS_wrapper.width(),dir=o.type==="click-thumb" ? 0 : $(this).hasClass("mTSButtonLeft") ? "+=" : $(this).hasClass("mTSButtonRight") ? "-=" : 0; 1108 if(o.type!=="click-thumb"){ 1109 var pct=parseInt(o.type.split("click-")[1]) || 1,amount=dir ? [null,dir+(w*pct/100)] : amount; 1110 }else{ 1111 var firstThumb=_firstLast.call($this[0])[2],lastThumb=_firstLast.call($this[0])[3]; 1112 if($(this).hasClass("mTSButtonRight")){ 1113 var amount=lastThumb ? (lastThumb[0].offsetLeft-parseInt(lastThumb.css("margin-right")))-w : 989999; 1114 }else if($(this).hasClass("mTSButtonLeft")){ 1115 var amount=firstThumb ? firstThumb[0].offsetLeft-parseInt(firstThumb.css("margin-left")) : 0; 1116 if(mTS_container[0].offsetLeft===0){return;} 1117 } 1118 } 1119 } 1120 if(amount!==null){methods.scrollTo.call($this[0],amount,{duration:0});} 1121 }); 1122 }, 1123 /* -------------------- */ 1124 1125 1126 /* returns the first and last items within the viewport */ 1127 _firstLast=function(){ 1128 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1129 mTS_container=$("#mTS_"+d.idx+"_container"), 1130 mTS_wrapper=$("#mTS_"+d.idx), 1131 mTS_item=mTS_container.find(".mTSThumbContainer"), 1132 f,l,fx,lx; 1133 mTS_item.each(function(){ 1134 var el=$(this), 1135 pos=[ 1136 Math.round((el.offset().top-mTS_container.offset().top)+mTS_container[0].offsetTop), 1137 Math.round((el.offset().left-mTS_container.offset().left)+mTS_container[0].offsetLeft) 1138 ]; 1139 if(pos[0]<=0-parseInt(el.css("margin-top"))){ 1140 f=pos[0]===0 ? mTS_item.eq(el.index()-1) : mTS_item.eq(el.index()); 1141 }else if(pos[0]<=mTS_wrapper.height()+parseInt(el.css("margin-bottom"))){ 1142 var i=mTS_item.eq(el.index()+1); 1143 l=i.length ? i : null; 1144 } 1145 if(pos[1]<=0-parseInt(el.css("margin-left"))){ 1146 fx=pos[1]===0 ? mTS_item.eq(el.index()-1) : mTS_item.eq(el.index()); 1147 }else if(pos[1]<=mTS_wrapper.width()+parseInt(el.css("margin-right"))){ 1148 var ix=mTS_item.eq(el.index()+1); 1149 lx=ix.length ? ix : null; 1150 } 1151 }); 1152 return [f,l,fx,lx]; 1153 }, 1154 /* -------------------- */ 1155 1156 1157 /* returns a yx array from value */ 1158 _arr=function(val){ 1159 var o=$(this).data(pluginPfx).opt,vals=[]; 1160 if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */ 1161 /* check if value is object or array, its length and create an array with yx values */ 1162 if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */ 1163 vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val; 1164 vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val; 1165 }else{ /* array value (e.g. [100,100]) */ 1166 vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null]; 1167 } 1168 /* check if array values are anonymous functions */ 1169 if(typeof vals[0]==="function"){vals[0]=vals[0]();} 1170 if(typeof vals[1]==="function"){vals[1]=vals[1]();} 1171 return vals; 1172 }, 1173 /* -------------------- */ 1174 1175 1176 /* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */ 1177 _to=function(val,dir){ 1178 if(val==null || typeof val=="undefined"){return;} 1179 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1180 mTS_wrapper=$("#mTS_"+d.idx), 1181 mTS_container=$("#mTS_"+d.idx+"_container"), 1182 t=typeof val; 1183 if(!dir){dir=o.axis==="x" ? "x" : "y";} 1184 var contentLength=dir==="x" ? mTS_container.width() : mTS_container.height(), 1185 contentOffset=dir==="x" ? mTS_container.offset().left : mTS_container.offset().top, 1186 contentPos=dir==="x" ? mTS_container[0].offsetLeft : mTS_container[0].offsetTop, 1187 cssProp=dir==="x" ? "left" : "top"; 1188 switch(t){ 1189 case "function": /* this currently is not used. Consider removing it */ 1190 return val(); 1191 break; 1192 case "object": 1193 if(val.nodeType){ /* DOM */ 1194 var objOffset=dir==="x" ? $(val).offset().left : $(val).offset().top; 1195 }else if(val.jquery){ /* jquery object */ 1196 if(!val.length){return;} 1197 var objOffset=dir==="x" ? val.offset().left : val.offset().top; 1198 } 1199 return objOffset-contentOffset; 1200 break; 1201 case "string": case "number": 1202 if(_isNumeric(val)){ /* numeric value */ 1203 return Math.abs(val); 1204 }else if(val.indexOf("%")!==-1){ /* percentage value */ 1205 return Math.abs(contentLength*parseInt(val)/100); 1206 }else if(val.indexOf("-=")!==-1){ /* decrease value */ 1207 return Math.abs(contentPos-parseInt(val.split("-=")[1])); 1208 }else if(val.indexOf("+=")!==-1){ /* inrease value */ 1209 var p=(contentPos+parseInt(val.split("+=")[1])); 1210 return p>=0 ? 0 : Math.abs(p); 1211 }else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */ 1212 return Math.abs(val.split("px")[0]); 1213 }else{ 1214 if(val==="top" || val==="left"){ /* special strings */ 1215 return 0; 1216 }else if(val==="bottom"){ 1217 return Math.abs(mTS_wrapper.height()-mTS_container.height()); 1218 }else if(val==="right"){ 1219 return Math.abs(mTS_wrapper.width()-mTS_container.width()); 1220 }else if(val==="first" || val==="last"){ 1221 var obj=mTS_container.find(":"+val), 1222 objOffset=dir==="x" ? $(obj).offset().left : $(obj).offset().top; 1223 return objOffset-contentOffset; 1224 }else{ 1225 if($(val).length){ /* jquery selector */ 1226 var objOffset=dir==="x" ? $(val).offset().left : $(val).offset().top; 1227 return objOffset-contentOffset; 1228 }else{ /* other values (e.g. "100em") */ 1229 mTS_container.css(cssProp,val); 1230 methods.update.call(null,$this[0]); 1231 return; 1232 } 1233 } 1234 } 1235 break; 1236 } 1237 }, 1238 /* -------------------- */ 1239 1240 1241 /* calls the update method automatically */ 1242 _autoUpdate=function(rem){ 1243 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1244 mTS_wrapper=$("#mTS_"+d.idx), 1245 mTS_container=$("#mTS_"+d.idx+"_container"); 1246 if(rem){ 1247 /* 1248 removes autoUpdate timer 1249 usage: functions._autoUpdate.call(this,"remove"); 1250 */ 1251 clearTimeout(mTS_container[0].autoUpdate); 1252 _delete(mTS_container[0],"autoUpdate"); 1253 return; 1254 } 1255 var oldSelSize=sizesSum(),newSelSize, 1256 os=[mTS_container.height(),mTS_container.width(),mTS_wrapper.height(),mTS_wrapper.width(),$this.height(),$this.width()],ns, 1257 oldImgsLen=imgSum(),newImgsLen; 1258 upd(); 1259 function upd(){ 1260 clearTimeout(mTS_container[0].autoUpdate); 1261 if($this.parents("html").length===0){ 1262 /* check element in dom tree */ 1263 $this=null; 1264 return; 1265 } 1266 mTS_container[0].autoUpdate=setTimeout(function(){ 1267 /* update on specific selector(s) length and size change */ 1268 if(o.advanced.updateOnSelectorChange){ 1269 newSelSize=sizesSum(); 1270 if(newSelSize!==oldSelSize){ 1271 doUpd(); 1272 oldSelSize=newSelSize; 1273 return; 1274 } 1275 } 1276 /* update on main element and scroller size changes */ 1277 if(o.advanced.updateOnContentResize){ 1278 ns=[mTS_container.height(),mTS_container.width(),mTS_wrapper.height(),mTS_wrapper.width(),$this.height(),$this.width()]; 1279 if(ns[0]!==os[0] || ns[1]!==os[1] || ns[2]!==os[2] || ns[3]!==os[3] || ns[4]!==os[4] || ns[5]!==os[5]){ 1280 doUpd(); 1281 os=ns; 1282 } 1283 } 1284 /* update on image load */ 1285 if(o.advanced.updateOnImageLoad){ 1286 newImgsLen=imgSum(); 1287 if(newImgsLen!==oldImgsLen){ 1288 mTS_container.find("img").each(function(){ 1289 imgLoader(this.src); 1290 });
vendor: 10,808 bytes, lines 1291-1602
1291 oldImgsLen=newImgsLen; 1292 } 1293 } 1294 if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();} 1295 },60); 1296 } 1297 /* returns images amount */ 1298 function imgSum(){ 1299 var total=0 1300 if(o.advanced.updateOnImageLoad){total=mTS_container.find("img").length;} 1301 return total; 1302 } 1303 /* a tiny image loader */ 1304 function imgLoader(src){ 1305 var img=new Image(); 1306 function createDelegate(contextObject,delegateMethod){ 1307 return function(){return delegateMethod.apply(contextObject,arguments);} 1308 } 1309 function imgOnLoad(){ 1310 this.onload=null; 1311 doUpd(); 1312 } 1313 img.onload=createDelegate(img,imgOnLoad); 1314 img.src=src; 1315 } 1316 /* returns the total height and width sum of all elements matching the selector */ 1317 function sizesSum(){ 1318 if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";} 1319 var total=0,sel=mTS_container.find(o.advanced.updateOnSelectorChange); 1320 if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=$(this).height()+$(this).width();});} 1321 return total; 1322 } 1323 /* calls the update method */ 1324 function doUpd(){ 1325 clearTimeout(mTS_container[0].autoUpdate); 1326 methods.update.call(null,$this[0]); 1327 } 1328 }, 1329 /* -------------------- */ 1330 1331 1332 /* stops content animations */ 1333 _stop=function(el){ 1334 var d=el.data(pluginPfx), 1335 sel=$("#mTS_"+d.idx+"_container"); 1336 sel.each(function(){ 1337 _stopTween.call(this); 1338 }); 1339 }, 1340 /* -------------------- */ 1341 1342 1343 /* 1344 ANIMATES CONTENT 1345 This is where the actual scrolling happens 1346 */ 1347 _scrollTo=function(el,to,options){ 1348 var d=el.data(pluginPfx),o=d.opt, 1349 defaults={ 1350 trigger:"internal", 1351 dir:"y", 1352 easing:"easeOut", 1353 dur:o.speed*60, 1354 overwrite:"all", 1355 callbacks:true, 1356 onStart:true, 1357 onUpdate:true, 1358 onComplete:true 1359 }, 1360 options=$.extend(defaults,options), 1361 mTS_wrapper=$("#mTS_"+d.idx), 1362 mTS_container=$("#mTS_"+d.idx+"_container"), 1363 totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0], 1364 totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0]; 1365 d.trigger=options.trigger; 1366 if(mTS_wrapper.scrollTop()!==0 || mTS_wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */ 1367 mTS_wrapper.scrollTop(0).scrollLeft(0); 1368 } 1369 switch(options.dir){ 1370 case "x": 1371 var property="left", 1372 contentPos=mTS_container[0].offsetLeft, 1373 limit=mTS_wrapper.width()-mTS_container.width(), 1374 scrollTo=to, 1375 tso=totalScrollOffsets[1], 1376 tsbo=totalScrollBackOffsets[1], 1377 totalScrollOffset=tso>0 ? tso : 0, 1378 totalScrollBackOffset=tsbo>0 ? tsbo : 0; 1379 break; 1380 case "y": 1381 var property="top", 1382 contentPos=mTS_container[0].offsetTop, 1383 limit=mTS_wrapper.height()-mTS_container.height(), 1384 scrollTo=to, 1385 tso=totalScrollOffsets[0], 1386 tsbo=totalScrollBackOffsets[0], 1387 totalScrollOffset=tso>0 ? tso : 0, 1388 totalScrollBackOffset=tsbo>0 ? tsbo : 0; 1389 break; 1390 } 1391 if(scrollTo>=0){ 1392 scrollTo=0; 1393 _buttonsVisibility.call(el,false,1,options.dir); /* show/hide buttons */ 1394 }else if(scrollTo<=limit){ 1395 scrollTo=limit; 1396 _buttonsVisibility.call(el,false,2,options.dir); /* show/hide buttons */ 1397 }else{ 1398 scrollTo=scrollTo; 1399 _buttonsVisibility.call(el,false,0,options.dir); /* show/hide buttons */ 1400 } 1401 if(!el[0].mts){ 1402 _mts(); /* init mts object (once) to make it available before callbacks */ 1403 if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */ 1404 } 1405 clearTimeout(mTS_container[0].onCompleteTimeout); 1406 if(!d.tweenRunning && ((contentPos===0 && scrollTo>=0) || (contentPos===limit && scrollTo<=limit))){return;} 1407 _tweenTo(mTS_container[0],property,Math.round(scrollTo),options.dur,options.easing,options.overwrite,{ 1408 onStart:function(){ 1409 if(options.callbacks && options.onStart && !d.tweenRunning){ 1410 /* callbacks: onScrollStart */ 1411 if(_cb("onScrollStart")){_mts(); o.callbacks.onScrollStart.call(el[0]);} 1412 d.tweenRunning=true; 1413 d.cbOffsets=_cbOffsets(); 1414 } 1415 },onUpdate:function(){ 1416 if(options.callbacks && options.onUpdate){ 1417 /* callbacks: whileScrolling */ 1418 if(_cb("whileScrolling")){_mts(); o.callbacks.whileScrolling.call(el[0]);} 1419 } 1420 },onComplete:function(){ 1421 if(options.callbacks && options.onComplete){ 1422 if(o.axis==="yx"){clearTimeout(mTS_container[0].onCompleteTimeout);} 1423 var t=mTS_container[0].idleTimer || 0; 1424 mTS_container[0].onCompleteTimeout=setTimeout(function(){ 1425 /* callbacks: onScroll, onTotalScroll, onTotalScrollBack */ 1426 if(_cb("onScroll")){_mts(); o.callbacks.onScroll.call(el[0]);} 1427 if(_cb("onTotalScroll") && scrollTo<=limit+totalScrollOffset && d.cbOffsets[0]){_mts(); o.callbacks.onTotalScroll.call(el[0]);} 1428 if(_cb("onTotalScrollBack") && scrollTo>=-totalScrollBackOffset && d.cbOffsets[1]){_mts(); o.callbacks.onTotalScrollBack.call(el[0]);} 1429 d.tweenRunning=false; 1430 mTS_container[0].idleTimer=0; 1431 },t); 1432 } 1433 } 1434 }); 1435 /* checks if callback function exists */ 1436 function _cb(cb){ 1437 return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function"; 1438 } 1439 /* checks whether callback offsets always trigger */ 1440 function _cbOffsets(){ 1441 return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo]; 1442 } 1443 /* 1444 populates object with useful values for the user 1445 values: 1446 content: this.mts.content 1447 content top position: this.mts.top 1448 content left position: this.mts.left 1449 scrolling y percentage: this.mts.topPct 1450 scrolling x percentage: this.mts.leftPct 1451 scrolling direction: this.mts.direction 1452 */ 1453 function _mts(){ 1454 var cp=[mTS_container[0].offsetTop,mTS_container[0].offsetLeft], /* content position */ 1455 cl=[mTS_container.height(),mTS_container.width()], /* content length */ 1456 pl=[mTS_wrapper.height(),mTS_wrapper.width()]; /* content parent length */ 1457 el[0].mts={ 1458 content:mTS_container, /* original content wrapper as jquery object */ 1459 top:cp[0],left:cp[1], 1460 topPct:Math.round((100*Math.abs(cp[0]))/(Math.abs(cl[0])-pl[0])),leftPct:Math.round((100*Math.abs(cp[1]))/(Math.abs(cl[1])-pl[1])), 1461 direction:options.dir 1462 }; 1463 /* 1464 this refers to the original element containing the scroller 1465 usage: this.mts.top, this.mts.leftPct etc. 1466 */ 1467 } 1468 }, 1469 /* -------------------- */ 1470 1471 1472 /* 1473 CUSTOM JAVASCRIPT ANIMATION TWEEN 1474 Lighter and faster than jquery animate() and css transitions 1475 Animates top/left properties and includes easings 1476 */ 1477 _tweenTo=function(el,prop,to,duration,easing,overwrite,callbacks){ 1478 if(!el._mTween){el._mTween={top:{},left:{}};} 1479 var callbacks=callbacks || {}, 1480 onStart=callbacks.onStart || function(){},onUpdate=callbacks.onUpdate || function(){},onComplete=callbacks.onComplete || function(){}, 1481 startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style,_request,tobj=el._mTween[prop]; 1482 if(prop==="left"){from=el.offsetLeft;} 1483 var diff=to-from; 1484 tobj.stop=0; 1485 if(overwrite!=="none"){_cancelTween();} 1486 _startTween(); 1487 function _step(){ 1488 if(tobj.stop){return;} 1489 if(!progress){onStart.call();} 1490 progress=_getTime()-startTime; 1491 _tween(); 1492 if(progress>=tobj.time){ 1493 tobj.time=(progress>tobj.time) ? progress+_delay-(progress-tobj.time) : progress+_delay-1; 1494 if(tobj.time<progress+1){tobj.time=progress+1;} 1495 } 1496 if(tobj.time<duration){tobj.id=_request(_step);}else{onComplete.call();} 1497 } 1498 function _tween(){ 1499 if(duration>0){ 1500 tobj.currVal=_ease(tobj.time,from,diff,duration,easing); 1501 elStyle[prop]=Math.round(tobj.currVal)+"px"; 1502 }else{ 1503 elStyle[prop]=to+"px"; 1504 } 1505 onUpdate.call(); 1506 } 1507 function _startTween(){ 1508 _delay=1000/60; 1509 tobj.time=progress+_delay; 1510 _request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame; 1511 tobj.id=_request(_step); 1512 } 1513 function _cancelTween(){ 1514 if(tobj.id==null){return;} 1515 if(!window.requestAnimationFrame){clearTimeout(tobj.id); 1516 }else{window.cancelAnimationFrame(tobj.id);} 1517 tobj.id=null; 1518 } 1519 function _ease(t,b,c,d,type){ 1520 switch(type){ 1521 case "linear": 1522 return c*t/d + b; 1523 break; 1524 case "linearOut": 1525 t/=d; t--; return c * Math.sqrt(1 - t*t) + b; 1526 break; 1527 case "easeInOutSmooth": 1528 t/=d/2; 1529 if(t<1) return c/2*t*t + b; 1530 t--; 1531 return -c/2 * (t*(t-2) - 1) + b; 1532 break; 1533 case "easeInOutStrong": 1534 t/=d/2; 1535 if(t<1) return c/2 * Math.pow( 2, 10 * (t - 1) ) + b; 1536 t--; 1537 return c/2 * ( -Math.pow( 2, -10 * t) + 2 ) + b; 1538 break; 1539 case "easeInOut": 1540 t/=d/2; 1541 if(t<1) return c/2*t*t*t + b; 1542 t-=2; 1543 return c/2*(t*t*t + 2) + b; 1544 break; 1545 case "easeOutSmooth": 1546 t/=d; t--; 1547 return -c * (t*t*t*t - 1) + b; 1548 break; 1549 case "easeOutStrong": 1550 return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b; 1551 break; 1552 case "easeOut": default: 1553 var ts=(t/=d)*t,tc=ts*t; 1554 return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t); 1555 } 1556 } 1557 }, 1558 /* -------------------- */ 1559 1560 1561 /* returns current time */ 1562 _getTime=function(){ 1563 if(window.performance && window.performance.now){ 1564 return window.performance.now(); 1565 }else{ 1566 if(window.performance && window.performance.webkitNow){ 1567 return window.performance.webkitNow(); 1568 }else{ 1569 if(Date.now){return Date.now();}else{return new Date().getTime();} 1570 } 1571 } 1572 }, 1573 /* -------------------- */ 1574 1575 1576 /* stops a tween */ 1577 _stopTween=function(){ 1578 var el=this; 1579 if(!el._mTween){el._mTween={top:{},left:{}};} 1580 var props=["top","left"]; 1581 for(var i=0; i<props.length; i++){ 1582 var prop=props[i]; 1583 if(el._mTween[prop].id){ 1584 if(!window.requestAnimationFrame){clearTimeout(el._mTween[prop].id); 1585 }else{window.cancelAnimationFrame(el._mTween[prop].id);} 1586 el._mTween[prop].id=null; 1587 el._mTween[prop].stop=1; 1588 } 1589 } 1590 }, 1591 /* -------------------- */ 1592 1593 1594 /* deletes a property (avoiding the exception thrown by IE) */ 1595 _delete=function(c,m){ 1596 try{delete c[m];}catch(e){c[m]=null;} 1597 }, 1598 /* -------------------- */ 1599 1600 1601 /* detects left mouse button */ 1602 _mouseBtnLeft=function(e){
1603 return !(e.which && e.which!==1); 1604 }, 1605 /* -------------------- */ 1606 1607 1608 /* detects if pointer type event is touch */ 1609 _pointerTouch=function(e){ 1610 var t=e.originalEvent.pointerType; 1611 return !(t && t!=="touch" && t!==2); 1612 }, 1613 /* -------------------- */ 1614 1615 1616 /* checks if value is numeric */ 1617 _isNumeric=function(val){ 1618 return !isNaN(parseFloat(val)) && isFinite(val); 1619 }; 1620 /* -------------------- */ 1621 1622 1623 1624 1625 1626 /* 1627 ---------------------------------------- 1628 PLUGIN SETUP 1629 ---------------------------------------- 1630 */ 1631 1632 /* plugin constructor functions */ 1633 $.fn[pluginNS]=function(method){ /* usage: $(selector).fn(); */ 1634 if(methods[method]){ 1635 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 1636 }else if(typeof method==="object" || !method){ 1637 return methods.init.apply(this,arguments); 1638 }else{ 1639 $.error("Method "+method+" does not exist"); 1640 } 1641 }; 1642 $[pluginNS]=function(method){ /* usage: $.fn(); */ 1643 if(methods[method]){ 1644 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 1645 }else if(typeof method==="object" || !method){ 1646 return methods.init.apply(this,arguments); 1647 }else{ 1648 $.error("Method "+method+" does not exist"); 1649 } 1650 }; 1651 1652 /* 1653 allow setting plugin default options. 1654 usage: $.mThumbnailScroller.defaults.speed=15; 1655 to apply any changed default options on default selectors (below), use inside document ready fn 1656 e.g.: $(document).ready(function(){ $.mThumbnailScroller.defaults.speed=15; }); 1657 */ 1658 $[pluginNS].defaults=defaults; 1659 1660 /* 1661 add window object (window.mThumbnailScroller) 1662 usage: if(window.mThumbnailScroller){console.log("plugin script loaded");} 1663 */ 1664 window[pluginNS]=true; 1665 1666 /* call plugin fn automatically on default selector with HTML data attributes */ 1667 $(window).on("load",function () { 1668 try { 1669 var elems=$(defaultSelector),instances=[]; 1670 if(elems.length){ 1671 elems.each(function(){ 1672 var elem=$(this),axis=elem.data("mts-axis") || defaults.axis,type=elem.data("mts-type") || defaults.type,theme=elem.data("mts-theme") || defaults.theme, 1673 elemClass="auto-"+pluginPfx+"-"+axis+"-"+type+"-"+theme,instance=[elemClass,axis,type]; 1674 elem.addClass(elemClass); 1675 if($.inArray(elemClass,instances)===-1){ 1676 instances.push(instance); 1677 } 1678 }); 1679 for(var i=0; i<instances.length; i++){ 1680 $("."+instances[i][0])[pluginNS]({axis:instances[i][1],type:instances[i][2]}); 1681 } 1682 } 1683 } 1684 catch (err) { 1685 console.log(err); 1686 } 1687 }); 1688 1689})(jQuery,window,document);
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.