Just a quick snippet
Forked from Chrysto's Pen Fullscreen slides with TweenLite, CSSPlugin and ScrollToPlugin.
A Pen by Captain Anonymous on CodePen.
Just a quick snippet
Forked from Chrysto's Pen Fullscreen slides with TweenLite, CSSPlugin and ScrollToPlugin.
A Pen by Captain Anonymous on CodePen.
<nav> | |
<ul> | |
<li><a href="#slide-1">Slide 1</a></li> | |
<li><a href="#slide-2">Slide 2</a></li> | |
<li><a href="#slide-3">Slide 3</a></li> | |
<li><a href="#slide-4">Slide 4</a></li> | |
</ul> | |
</nav> | |
<div class="slides-container"> | |
<div class="slide" id="slide-1"> | |
<div class="centered"> | |
<h1>Fullscreen slides with GSAP</h1> | |
<p>Let's go to the <span class="go-next">next slide</span>.</p> | |
</div> | |
</div> | |
<div class="slide" id="slide-2"> | |
<div class="centered"> | |
<h1>It is so easy to navigate through slides</h1> | |
<p>You can go back to <span class="go-prev">previous slide</span> or go to the <span class="go-next">next slide</span>.</p> | |
</div> | |
</div> | |
<div class="slide" id="slide-3"> | |
<div class="centered"> | |
<h1>Use mouse wheel</h1> | |
<p>No, really. Try to scroll up and down with the mouse wheel to switch between slides.</p> | |
</div> | |
</div> | |
<div class="slide" id="slide-4"> | |
<div class="centered"> | |
<h1>... Or use keyboard arrows</h1> | |
<p>You go to previous and next slide, using up and down keyboard arrows.</p> | |
</div> | |
</div> | |
</div> | |
//First the variables our app is going to use need to be declared | |
//References to DOM elements | |
var $window = $(window); | |
var $document = $(document); | |
//Only links that starts with # | |
var $navButtons = $("nav a").filter("[href^=#]"); | |
var $navGoPrev = $(".go-prev"); | |
var $navGoNext = $(".go-next"); | |
var $slidesContainer = $(".slides-container"); | |
var $slides = $(".slide"); | |
var $currentSlide = $slides.first(); | |
//Animating flag - is our app animating | |
var isAnimating = false; | |
//The height of the window | |
var pageHeight = $window.innerHeight(); | |
//Key codes for up and down arrows on keyboard. We'll be using this to navigate change slides using the keyboard | |
var keyCodes = { | |
UP : 38, | |
DOWN: 40 | |
} | |
//Going to the first slide | |
goToSlide($currentSlide); | |
/* | |
* Adding event listeners | |
* */ | |
$window.on("resize", onResize).resize(); | |
$window.on("mousewheel DOMMouseScroll", onMouseWheel); | |
$document.on("keydown", onKeyDown); | |
$navButtons.on("click", onNavButtonClick); | |
$navGoPrev.on("click", goToPrevSlide); | |
$navGoNext.on("click", goToNextSlide); | |
/* | |
* Internal functions | |
* */ | |
/* | |
* When a button is clicked - first get the button href, and then slide to the container, if there's such a container | |
* */ | |
function onNavButtonClick(event) | |
{ | |
//The clicked button | |
var $button = $(this); | |
//The slide the button points to | |
var $slide = $($button.attr("href")); | |
//If the slide exists, we go to it | |
if($slide.length) | |
{ | |
goToSlide($slide); | |
event.preventDefault(); | |
} | |
} | |
/* | |
* Getting the pressed key. Only if it's up or down arrow, we go to prev or next slide and prevent default behaviour | |
* This way, if there's text input, the user is still able to fill it | |
* */ | |
function onKeyDown(event) | |
{ | |
var PRESSED_KEY = event.keyCode; | |
if(PRESSED_KEY == keyCodes.UP) | |
{ | |
goToPrevSlide(); | |
event.preventDefault(); | |
} | |
else if(PRESSED_KEY == keyCodes.DOWN) | |
{ | |
goToNextSlide(); | |
event.preventDefault(); | |
} | |
} | |
/* | |
* When user scrolls with the mouse, we have to change slides | |
* */ | |
function onMouseWheel(event) | |
{ | |
//Normalize event wheel delta | |
var delta = event.originalEvent.wheelDelta / 30 || -event.originalEvent.detail; | |
//If the user scrolled up, it goes to previous slide, otherwise - to next slide | |
if(delta < -1) | |
{ | |
goToNextSlide(); | |
} | |
else if(delta > 1) | |
{ | |
goToPrevSlide(); | |
} | |
event.preventDefault(); | |
} | |
/* | |
* If there's a previous slide, slide to it | |
* */ | |
function goToPrevSlide() | |
{ | |
if($currentSlide.prev().length) | |
{ | |
goToSlide($currentSlide.prev()); | |
} | |
} | |
/* | |
* If there's a next slide, slide to it | |
* */ | |
function goToNextSlide() | |
{ | |
if($currentSlide.next().length) | |
{ | |
goToSlide($currentSlide.next()); | |
} | |
} | |
/* | |
* Actual transition between slides | |
* */ | |
function goToSlide($slide) | |
{ | |
//If the slides are not changing and there's such a slide | |
if(!isAnimating && $slide.length) | |
{ | |
//setting animating flag to true | |
isAnimating = true; | |
$currentSlide = $slide; | |
//Sliding to current slide | |
TweenLite.to($slidesContainer, 1, {scrollTo: {y: pageHeight * $currentSlide.index() }, onComplete: onSlideChangeEnd, onCompleteScope: this}); | |
//Animating menu items | |
TweenLite.to($navButtons.filter(".active"), 0.5, {className: "-=active"}); | |
TweenLite.to($navButtons.filter("[href=#" + $currentSlide.attr("id") + "]"), 0.5, {className: "+=active"}); | |
} | |
} | |
/* | |
* Once the sliding is finished, we need to restore "isAnimating" flag. | |
* You can also do other things in this function, such as changing page title | |
* */ | |
function onSlideChangeEnd() | |
{ | |
isAnimating = false; | |
} | |
/* | |
* When user resize it's browser we need to know the new height, so we can properly align the current slide | |
* */ | |
function onResize(event) | |
{ | |
//This will give us the new height of the window | |
var newPageHeight = $window.innerHeight(); | |
/* | |
* If the new height is different from the old height ( the browser is resized vertically ), the slides are resized | |
* */ | |
if(pageHeight !== newPageHeight) | |
{ | |
pageHeight = newPageHeight; | |
//This can be done via CSS only, but fails into some old browsers, so I prefer to set height via JS | |
TweenLite.set([$slidesContainer, $slides], {height: pageHeight + "px"}); | |
//The current slide should be always on the top | |
TweenLite.set($slidesContainer, {scrollTo: {y: pageHeight * $currentSlide.index() }}); | |
} | |
} |
body, div, p { | |
margin: 0; | |
padding: 0; | |
} | |
body { | |
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; | |
font-weight: 300; | |
letter-spacing: 0.0625em; | |
} | |
a { | |
text-decoration: none; | |
} | |
nav { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
z-index: 100; | |
} | |
nav ul { | |
list-style: none; | |
text-align: center; | |
margin-top: 30px; | |
} | |
nav ul li { | |
display: inline-block; | |
margin-right: 20px; | |
} | |
nav ul li:last-child { | |
margin-right: 0; | |
} | |
#back-to-tutorial { | |
margin-left: 100px; | |
} | |
nav a { | |
position: relative; | |
top: 0; | |
padding: 10px 20px; | |
font-weight: normal; | |
font-size: 20px; | |
text-align: center; | |
border-radius: 4px; | |
background-color: #FFFFFF; | |
color: #83C78E; | |
-webkit-box-shadow: none; | |
-moz-box-shadow: none; | |
box-shadow: none; | |
} | |
nav a.active { | |
top: -4px; | |
background-color: #69C773; | |
color: #FFFFFF; | |
-webkit-box-shadow: 0 4px 0 0 #51a65f; | |
-moz-box-shadow: 0 4px 0 0 #51a65f; | |
box-shadow: 0 4px 0 0 #51a65f; | |
} | |
.slides-container { | |
position: absolute; | |
left: 0; | |
top: 0; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
z-index: 10; | |
} | |
.slide { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
.slide .centered { | |
width: 60%; | |
margin: 200px auto 0; | |
} | |
.slide .centered h1 { | |
text-align: center; | |
} | |
.slide .centered p { | |
text-align: center; | |
margin-top: 20px; | |
font-size: 20px; | |
} | |
#slide-1 { | |
background-color: #FFFFFF; | |
} | |
#slide-2 { | |
background-color: #45959b; | |
} | |
#slide-3 { | |
background-color: #778899; | |
} | |
#slide-4 { | |
color: #FFFFFF; | |
background-color: #291F37; | |
} | |
.go-prev, .go-next { | |
cursor: pointer; | |
font-weight: bold; | |
text-decoration: underline; | |
} |