HTML
<div id="cbp-fbscroller" class="cbp-fbscroller"> <nav> <a href="#fbsection1" class="cbp-fbcurrent">Section 1</a> <a href="#fbsection2">Section 2</a> <a href="#fbsection3">Section 3</a> <a href="#fbsection4">Section 4</a> <a href="#fbsection5">Section 5</a> </nav> <section id="fbsection1"></section> <section id="fbsection2"></section> <section id="fbsection3"></section> <section id="fbsection4"></section> <section id="fbsection5"></section> </div>
CSS
/* Set all parents to full height */ html,body,.container,.cbp-fbscroller,.cbp-fbscroller section { height:100%; } /* The nav is fixed on the right side and we center it by translating it 50% (we don't know it's height so we can't use the negative margin trick) */ .cbp-fbscroller > nav { position:fixed; z-index:9999; right:100px; top:50%; -webkit-transform:translateY(-50%); -moz-transform:translateY(-50%); -ms-transform:translateY(-50%); transform:translateY(-50%); } .cbp-fbscroller > nav a { display:block; position:relative; color:transparent; height:50px; } .cbp-fbscroller > nav a:after { content:''; position:absolute; width:24px; height:24px; border-radius:50%; border:4px solid #fff; } .cbp-fbscroller > nav a:hover:after { background:rgba(255,255,255,0.6); } .cbp-fbscroller > nav a.cbp-fbcurrent:after { background:#fff; } /* background-attachment does the trick */ .cbp-fbscroller section { position:relative; background-position:top center; background-repeat:no-repeat; background-size:cover; background-attachment:fixed; } #fbsection1 { background-image:url(../images/1.jpg); } #fbsection2 { background-image:url(../images/2.jpg); } #fbsection3 { background-image:url(../images/3.jpg); } #fbsection4 { background-image:url(../images/4.jpg); } #fbsection5 { background-image:url(../images/5.jpg);
JavaScript
var cbpFixedScrollLayout = (function() { // cache and initialize some values var config = { // the cbp-fbscroller′s sections $sections : $( '#cbp-fbscroller > section' ), // the navigation links $navlinks : $( '#cbp-fbscroller > nav:first > a' ), // index of current link / section currentLink : 0, // the body element $body : $( 'html, body' ), // the body animation speed animspeed : 650, // the body animation easing (jquery easing) animeasing : 'easeInOutExpo' }; function init() { // click on a navigation link: the body is scrolled to the position of the respective section config.$navlinks.on( 'click', function() { scrollAnim( config.$sections.eq( $( this ).index() ).offset().top ); return false; } ); // 2 waypoints defined: // First one when we scroll down: the current navigation link gets updated. // A `new section′ is reached when it occupies more than 70% of the viewport // Second one when we scroll up: the current navigation link gets updated. // A `new section′ is reached when it occupies more than 70% of the viewport config.$sections.waypoint( function( direction ) { if( direction === 'down' ) { changeNav( $( this ) ); } }, { offset: '30%' } ).waypoint( function( direction ) { if( direction === 'up' ) { changeNav( $( this ) ); } }, { offset: '-30%' } ); // on window resize: the body is scrolled to the position of the current section $( window ).on( 'debouncedresize', function() { scrollAnim( config.$sections.eq( config.currentLink ).offset().top ); } ); } // update the current navigation link function changeNav( $section ) { config.$navlinks.eq( config.currentLink ).removeClass( 'cbp-fbcurrent' ); config.currentLink = $section.index( 'section' ); config.$navlinks.eq( config.currentLink ).addClass( 'cbp-fbcurrent' ); } // function to scroll / animate the body function scrollAnim( top ) { config.$body.stop().animate( { scrollTop : top }, config.animspeed, config.animeasing ); } return { init : init }; })();