/**
* 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);