1function onYouTubeIframeAPIReady(){ 2 if(PEXETO.pendingVideoFunction){ 3 PEXETO.pendingVideoFunction.call(); 4 } 5} 6 7 8/** 9 * This is the script for the content slider - it slides between different slides with 10 * different animation. Each slide is composed of two sections and each of this section 11 * is animated in a random effect. 12 * 13 * Dependencies: 14 * - jQuery 15 * - jQuery Easing : http://gsgd.co.uk/sandbox/jquery/easing/ 16 * 17 * @author Pexeto 18 * http://pexetothemes.com 19 */ 20(function($) { 21 $.fn.pexetoContentSlider = function(options) { 22 var defaults = { 23 //set the default options (can be overwritten from the calling function) 24 autoplay : true, 25 animationInterval : 5000, 26 //the interval between each animation when autoplay is true 27 pauseOnHover : true, 28 //if true the animation will be paused when the mouse is 29 // over the slider 30 pauseInterval : 5000, 31 //the time that the animation will be paused after a click 32 animationSpeed : 400, 33 easing : 'easeOutSine', 34 buttons : true, 35 //show the navigation buttons 36 arrows : true, 37 //show the navigation arrows 38 //selectors, classes and IDs 39 ulSel : '#cs-slider-ul', 40 navigationId : 'cs-navigation', 41 selectedClass : 'selected', 42 firstBoxSel : '.cs-content-left', 43 secondBoxSel : '.cs-content-right', 44 centerBoxSel : '.cs-content-centered', 45 prevArrowClass : 'cs-arrows cs-prev-arrow', 46 nextArrowClass : 'cs-arrows cs-next-arrow', 47 loadingClass : 'cs-loading' 48 }; 49 50 51 var o = $.extend(defaults, options), 52 $root = null, 53 $parent = null, 54 $ul = null, 55 $nav = null, 56 $navLi = null, 57 $prevArrow = null, 58 $nextArrow = null, 59 itemNum = 0, 60 currentIndex = 0, 61 timer = 0, 62 stopped = true, 63 inAnimation = false, 64 sliderHeight = 0, 65 showEffects = ['slideLeft', 'slideRight', 'slideUp', 'slideDown'], 66 showEffectNum = showEffects.length, 67 slides = [], 68 $newBgImage = null, 69 $oldBgImage = null, 70 defaultBg = '#777777', 71 isIe8 = PEXETO.getBrowser().msie && PEXETO.getBrowser().version<=8, 72 loadProgress = 0, 73 videoId = 0, 74 videoPlaying = false, 75 videoLoading = false, 76 pendingVideoFunction = null, 77 mouseIn = false, 78 supportsTransition = PEXETO.utils.supportsTransition(); 79 80 $root = $(this); 81 $parent = $root.parent(); 82 $ul = $(o.ulSel); 83 84 85 /** 86 * Inits the slider - calls the main functionality. 87 */ 88 89 function init() { 90 91 $root.addClass(o.loadingClass); 92 93 //get the items number 94 itemNum = $ul.find('li').each(function(i) { 95 var $li = $(this), 96 layout = $li.data('layout'); 97 98 99 slides[i] = { 100 firstBox: layout === 'centered' ? $li.find(o.centerBoxSel) : $li.find(o.firstBoxSel), 101 secondBox: layout === 'centered' ? null : $li.find(o.secondBoxSel), 102 li:$li, 103 layout:layout, 104 animation:$li.data('animation') 105 }; 106 107 if($li.data('bg_image_url')){ 108 slides[i].bgImage = $li.data('bg_image_url'); 109 slides[i].bgOpacity = $li.data('bg_image_opacity'); 110 } 111 112 if($li.data('bg_align')){ 113 slides[i].bgAlign = $li.data('bg_align'); 114 } 115 116 if($li.data('bg_style')){ 117 slides[i].bgStyle = $li.data('bg_style'); 118 } 119 120 if($li.data('bg_color')){ 121 slides[i].bgColor = $li.data('bg_color'); 122 $parent.css({backgroundColor:slides[i].bgColor}); 123 } 124 125 if($li.data('video')){ 126 slides[i].video = $li.data('video'); 127 } 128 129 }).length; 130 131 loadSlideImages(0,0).done(function(){ 132 doOnImgLoaded(); 133 $root.removeClass(o.loadingClass); 134 showSlide(0); 135 }); 136 137 if(itemNum<=1){ 138 o.buttons=false; 139 o.arrows=false; 140 o.autoplay=false; 141 } 142 143 if(PEXETO.utils.checkIfMobile()){ 144 o.autoplay=false; 145 } 146 147 loadSlideImages(1,itemNum-1).done(doOnImgLoaded); 148 } 149 150 function doOnImgLoaded(){ 151 loadProgress+=0.5; 152 if(loadProgress===1){ 153 //both the first image and the rest of the images have been loaded 154 //init the slider functionality 155 156 //set the navigation buttons 157 setNavigation(); 158 bindEventHandlers(); 159 160 //the images are loaded, start the animation 161 if(o.autoplay) { 162 startAnimation(); 163 } 164 165 } 166 } 167 168 function loadSlideImages(firstIndex, lastIndex){ 169 var deferred = new $.Deferred(), 170 progress = 0, 171 imgSrcToLoad = [], 172 imagesToLoad = [], 173 imgNum = 0, 174 imgLoaded = 0, 175 img = null, 176 onImgLoaded = function(){ 177 imgLoaded++; 178
179 if(imgLoaded===imgNum){ 180 deferred.resolve(); 181 } 182 }; 183 184 for(var i=firstIndex; i<=lastIndex; i++){ 185 slides[i].li.find('img').each(function(){ 186 imgSrcToLoad.push($(this).attr('src')); 187 }); 188 189 if(slides[i].bgImage){ 190 imgSrcToLoad.push(slides[i].bgImage); 191 192 } 193 } 194 195 imgNum = imgSrcToLoad.length; 196 197 for(i=0; i<imgNum; i++){ 198 img = new Image(); 199 img.src = imgSrcToLoad[i]; 200 imagesToLoad.push($(img)); 201 } 202 203 if(imgNum===0){ 204 deferred.resolve(); 205 }else{ 206 for(i=0; i<imgNum; i++){ 207 imagesToLoad[i].pexetoOnImgLoaded({callback:onImgLoaded}); 208 } 209 } 210 211 return deferred; 212 } 213 214 /** 215 * Binds event handlers for the main slider functionality. 216 */ 217 218 function bindEventHandlers() { 219 220 if(o.buttons) { 221 //add event handlers 222 $nav.on({ 223 'click': doOnBtnClick, 224 'slideChanged': doOnSlideChanged 225 }, 'li'); 226 227 } 228 229 if(o.arrows) { 230 $prevArrow.on('click', function() { 231 mouseIn = true; 232 doOnArrowClick(false); 233 }); 234 $nextArrow.on('click', function() { 235 mouseIn = true; 236 doOnArrowClick(true); 237 }); 238 } 239 240 241 242 //display/hide the navigation on $root hover 243 $root.on({ 244 'mouseenter': doOnSliderMouseEnter, 245 'mouseleave': doOnSliderMouseLeave 246 }); 247 248 $(window).on('resize', function(){ 249 setSliderHeight(currentIndex); 250 centerSlide(currentIndex); 251 }); 252 } 253 254 /** 255 * Calls the functionality to change the current slide with another one. 256 * @param {int} index the index of the new slide 257 */ 258 259 function changeSlide(index) { 260 if(!inAnimation) { 261 inAnimation = true; 262 hideSlide(currentIndex); 263 showSlide(index); 264 currentIndex = index; 265 266 if(o.buttons) { 267 $navLi.trigger('slideChanged'); 268 } 269 } 270 } 271 272 273 /** 274 * Adds navigation buttons to the slider and sets event handler functions to them. 275 */ 276 277 function setNavigation() { 278 var i, html = ''; 279 280 //generate the buttons 281 if(o.buttons) { 282 $nav = $('<ul />', { 283 id: o.navigationId 284 }); 285 for(i = 0; i < itemNum; i++) { 286 html += '<li><span></span></li>'; 287 } 288 $nav.html(html).appendTo($root).fadeIn(700); 289 290 $navLi = $nav.find('li'); 291 $navLi.eq(0).addClass(o.selectedClass); 292 } 293 294 //generate the arrows 295 if(o.arrows) { 296 $prevArrow = $('<div />', { 297 'class': o.prevArrowClass 298 }).appendTo($root); 299 $nextArrow = $('<div />', { 300 'class': o.nextArrowClass 301 }).appendTo($root); 302 } 303 304 } 305 306 /*********************************************************************** 307 * EVENT HANDLER FUNCTIONS 308 **********************************************************************/ 309 310 /** 311 * On arrow click event handler. Calls a function to change the slide 312 * depending on which arrow (previous/next) was clicked. 313 * @param {boolean} next whether the next arrow is clicked (set it to true) 314 * or the previous one was cicked (set it to false) 315 */ 316 317 function doOnArrowClick(next) { 318 var index; 319 if(next) { 320 //next index will be the next item if there is one or the first item 321 index = currentIndex + 1 < itemNum ? currentIndex + 1 : 0; 322 } else { 323 //previous index will be the previous item if there is one or the last item 324 index = currentIndex - 1 >= 0 ? currentIndex - 1 : itemNum - 1; 325 } 326 if(!inAnimation) { 327 pause(); 328 } 329 changeSlide(index); 330 } 331 332 /** 333 * On slider mouse enter event handler. 334 */ 335 336 function doOnSliderMouseEnter() { 337 if(o.buttons) { 338 //show the buttons 339 $nav.stop().fadeIn(function() { 340 $nav.animate({ 341 opacity: 1 342 }, 0); 343 }); 344 } 345 346 if(o.autoplay && o.pauseOnHover) { 347 //pause the animation 348 stopAnimation(); 349 mouseIn = true; 350 } 351 } 352 353 /** 354 * On slider mouse leave event handler. 355 */ 356 357 function doOnSliderMouseLeave() { 358 if(o.buttons) { 359 //hide the buttons 360 $nav.stop().animate({ 361 opacity: 0 362 }); 363 } 364 365 if(o.autoplay && o.pauseOnHover) { 366 //resume the animation 367 mouseIn = false; 368 startAnimation(); 369 } 370 } 371 372 /** 373 * On navigation button click event handler. Calls the functionality 374 * to show the slide that corresponds to the button index. 375 * @param {object} e the event object 376 */ 377 378 function doOnBtnClick(e) { 379 e.stopPropagation(); 380 var index = $navLi.index($(this)); 381 if(!inAnimation) { 382 pause(); 383 } 384 if(currentIndex !== index) { 385 changeSlide(index); 386 } 387 } 388 389 /** 390 * On slider change event handler. Sets the current button in the navigation 391 * to be selected according to the current slide index. 392 */ 393 394 function doOnSlideChanged() { 395 var index = $navLi.index($(this)); 396 if(currentIndex === index) { 397 $(this).addClass(o.selectedClass); 398 } else { 399 $(this).removeClass(o.selectedClass); 400 } 401 } 402 403 /*************************************************************************** 404 * ANIMATION FUNCTIONS 405 **************************************************************************/ 406 407 /** 408 * Hides a slide with a random animation. 409 * @param {int} index the index of the slide to be displayed 410 */ 411 412 function hideSlide(index) { 413 414 var slide = slides[index], 415 $firstBox = slides[index].firstBox, 416 $secondBox = slides[index].secondBox, 417 finishHide = function($box){ 418 slide.li.hide(); 419 $box.find('.cs-element').removeClass('cs-animate'); 420 }; 421 422 if(slide.video){ 423 hideVideo(slide); 424 } 425 426 427 //hide the first box 428 hideInnerElements($firstBox, function(){ 429 finishHide($firstBox); 430 }); 431 432 //hide the second box 433 if($secondBox){ 434 hideInnerElements($secondBox, function(){ 435 finishHide($secondBox); 436 }); 437 } 438 439 if($newBgImage){ 440 //fade out the background image 441 $oldBgImage = $newBgImage; 442 $oldBgImage.animate({opacity:0}
442, 1000, function(){ 443 $(this).remove(); 444 $oldBgImage = null; 445 }); 446 } 447 448 } 449 450 function hideInnerElements($box, callback){ 451 var $elements = $box.find('.cs-element'); 452 $elements.css({opacity:0}); 453 if(callback){ 454 if(supportsTransition){ 455 $elements.last().on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){ 456 callback.call(); 457 $(this).off('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd'); 458 }); 459 }else{ 460 callback.call(); 461 } 462 } 463 } 464 465 function centerSlide(index){ 466 var slide = slides[index]; 467 468 if(slide.layout=='centered'){ 469 var liHeight = slide.li.height(), 470 ulHeight = Math.max(sliderHeight, parseInt($ul.css('minHeight'), 10)); 471 if(ulHeight > liHeight){ 472 slide.li.css({paddingTop:((ulHeight-liHeight)/2)}); 473 } 474 } 475 } 476 477 /** 478 * Displays a slide with a random animation. 479 * @param {int} index the index of the slide to be displayed 480 */ 481 482 function showSlide(index) { 483 var slide = slides[index], 484 animation = slide.animation === 'random' ? 485 showEffects[Math.floor(Math.random() * showEffectNum)] : 486 slide.animation, 487 //get a random effect 488 $firstBox = slide.firstBox, 489 $secondBox = slide.secondBox, 490 lastBox = true; 491 492 493 videoPlaying = false; 494 slide.li.show(); 495 496 if(slide.video){ 497 initVideo(slide); 498 } 499 500 501 setSliderHeight(index); 502 503 centerSlide(index); 504 505 //show the background image 506 if(slide.bgImage){ 507 var cssArgs = {backgroundImage:'url('+slide.bgImage+')'}; 508 509 if(slide.bgAlign){ 510 cssArgs.backgroundPosition = slide.bgAlign; 511 } 512 if(slide.bgStyle){ 513 //only the default style is parallax (background-attachment fixed), the other styles are scroll 514 cssArgs.backgroundAttachment = 'scroll'; 515 if(slide.bgStyle==='contain'){ 516 cssArgs.backgroundSize = 'contain'; 517 } 518 } 519 520 521 $newBgImage = $('<div />', {'class':'full-bg-image'}) 522 .css(cssArgs) 523 .insertBefore($root) 524 .animate({opacity:slide.bgOpacity}, 1000); 525 526 if(isIe8){ 527 new PEXETO.utils.bgCoverFallback($newBgImage).init(); 528 } 529 530 } 531 532 if(slide.bgColor){ 533 $parent.css({backgroundColor:'#'+slide.bgColor}); 534 }else if($parent.css('backgroundColor')!==defaultBg){ 535 $parent.css({backgroundColor:defaultBg}); 536 } 537 538 $.when( 539 (function(){ 540 //animate the first box elements with a delay 541 var def = new $.Deferred(); 542 setTimeout(function() { 543 showInnerElements($firstBox, animation, def); 544 }, o.animationSpeed / 2 + 150); 545 return def; 546 })(), 547 (function(){ 548 //animate the second box elements 549 var def = new $.Deferred(); 550 if($secondBox){ 551 showInnerElements($secondBox, animation, def); 552 }else{ 553 def.resolve(); 554 } 555 return def; 556 })() 557 ).done(function(){ 558 setEndAnimation(); 559 }); 560 } 561 562 function initVideo (slide) { 563 videoLoading = true; 564 pause(); 565 566 var videoElId = 'video-'+(videoId++), 567 initElVideo = function(){ 568 var player = new YT.Player(videoElId, { 569 height: '100%', 570 width: '100%', 571 videoId: slide.video, 572 events: { 573 'onReady': function(){ 574 slide.$videoWrap 575 .animate({opacity:1}, 700) 576 .parent().removeClass('loading'); 577 videoLoading = false; 578 startAnimation(); 579 580 581 }, 582 'onStateChange': function(event){ 583 if (event.data == YT.PlayerState.PLAYING) { 584 stopAnimation(); 585 videoPlaying = true; 586 } 587 } 588 } 589 }); 590 591 PEXETO.init.ieIframeFix(); //fix the iframe z-index bug on IE 592 593 }; 594 595 slide.$videoWrap = slide.li.find('.cs-video:first').css({opacity:0}); 596 $('<div />', {'id':videoElId}).appendTo(slide.$videoWrap); 597 slide.$videoWrap.parent().addClass('loading'); 598 599 if(window.YT && window.YT.Player){ 600 initElVideo(); 601 }else{ 602 PEXETO.pendingVideoFunction = initElVideo; 603 } 604 } 605 606 function hideVideo(slide){ 607 slide.$videoWrap.animate({opacity:0}
607, function(){ 608 slide.$videoWrap.empty(); 609 }); 610 } 611 612 function showInnerElements($box, animation, def){ 613 var i = 100, 614 settings = getPositionPropertySettings(animation), 615 animateProperty = settings.property, 616 mult = settings.mult, 617 pos = 150*mult, 618 $elements = $box.find('.cs-element'); 619 620 if(!$elements.length){ 621 def.resolve(); 622 return; 623 } 624 625 $elements.each(function(index){ 626 var $el = $(this), 627 args = {opacity:0}; 628 629 args[animateProperty] = pos; 630 631 $el.css(args); 632 633 setTimeout(function(){ 634 var showArgs = {opacity:1}, 635 args; 636 showArgs[animateProperty] = 0; 637 args = [showArgs]; 638 639 if(index===$elements.length-1){ 640 //add a callback function to be executed after the 641 //element animation 642 args.push(function(){ 643 def.resolve(); 644 }); 645 } 646 647 $el.addClass('cs-animate'); 648 $.fn.pexetoTransit.apply($el, args); 649 650 }, i); 651 i+=150; 652 pos = pos > 20 ? pos-20 : pos; 653 }); 654 } 655 656 function getPositionPropertySettings(animation){ 657 var settings = { 658 'slideLeft' : {property: 'left', mult: 1}, 659 'slideRight' : {property: 'left', mult: -1}, 660 'slideUp' : {property: 'top', mult: 1}, 661 'slideDown' : {property: 'top', mult: -1} 662 }; 663 664 return settings[animation]; 665 666 } 667 668 function setSliderHeight(index){ 669 670 sliderHeight = slides[index].li.height(); 671 672 $ul.css({height: sliderHeight}); 673 } 674 675 676 /** 677 * Starts the animation. 678 */ 679 680 function startAnimation() { 681 if(o.autoplay && stopped && !videoPlaying) { 682 if(o.pauseOnHover && mouseIn){ 683 //the mouse is still within the container 684 return; 685 } 686 stopped = false; 687 timer = window.setInterval(callNextSlide, o.animationInterval); 688 } 689 } 690 691 /** 692 * Sets the inAnimation variable to false. 693 */ 694 695 function setEndAnimation() { 696 inAnimation = false; 697 } 698 699 /** 700 * Triggers a changeSlide event to display the next slide. 701 */ 702 703 function callNextSlide() { 704 if(!videoLoading){ 705 var nextIndex = (currentIndex < itemNum - 1) ? (currentIndex + 1) : 0; 706 changeSlide(nextIndex); 707 } 708 } 709 710 /** 711 * Stops the animation. 712 */ 713 714 function stopAnimation() { 715 if(o.autoplay) { 716 window.clearInterval(timer); 717 timer = -1; 718 stopped = true; 719 } 720 } 721 722 /** 723 * Pauses the animation. 724 */ 725 726 function pause() { 727 if(o.autoplay) { 728 window.clearInterval(timer); 729 timer = -1; 730 if(!stopped) { 731 window.setTimeout(startAnimation, o.pauseInterval); 732 } 733 stopped = true; 734 } 735 } 736 737 738 init(); 739 740 }; 741 742}(jQuery));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.