/** * fullpage 2.2.9 * https://github.com/alvarotrigo/fullpage.js * mit licensed * * copyright (c) 2013 alvarotrigo.com - a project by alvaro trigo */ (function($) { $.fn.fullpage = function(options) { // create some defaults, extending them with any options that were provided options = $.extend({ "verticalcentered": true, 'resize': true, 'sectionscolor' : [], 'anchors':[], 'scrollingspeed': 700, 'easing': 'easeinquart', 'menu': false, 'navigation': false, 'navigationposition': 'right', 'navigationcolor': '#000', 'navigationtooltips': [], 'slidesnavigation': false, 'slidesnavposition': 'bottom', 'controlarrowcolor': '#fff', 'loopbottom': false, 'looptop': false, 'loophorizontal': true, 'autoscrolling': true, 'scrolloverflow': false, 'css3': false, 'paddingtop': 0, 'paddingbottom': 0, 'fixedelements': null, 'normalscrollelements': null, 'keyboardscrolling': true, 'touchsensitivity': 5, 'continuousvertical': false, 'animateanchor': true, 'normalscrollelementtouchthreshold': 5, 'sectionselector': '.section', 'slideselector': '.slide', //events 'afterload': null, 'onleave': null, 'afterrender': null, 'afterresize': null, 'afterslideload': null, 'onslideleave': null }, options); // disable mutually exclusive settings if (options.continuousvertical && (options.looptop || options.loopbottom)) { options.continuousvertical = false; console && console.log && console.log("option looptop/loopbottom is mutually exclusive with continuousvertical; continuousvertical disabled"); } //defines the delay to take place before being able to scroll to the next section //be careful! not recommened to change it under 400 for a good behavior in laptops and //apple devices (laptops, mouses...) var scrolldelay = 600; $.fn.fullpage.setautoscrolling = function(value){ options.autoscrolling = value; var element = $('.fp-section.active'); if(options.autoscrolling){ $('html, body').css({ 'overflow' : 'hidden', 'height' : '100%' }); //for ie touch devices container.css({ '-ms-touch-action': 'none', 'touch-action': 'none' }); if(element.length){ //moving the container up silentscroll(element.position().top); } }else{ $('html, body').css({ 'overflow' : 'visible', 'height' : 'initial' }); //for ie touch devices container.css({ '-ms-touch-action': '', 'touch-action': '' }); silentscroll(0); //scrolling the page to the section with no animation $('html, body').scrolltop(element.position().top); } }; /** * defines the scrolling speed */ $.fn.fullpage.setscrollingspeed = function(value){ options.scrollingspeed = value; }; /** * adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad. */ $.fn.fullpage.setmousewheelscrolling = function (value){ if(value){ addmousewheelhandler(); }else{ removemousewheelhandler(); } }; /** * adds or remove the possiblity of scrolling through sections by using the mouse wheel/trackpad or touch gestures. */ $.fn.fullpage.setallowscrolling = function (value){ if(value){ $.fn.fullpage.setmousewheelscrolling(true); addtouchhandler(); }else{ $.fn.fullpage.setmousewheelscrolling(false); removetouchhandler(); } }; /** * adds or remove the possiblity of scrolling through sections by using the keyboard arrow keys */ $.fn.fullpage.setkeyboardscrolling = function (value){ options.keyboardscrolling = value; }; //flag to avoid very fast sliding for landscape sliders var slidemoving = false; var istouchdevice = navigator.useragent.match(/(iphone|ipod|ipad|android|blackberry|bb10|windows phone|tizen|bada)/); var istouch = (('ontouchstart' in window) || (navigator.msmaxtouchpoints > 0)); var container = $(this); var windowsheight = $(window).height(); var ismoving = false; var isresizing = false; var lastscrolleddestiny; var lastscrolledslide; var nav; var wrapperselector = 'fullpage-wrapper'; $.fn.fullpage.setallowscrolling(true); //if css3 is not supported, it will use jquery animations if(options.css3){ options.css3 = support3d(); } if($(this).length){ container.css({ 'height': '100%', 'position': 'relative' }); //adding a class to recognize the container internally in the code container.addclass(wrapperselector); } //trying to use fullpage without a selector? else{ console.error("error! fullpage.js needs to be initialized with a selector. for example: $('#mycontainer').fullpage();"); } //adding internal class names to void problem with common ones $(options.sectionselector).each(function(){ $(this).addclass('fp-section'); }); $(options.slideselector).each(function(){ $(this).addclass('fp-slide'); }); //creating the navigation dots if (options.navigation) { addverticalnavigation(); } $('.fp-section').each(function(index){ var that = $(this); var slides = $(this).find('.fp-slide'); var numslides = slides.length; //if no active section is defined, the 1st one will be the default one if(!index && $('.fp-section.active').length === 0) { $(this).addclass('active'); } $(this).css('height', windowsheight + 'px'); if(options.paddingtop || options.paddingbottom){ $(this).css('padding', options.paddingtop + ' 0 ' + options.paddingbottom + ' 0'); } if (typeof options.sectionscolor[index] !== 'undefined') { $(this).css('background-color', options.sectionscolor[index]); } if (typeof options.anchors[index] !== 'undefined') { $(this).attr('data-anchor', options.anchors[index]); } // if there's any slide if (numslides > 1) { var sliderwidth = numslides * 100; var slidewidth = 100 / numslides; slides.wrapall('
'); slides.parent().wrap('
'); $(this).find('.fp-slidescontainer').css('width', sliderwidth + '%'); $(this).find('.fp-slides').after('
'); if(options.controlarrowcolor!='#fff'){ $(this).find('.fp-controlarrow.fp-next').css('border-color', 'transparent transparent transparent '+options.controlarrowcolor); $(this).find('.fp-controlarrow.fp-prev').css('border-color', 'transparent '+ options.controlarrowcolor + ' transparent transparent'); } if(!options.loophorizontal){ $(this).find('.fp-controlarrow.fp-prev').hide(); } if(options.slidesnavigation){ addslidesnavigation($(this), numslides); } slides.each(function(index) { $(this).css('width', slidewidth + '%'); if(options.verticalcentered){ addtableclass($(this)); } }); var startingslide = that.find('.fp-slide.active'); //if the slide won#t be an starting point, the default will be the first one if(startingslide.length == 0){ slides.eq(0).addclass('active'); } //is there a starting point for a non-starting section? else{ silentlandscapescroll(startingslide); } }else{ if(options.verticalcentered){ addtableclass($(this)); } } }).promise().done(function(){ $.fn.fullpage.setautoscrolling(options.autoscrolling); //the starting point is a slide? var activeslide = $('.fp-section.active').find('.fp-slide.active'); //the active section isn't the first one? is not the first slide of the first section? then we load that section/slide by default. if( activeslide.length && ($('.fp-section.active').index('.fp-section') != 0 || ($('.fp-section.active').index('.fp-section') == 0 && activeslide.index() != 0))){ silentlandscapescroll(activeslide); } //fixed elements need to be moved out of the plugin container due to problems with css3. if(options.fixedelements && options.css3){ $(options.fixedelements).appendto('body'); } //vertical centered of the navigation + first bullet active if(options.navigation){ nav.css('margin-top', '-' + (nav.height()/2) + 'px'); nav.find('li').eq($('.fp-section.active').index('.fp-section')).find('a').addclass('active'); } //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using css3 tranforms) if(options.menu && options.css3 && $(options.menu).closest('.fullpage-wrapper').length){ $(options.menu).appendto('body'); } if(options.scrolloverflow){ if(document.readystate === "complete"){ createslimscrollinghandler(); } //after dom and images are loaded $(window).on('load', createslimscrollinghandler); }else{ $.isfunction( options.afterrender ) && options.afterrender.call( this); } //getting the anchor link in the url and deleting the `#` var value = window.location.hash.replace('#', '').split('/'); var destiny = value[0]; if(destiny.length){ var section = $('[data-anchor="'+destiny+'"]'); if(!options.animateanchor && section.length){ if(options.autoscrolling){ silentscroll(section.position().top); } else{ silentscroll(0); //scrolling the page to the section with no animation $('html, body').scrolltop(section.position().top); } activatemenuelement(destiny); activatenavdots(destiny, null); $.isfunction( options.afterload ) && options.afterload.call( this, destiny, (section.index('.fp-section') + 1)); //updating the active class section.addclass('active').siblings().removeclass('active'); } } $(window).on('load', function() { scrolltoanchor(); }); }); /** * creates a vertical navigation bar. */ function addverticalnavigation(){ $('body').append('
    '); nav = $('#fp-nav'); nav.css('color', options.navigationcolor); nav.addclass(options.navigationposition); for(var cont = 0; cont < $('.fp-section').length; cont++){ var link = ''; if(options.anchors.length){ link = options.anchors[cont]; } var tooltip = options.navigationtooltips[cont]; if(typeof tooltip === 'undefined'){ tooltip = ''; } nav.find('ul').append('
  • '); } } function createslimscrollinghandler(){ $('.fp-section').each(function(){ var slides = $(this).find('.fp-slide'); if(slides.length){ slides.each(function(){ createslimscrolling($(this)); }); }else{ createslimscrolling($(this)); } }); $.isfunction( options.afterrender ) && options.afterrender.call( this); } var scrollid; var isscrolling = false; //when scrolling... $(window).on('scroll', scrollhandler); function scrollhandler(){ if(!options.autoscrolling){ var currentscroll = $(window).scrolltop(); var scrolledsections = $('.fp-section').map(function(){ if ($(this).offset().top < (currentscroll + 100)){ return $(this); } }); //geting the last one, the current one on the screen var currentsection = scrolledsections[scrolledsections.length-1]; //executing only once the first time we reach the section if(!currentsection.hasclass('active')){ isscrolling = true; var leavingsection = $('.fp-section.active').index('.fp-section') + 1; var ymovement = getymovement(currentsection); var anchorlink = currentsection.data('anchor'); currentsection.addclass('active').siblings().removeclass('active'); $.isfunction( options.onleave ) && options.onleave.call( this, leavingsection, (currentsection.index('.fp-section') + 1), ymovement); $.isfunction( options.afterload ) && options.afterload.call( this, anchorlink, (currentsection.index('.fp-section') + 1)); activatemenuelement(anchorlink); activatenavdots(anchorlink, 0); if(options.anchors.length && !ismoving){ //needed to enter in hashchange event when using the menu with anchor links lastscrolleddestiny = anchorlink; location.hash = anchorlink; } //small timeout in order to avoid entering in hashchange event when scrolling is not finished yet cleartimeout(scrollid); scrollid = settimeout(function(){ isscrolling = false; }, 100); } } } /** * determines whether the active section or slide is scrollable through and scrolling bar */ function isscrollable(activesection){ //if there are landscape slides, we check if the scrolling bar is in the current one or not if(activesection.find('.fp-slides').length){ scrollable= activesection.find('.fp-slide.active').find('.fp-scrollable'); }else{ scrollable = activesection.find('.fp-scrollable'); } return scrollable; } /** * determines the way of scrolling up or down: * by 'automatically' scrolling a section or by using the default and normal scrolling. */ function scrolling(type, scrollable){ if(type == 'down'){ var check = 'bottom'; var scrollsection = $.fn.fullpage.movesectiondown; }else{ var check = 'top'; var scrollsection = $.fn.fullpage.movesectionup; } if(scrollable.length > 0 ){ //is the scrollbar at the start/end of the scroll? if(isscrolled(check, scrollable)){ scrollsection(); }else{ return true; } }else{ // moved up/down scrollsection(); } } var touchstarty = 0; var touchstartx = 0; var touchendy = 0; var touchendx = 0; /* detecting touch events * as we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. * this way, the touchstart and the touch moves shows an small difference between them which is the * used one to determine the direction. */ function touchmovehandler(event){ var e = event.originalevent; if(options.autoscrolling){ //preventing the easing on ios devices event.preventdefault(); } // additional: if one of the normalscrollelements isn't within options.normalscrollelementtouchthreshold hops up the dom chain if (!checkparentfornormalscrollelement(event.target)) { var activesection = $('.fp-section.active'); var scrollable = isscrollable(activesection); if (!ismoving && !slidemoving) { //if theres any # var touchevents = geteventspage(e); touchendy = touchevents['y']; touchendx = touchevents['x']; //if movement in the x axys is greater than in the y and the currect section has slides... if (activesection.find('.fp-slides').length && math.abs(touchstartx - touchendx) > (math.abs(touchstarty - touchendy))) { //is the movement greater than the minimum resistance to scroll? if (math.abs(touchstartx - touchendx) > ($(window).width() / 100 * options.touchsensitivity)) { if (touchstartx > touchendx) { $.fn.fullpage.moveslideright(); //next } else { $.fn.fullpage.moveslideleft(); //prev } } } //vertical scrolling (only when autoscrolling is enabled) else if(options.autoscrolling){ //is the movement greater than the minimum resistance to scroll? if (math.abs(touchstarty - touchendy) > ($(window).height() / 100 * options.touchsensitivity)) { if (touchstarty > touchendy) { scrolling('down', scrollable); } else if (touchendy > touchstarty) { scrolling('up', scrollable); } } } } } } /** * recursive function to loop up the parent nodes to check if one of them exists in options.normalscrollelements * currently works well for ios - android might need some testing * @param {element} el target element / jquery selector (in subsequent nodes) * @param {int} hop current hop compared to options.normalscrollelementtouchthreshold * @return {boolean} true if there is a match to options.normalscrollelements */ function checkparentfornormalscrollelement (el, hop) { hop = hop || 0; var parent = $(el).parent(); if (hop < options.normalscrollelementtouchthreshold && parent.is(options.normalscrollelements) ) { return true; } else if (hop == options.normalscrollelementtouchthreshold) { return false; } else { return checkparentfornormalscrollelement(parent, ++hop); } } function touchstarthandler(event){ var e = event.originalevent; var touchevents = geteventspage(e); touchstarty = touchevents['y']; touchstartx = touchevents['x']; } /** * detecting mousewheel scrolling * * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html * http://www.sitepoint.com/html5-javascript-mouse-wheel/ */ function mousewheelhandler(e) { if(options.autoscrolling){ // cross-browser wheel delta e = window.event || e; var delta = math.max(-1, math.min(1, (e.wheeldelta || -e.deltay || -e.detail))); var activesection = $('.fp-section.active'); var scrollable = isscrollable(activesection); if (!ismoving) { //if theres any # //scrolling down? if (delta < 0) { scrolling('down', scrollable); //scrolling up? }else { scrolling('up', scrollable); } } return false; } } $.fn.fullpage.movesectionup = function(){ var prev = $('.fp-section.active').prev('.fp-section'); //looping to the bottom if there's no more sections above if (!prev.length && (options.looptop || options.continuousvertical)) { prev = $('.fp-section').last(); } if (prev.length) { scrollpage(prev, null, true); } }; $.fn.fullpage.movesectiondown = function (){ var next = $('.fp-section.active').next('.fp-section'); //looping to the top if there's no more sections below if(!next.length && (options.loopbottom || options.continuousvertical)){ next = $('.fp-section').first(); } if(next.length){ scrollpage(next, null, false); } }; $.fn.fullpage.moveto = function (section, slide){ var destiny = ''; if(isnan(section)){ destiny = $('[data-anchor="'+section+'"]'); }else{ destiny = $('.fp-section').eq( (section -1) ); } if (typeof slide !== 'undefined'){ scrollpageandslide(section, slide); }else if(destiny.length > 0){ scrollpage(destiny); } }; $.fn.fullpage.moveslideright = function(){ moveslide('next'); }; $.fn.fullpage.moveslideleft = function(){ moveslide('prev'); }; function moveslide(direction){ var activesection = $('.fp-section.active'); var slides = activesection.find('.fp-slides'); // more than one slide needed and nothing should be sliding if (!slides.length || slidemoving) { return; } var currentslide = slides.find('.fp-slide.active'); var destiny = null; if(direction === 'prev'){ destiny = currentslide.prev('.fp-slide'); }else{ destiny = currentslide.next('.fp-slide'); } //isn't there a next slide in the secuence? if(!destiny.length){ //respect loophorizontal settin if (!options.loophorizontal) return; if(direction === 'prev'){ destiny = currentslide.siblings(':last'); }else{ destiny = currentslide.siblings(':first'); } } slidemoving = true; landscapescroll(slides, destiny); } /** * maintains the active slides in the viewport * (because he `scroll` animation might get lost with some actions, such as when using continuousvertical) */ function keepslidesposition(){ $('.fp-slide.active').each(function(){ silentlandscapescroll($(this)); }); } function scrollpage(element, callback, ismovementup){ var scrolloptions = {}, scrolledelement; var dest = element.position(); if(typeof dest === "undefined"){ return; } //there's no element to scroll, leaving the function var dtop = dest.top; var ymovement = getymovement(element); var anchorlink = element.data('anchor'); var sectionindex = element.index('.fp-section'); var activeslide = element.find('.fp-slide.active'); var activesection = $('.fp-section.active'); var leavingsection = activesection.index('.fp-section') + 1; //caching the value of isresizing at the momment the function is called //because it will be checked later inside a settimeout and the value might change var localisresizing = isresizing; if(activeslide.length){ var slideanchorlink = activeslide.data('anchor'); var slideindex = activeslide.index(); } // if continuousvertical && we need to wrap around if (options.autoscrolling && options.continuousvertical && typeof (ismovementup) !== "undefined" && ((!ismovementup && ymovement == 'up') || // intending to scroll down but about to go up or (ismovementup && ymovement == 'down'))) { // intending to scroll up but about to go down // scrolling down if (!ismovementup) { // move all previous sections to after the active section $(".fp-section.active").after(activesection.prevall(".fp-section").get().reverse()); } else { // scrolling up // move all next sections to before the active section $(".fp-section.active").before(activesection.nextall(".fp-section")); } // maintain the displayed position (now that we changed the element order) silentscroll($('.fp-section.active').position().top); // maintain the active slides visible in the viewport keepslidesposition(); // save for later the elements that still need to be reordered var wraparoundelements = activesection; // recalculate animation variables dest = element.position(); dtop = dest.top; ymovement = getymovement(element); } element.addclass('active').siblings().removeclass('active'); //preventing from activating the mousewheelhandler event //more than once if the page is scrolling ismoving = true; if(typeof anchorlink !== 'undefined'){ seturlhash(slideindex, slideanchorlink, anchorlink); } if(options.autoscrolling){ scrolloptions['top'] = -dtop; scrolledelement = '.'+wrapperselector; }else{ scrolloptions['scrolltop'] = dtop; scrolledelement = 'html, body'; } // fix section order after continuousvertical changes have been animated var continuousverticalfixsectionorder = function () { // if continuousvertical is in effect (and autoscrolling would also be in effect then), // finish moving the elements around so the direct navigation will function more simply if (!wraparoundelements || !wraparoundelements.length) { return; } if (ismovementup) { $('.fp-section:first').before(wraparoundelements); } else { $('.fp-section:last').after(wraparoundelements); } silentscroll($('.fp-section.active').position().top); // maintain the active slides visible in the viewport keepslidesposition(); }; //actions to do once the section is loaded var aftersectionloads = function(){ continuousverticalfixsectionorder(); //callback (afterload) if the site is not just resizing and readjusting the slides $.isfunction(options.afterload) && !localisresizing && options.afterload.call(this, anchorlink, (sectionindex + 1)); settimeout(function () { ismoving = false; $.isfunction(callback) && callback.call(this); }, scrolldelay); } //callback (onleave) if the site is not just resizing and readjusting the slides $.isfunction(options.onleave) && !localisresizing && options.onleave.call(this, leavingsection, (sectionindex + 1), ymovement); // use css3 translate functionality or... if (options.css3 && options.autoscrolling) { var translate3d = 'translate3d(0px, -' + dtop + 'px, 0px)'; transformcontainer(translate3d, true); settimeout(function () { aftersectionloads(); }, options.scrollingspeed); } else { // ... use jquery animate $(scrolledelement).animate( scrolloptions , options.scrollingspeed, options.easing, function () { aftersectionloads(); }); } //flag to avoid callingn `scrollpage()` twice in case of using anchor links lastscrolleddestiny = anchorlink; //avoid firing it twice (as it does also on scroll) if(options.autoscrolling){ activatemenuelement(anchorlink); activatenavdots(anchorlink, sectionindex); } } function scrolltoanchor(){ //getting the anchor link in the url and deleting the `#` var value = window.location.hash.replace('#', '').split('/'); var section = value[0]; var slide = value[1]; if(section){ //if theres any # scrollpageandslide(section, slide); } } //detecting any change on the url to scroll to the given anchor link //(a way to detect back history button as we play with the hashes on the url) $(window).on('hashchange', hashchangehandler); function hashchangehandler(){ if(!isscrolling){ var value = window.location.hash.replace('#', '').split('/'); var section = value[0]; var slide = value[1]; if(section.length){ //when moving to a slide in the first section for the first time (first time to add an anchor to the url) var isfirstslidemove = (typeof lastscrolleddestiny === 'undefined'); var isfirstscrollmove = (typeof lastscrolleddestiny === 'undefined' && typeof slide === 'undefined' && !slidemoving); /*in order to call scrollpage() only once for each destination at a time it is called twice for each scroll otherwise, as in case of using anchorlinks `hashchange` event is fired on every scroll too.*/ if ((section && section !== lastscrolleddestiny) && !isfirstslidemove || isfirstscrollmove || (!slidemoving && lastscrolledslide != slide )) { scrollpageandslide(section, slide); } } } } /** * sliding with arrow keys, both, vertical and horizontal */ $(document).keydown(function(e) { //moving the main page with the keyboard arrows if keyboard scrolling is enabled if (options.keyboardscrolling && !ismoving) { switch (e.which) { //up case 38: case 33: $.fn.fullpage.movesectionup(); break; //down case 40: case 34: $.fn.fullpage.movesectiondown(); break; //home case 36: $.fn.fullpage.moveto(1); break; //end case 35: $.fn.fullpage.moveto( $('.fp-section').length ); break; //left case 37: $.fn.fullpage.moveslideleft(); break; //right case 39: $.fn.fullpage.moveslideright(); break; default: return; // exit this handler for other keys } } }); /** * scrolls to the section when clicking the navigation bullet */ $(document).on('click touchstart', '#fp-nav a', function(e){ e.preventdefault(); var index = $(this).parent().index(); scrollpage($('.fp-section').eq(index)); }); /** * scrolls the slider to the given slide destination for the given section */ $(document).on('click touchstart', '.fp-slidesnav a', function(e){ e.preventdefault(); var slides = $(this).closest('.fp-section').find('.fp-slides'); var destiny = slides.find('.fp-slide').eq($(this).closest('li').index()); landscapescroll(slides, destiny); }); //navigation tooltips $(document).on({ mouseenter: function(){ var tooltip = $(this).data('tooltip'); $('
    ' + tooltip + '
    ').hide().appendto($(this)).fadein(200); }, mouseleave: function(){ $(this).find('.fp-tooltip').fadeout(200, function() { $(this).remove(); }); } }, '#fp-nav li'); if(options.normalscrollelements){ $(document).on('mouseenter', options.normalscrollelements, function () { $.fn.fullpage.setmousewheelscrolling(false); }); $(document).on('mouseleave', options.normalscrollelements, function(){ $.fn.fullpage.setmousewheelscrolling(true); }); } /** * scrolling horizontally when clicking on the slider controls. */ $('.fp-section').on('click touchstart', '.fp-controlarrow', function() { if ($(this).hasclass('fp-prev')) { $.fn.fullpage.moveslideleft(); } else { $.fn.fullpage.moveslideright(); } }); /** * scrolling horizontally when clicking on the slider controls. */ $('.fp-section').on('click', '.toslide', function(e) { e.preventdefault(); var slides = $(this).closest('.fp-section').find('.fp-slides'); var currentslide = slides.find('.fp-slide.active'); var destiny = null; destiny = slides.find('.fp-slide').eq( ($(this).data('index') -1) ); if(destiny.length > 0){ landscapescroll(slides, destiny); } }); /** * scrolls horizontal sliders. */ function landscapescroll(slides, destiny){ var destinypos = destiny.position(); var slidescontainer = slides.find('.fp-slidescontainer').parent(); var slideindex = destiny.index(); var section = slides.closest('.fp-section'); var sectionindex = section.index('.fp-section'); var anchorlink = section.data('anchor'); var slidesnav = section.find('.fp-slidesnav'); var slideanchor = destiny.data('anchor'); //caching the value of isresizing at the momment the function is called //because it will be checked later inside a settimeout and the value might change var localisresizing = isresizing; if(options.onslideleave){ var prevslideindex = section.find('.fp-slide.active').index(); var xmovement = getxmovement(prevslideindex, slideindex); //if the site is not just resizing and readjusting the slides if(!localisresizing){ $.isfunction( options.onslideleave ) && options.onslideleave.call( this, anchorlink, (sectionindex + 1), prevslideindex, xmovement); } } destiny.addclass('active').siblings().removeclass('active'); if(typeof slideanchor === 'undefined'){ slideanchor = slideindex; } if(!options.loophorizontal){ //hidding it for the fist slide, showing for the rest section.find('.fp-controlarrow.fp-prev').toggle(slideindex!=0); //hidding it for the last slide, showing for the rest section.find('.fp-controlarrow.fp-next').toggle(!destiny.is(':last-child')); } //only changing the url if the slides are in the current section (not for resize re-adjusting) if(section.hasclass('active')){ seturlhash(slideindex, slideanchor, anchorlink); } var afterslideloads = function(){ //if the site is not just resizing and readjusting the slides if(!localisresizing){ $.isfunction( options.afterslideload ) && options.afterslideload.call( this, anchorlink, (sectionindex + 1), slideanchor, slideindex); } //letting them slide again slidemoving = false; }; if(options.css3){ var translate3d = 'translate3d(-' + destinypos.left + 'px, 0px, 0px)'; slides.find('.fp-slidescontainer').toggleclass('fp-easing', options.scrollingspeed>0).css(gettransforms(translate3d)); settimeout(function(){ afterslideloads(); }, options.scrollingspeed, options.easing); }else{ slidescontainer.animate({ scrollleft : destinypos.left }, options.scrollingspeed, options.easing, function() { afterslideloads(); }); } slidesnav.find('.active').removeclass('active'); slidesnav.find('li').eq(slideindex).find('a').addclass('active'); } //when resizing the site, we adjust the heights of the sections, slimscroll... $(window).resize(resizehandler); var resizeid; function resizehandler(){ // rebuild immediately on touch devices if (istouchdevice) { $.fn.fullpage.rebuild(); }else{ //in order to call the functions only when the resize is finished //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing cleartimeout(resizeid); resizeid = settimeout($.fn.fullpage.rebuild, 500); } } /** * when resizing is finished, we adjust the slides sizes and positions */ $.fn.fullpage.rebuild = function(){ isresizing = true; var windowswidth = $(window).width(); windowsheight = $(window).height(); //text and images resizing if (options.resize) { resizeme(windowsheight, windowswidth); } $('.fp-section').each(function(){ var scrollheight = windowsheight - parseint($(this).css('padding-bottom')) - parseint($(this).css('padding-top')); //adjusting the height of the table-cell for ie and firefox if(options.verticalcentered){ $(this).find('.fp-tablecell').css('height', gettableheight($(this)) + 'px'); } $(this).css('height', windowsheight + 'px'); //resizing the scrolling divs if(options.scrolloverflow){ var slides = $(this).find('.fp-slide'); if(slides.length){ slides.each(function(){ createslimscrolling($(this)); }); }else{ createslimscrolling($(this)); } } //adjusting the position fo the full width slides... var slides = $(this).find('.fp-slides'); if (slides.length) { landscapescroll(slides, slides.find('.fp-slide.active')); } }); //adjusting the position for the current section var destinypos = $('.fp-section.active').position(); var activesection = $('.fp-section.active'); //isn't it the first section? if(activesection.index('.fp-section')){ scrollpage(activesection); } isresizing = false; $.isfunction( options.afterresize ) && options.afterresize.call( this); } /** * resizing of the font size depending on the window size as well as some of the images on the site. */ function resizeme(displayheight, displaywidth) { //standard dimensions, for which the body font size is correct var preferredheight = 825; var preferredwidth = 900; if (displayheight < preferredheight || displaywidth < preferredwidth) { var heightpercentage = (displayheight * 100) / preferredheight; var widthpercentage = (displaywidth * 100) / preferredwidth; var percentage = math.min(heightpercentage, widthpercentage); var newfontsize = percentage.tofixed(2); $("body").css("font-size", newfontsize + '%'); } else { $("body").css("font-size", '100%'); } } /** * activating the website navigation dots according to the given slide name. */ function activatenavdots(name, sectionindex){ if(options.navigation){ $('#fp-nav').find('.active').removeclass('active'); if(name){ $('#fp-nav').find('a[href="#' + name + '"]').addclass('active'); }else{ $('#fp-nav').find('li').eq(sectionindex).find('a').addclass('active'); } } } /** * activating the website main menu elements according to the given slide name. */ function activatemenuelement(name){ if(options.menu){ $(options.menu).find('.active').removeclass('active'); $(options.menu).find('[data-menuanchor="'+name+'"]').addclass('active'); } } /** * return a boolean depending on whether the scrollable element is at the end or at the start of the scrolling * depending on the given type. */ function isscrolled(type, scrollable){ if(type === 'top'){ return !scrollable.scrolltop(); }else if(type === 'bottom'){ return scrollable.scrolltop() + 1 + scrollable.innerheight() >= scrollable[0].scrollheight; } } /** * retuns `up` or `down` depending on the scrolling movement to reach its destination * from the current section. */ function getymovement(destiny){ var fromindex = $('.fp-section.active').index('.fp-section'); var toindex = destiny.index('.fp-section'); if(fromindex > toindex){ return 'up'; } return 'down'; } /** * retuns `right` or `left` depending on the scrolling movement to reach its destination * from the current slide. */ function getxmovement(fromindex, toindex){ if( fromindex == toindex){ return 'none' } if(fromindex > toindex){ return 'left'; } return 'right'; } function createslimscrolling(element){ //needed to make `scrollheight` work under opera 12 element.css('overflow', 'hidden'); //in case element is a slide var section = element.closest('.fp-section'); var scrollable = element.find('.fp-scrollable'); //if there was scroll, the contentheight will be the one in the scrollable section if(scrollable.length){ var contentheight = scrollable.get(0).scrollheight; }else{ var contentheight = element.get(0).scrollheight; if(options.verticalcentered){ contentheight = element.find('.fp-tablecell').get(0).scrollheight; } } var scrollheight = windowsheight - parseint(section.css('padding-bottom')) - parseint(section.css('padding-top')); //needs scroll? if ( contentheight > scrollheight) { //was there already an scroll ? updating it if(scrollable.length){ scrollable.css('height', scrollheight + 'px').parent().css('height', scrollheight + 'px'); } //creating the scrolling else{ if(options.verticalcentered){ element.find('.fp-tablecell').wrapinner('
    '); }else{ element.wrapinner('
    '); } element.find('.fp-scrollable').slimscroll({ allowpagescroll: true, height: scrollheight + 'px', size: '10px', alwaysvisible: true }); } } //removing the scrolling when it is not necessary anymore else{ removeslimscroll(element); } //undo element.css('overflow', ''); } function removeslimscroll(element){ element.find('.fp-scrollable').children().first().unwrap().unwrap(); element.find('.slimscrollbar').remove(); element.find('.slimscrollrail').remove(); } function addtableclass(element){ element.addclass('fp-table').wrapinner('
    '); } function gettableheight(element){ var sectionheight = windowsheight; if(options.paddingtop || options.paddingbottom){ var section = element; if(!section.hasclass('fp-section')){ section = element.closest('.fp-section'); } var paddings = parseint(section.css('padding-top')) + parseint(section.css('padding-bottom')); sectionheight = (windowsheight - paddings); } return sectionheight; } /** * adds a css3 transform property to the container class with or without animation depending on the animated param. */ function transformcontainer(translate3d, animated){ container.toggleclass('fp-easing', animated); container.css(gettransforms(translate3d)); } /** * scrolls to the given section and slide */ function scrollpageandslide(destiny, slide){ if (typeof slide === 'undefined') { slide = 0; } if(isnan(destiny)){ var section = $('[data-anchor="'+destiny+'"]'); }else{ var section = $('.fp-section').eq( (destiny -1) ); } //we need to scroll to the section and then to the slide if (destiny !== lastscrolleddestiny && !section.hasclass('active')){ scrollpage(section, function(){ scrollslider(section, slide) }); } //if we were already in the section else{ scrollslider(section, slide); } } /** * scrolls the slider to the given slide destination for the given section */ function scrollslider(section, slide){ if(typeof slide != 'undefined'){ var slides = section.find('.fp-slides'); var destiny = slides.find('[data-anchor="'+slide+'"]'); if(!destiny.length){ destiny = slides.find('.fp-slide').eq(slide); } if(destiny.length){ landscapescroll(slides, destiny); } } } /** * creates a landscape navigation bar with dots for horizontal sliders. */ function addslidesnavigation(section, numslides){ section.append('
      '); var nav = section.find('.fp-slidesnav'); //top or bottom nav.addclass(options.slidesnavposition); for(var i=0; i< numslides; i++){ nav.find('ul').append('
    • '); } //centering it nav.css('margin-left', '-' + (nav.width()/2) + 'px'); nav.find('li').first().find('a').addclass('active'); } /** * sets the url hash for a section with slides */ function seturlhash(slideindex, slideanchor, anchorlink){ var sectionhash = ''; if(options.anchors.length){ //isn't it the first slide? if(slideindex){ if(typeof anchorlink !== 'undefined'){ sectionhash = anchorlink; } //slide without anchor link? we take the index instead. if(typeof slideanchor === 'undefined'){ slideanchor = slideindex; } lastscrolledslide = slideanchor; location.hash = sectionhash + '/' + slideanchor; //first slide won't have slide anchor, just the section one }else if(typeof slideindex !== 'undefined'){ lastscrolledslide = slideanchor; location.hash = anchorlink; } //section without slides else{ location.hash = anchorlink; } } } /** * checks for translate3d support * @return boolean * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support */ function support3d() { var el = document.createelement('p'), has3d, transforms = { 'webkittransform':'-webkit-transform', 'otransform':'-o-transform', 'mstransform':'-ms-transform', 'moztransform':'-moz-transform', 'transform':'transform' }; // add it to the body to get the computed style. document.body.insertbefore(el, null); for (var t in transforms) { if (el.style[t] !== undefined) { el.style[t] = "translate3d(1px,1px,1px)"; has3d = window.getcomputedstyle(el).getpropertyvalue(transforms[t]); } } document.body.removechild(el); return (has3d !== undefined && has3d.length > 0 && has3d !== "none"); } /** * removes the auto scrolling action fired by the mouse wheel and tackpad. * after this function is called, the mousewheel and trackpad movements won't scroll through sections. */ function removemousewheelhandler(){ if (document.addeventlistener) { document.removeeventlistener('mousewheel', mousewheelhandler, false); //ie9, chrome, safari, oper document.removeeventlistener('wheel', mousewheelhandler, false); //firefox } else { document.detachevent("onmousewheel", mousewheelhandler); //ie 6/7/8 } } /** * adds the auto scrolling action for the mouse wheel and tackpad. * after this function is called, the mousewheel and trackpad movements will scroll through sections */ function addmousewheelhandler(){ if (document.addeventlistener) { document.addeventlistener("mousewheel", mousewheelhandler, false); //ie9, chrome, safari, oper document.addeventlistener("wheel", mousewheelhandler, false); //firefox } else { document.attachevent("onmousewheel", mousewheelhandler); //ie 6/7/8 } } /** * adds the possibility to auto scroll through sections on touch devices. */ function addtouchhandler(){ if(istouchdevice || istouch){ //microsoft pointers mspointer = getmspointer(); $(document).off('touchstart ' + mspointer.down).on('touchstart ' + mspointer.down, touchstarthandler); $(document).off('touchmove ' + mspointer.move).on('touchmove ' + mspointer.move, touchmovehandler); } } /** * removes the auto scrolling for touch devices. */ function removetouchhandler(){ if(istouchdevice || istouch){ //microsoft pointers mspointer = getmspointer(); $(document).off('touchstart ' + mspointer.down); $(document).off('touchmove ' + mspointer.move); } } /* * returns and object with microsoft pointers (for ie<11 and for ie >= 11) * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx */ function getmspointer(){ var pointer; //ie >= 11 if(window.pointerevent){ pointer = { down: "pointerdown", move: "pointermove"}; } //ie < 11 else{ pointer = { down: "mspointerdown", move: "mspointermove"}; } return pointer; } /** * gets the pagex and pagey properties depending on the browser. * https://github.com/alvarotrigo/fullpage.js/issues/194#issuecomment-34069854 */ function geteventspage(e){ var events = new array(); if (window.navigator.mspointerenabled){ events['y'] = e.pagey; events['x'] = e.pagex; }else{ events['y'] = e.touches[0].pagey; events['x'] = e.touches[0].pagex; } return events; } function silentlandscapescroll(activeslide){ var prevscrollingspeepd = options.scrollingspeed; $.fn.fullpage.setscrollingspeed (0); landscapescroll(activeslide.closest('.fp-slides'), activeslide); $.fn.fullpage.setscrollingspeed(prevscrollingspeepd); } function silentscroll(top){ if (options.css3) { var translate3d = 'translate3d(0px, -' + top + 'px, 0px)'; transformcontainer(translate3d, false); } else { container.css("top", -top); } } function gettransforms(translate3d){ return { '-webkit-transform': translate3d, '-moz-transform': translate3d, '-ms-transform':translate3d, 'transform': translate3d }; } /* * destroys fullpage.js plugin events and optinally its html markup and styles */ $.fn.fullpage.destroy = function(all){ $.fn.fullpage.setautoscrolling(false); $.fn.fullpage.setallowscrolling(false); $.fn.fullpage.setkeyboardscrolling(false); $(window) .off('scroll', scrollhandler) .off('hashchange', hashchangehandler) .off('resize', resizehandler); $(document) .off('click', '#fp-nav a') .off('mouseenter', '#fp-nav li') .off('mouseleave', '#fp-nav li') .off('click', '.fp-slidesnav a') .off('mouseover', options.normalscrollelements) .off('mouseout', options.normalscrollelements); $('.fp-section') .off('click', '.fp-controlarrow') .off('click', '.toslide'); //lets make a mess! if(all){ destroystructure(); } }; /* * removes inline styles added by fullpage.js */ function destroystructure(){ //reseting the `top` or `translate` properties to 0 silentscroll(0); $('#fp-nav, .fp-slidesnav, .fp-controlarrow').remove(); //removing inline styles $('.fp-section').css( { 'height': '', 'background-color' : '', 'padding': '' }); $('.fp-slide').css( { 'width': '' }); container.css({ 'height': '', 'position': '', '-ms-touch-action': '', 'touch-action': '' }); //removing added classes $('.fp-section, .fp-slide').each(function(){ removeslimscroll($(this)); $(this).removeclass('fp-table active'); }) container.find('.fp-easing').removeclass('fp-easing'); //unwrapping content container.find('.fp-tablecell, .fp-slidescontainer, .fp-slides').each(function(){ //unwrap not being use in case there's no child element inside and its just text $(this).replacewith(this.childnodes); }); //scrolling the page to the top with no animation $('html, body').scrolltop(0); } }; })(jquery);