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