Velocity - Scroll Hijacking
by Leon Freire
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.2/velocity.ui.min.js"></script>
<!-- hijacking: on/off - animation: none/scaleDown/rotate/gallery/catch/opacity/fixed/parallax -->
<body data-hijacking="on" data-animation="scaleDown">
<section class="cd-section visible">
<div>
<h2>Page Scroll Effects</h2>
</div>
</section>
<section class="cd-section">
<div>
<h2>Section 2</h2>
</div>
</section>
<section class="cd-section">
<div>
<h2>Section 3</h2>
</div>
</section>
<section class="cd-section">
<div>
<h2>Section 4</h2>
</div>
</section>
<section class="cd-section">
<div>
<h2>Section 5</h2>
</div>
</section>
<nav>
<ul class="cd-vertical-nav">
<li><a href="#0" class="cd-prev inactive">Next</a></li>
<li><a href="#0" class="cd-next">Prev</a></li>
</ul>
</nav>
<!-- .cd-vertical-nav -->
</body>
CSS
/* --------------------------------
Primary style
-------------------------------- */
*,
*::after,
*::before {
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
font-family: "Open Sans", sans-serif;
color: #ffffff;
background-color: #22283f;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body::before {
/* never visible - this is used in jQuery to check the current MQ */
content: 'mobile';
display: none;
}
@media only screen and (min-width: 1050px) {
body::before {
/* never visible - this is used in jQuery to check the current MQ */
content: 'desktop';
}
}
a {
color: #267481;
text-decoration: none;
}
/* --------------------------------
Main Components
-------------------------------- */
@media only screen and (min-width: 1050px) {
body[data-hijacking="on"] {
overflow: hidden;
}
}
.cd-section {
height: 100vh;
}
.cd-section h2 {
line-height: 100vh;
text-align: center;
font-size: 2.4rem;
}
.cd-section:first-of-type > div {
background-color: #2b334f;
}
.cd-section:first-of-type > div::before {
/* alert -> all scrolling effects are not visible on small devices */
content: 'Effects not visible on mobile!';
position: absolute;
width: 100%;
text-align: center;
top: 20px;
z-index: 2;
font-weight: bold;
font-size: 1.3rem;
text-transform: uppercase;
color: #6a7083;
}
.cd-section:nth-of-type(2) > div {
background-color: #2e5367;
}
.cd-section:nth-of-type(3) > div {
background-color: #267481;
}
.cd-section:nth-of-type(4) > div {
background-color: #fcb052;
}
.cd-section:nth-of-type(5) > div {
background-color: #f06a59;
}
[data-animation="parallax"] .cd-section > div,
[data-animation="fixed"] .cd-section > div,
[data-animation="opacity"] .cd-section > div {
background-position: center center;
background-repeat: no-repeat;
background-size: cover;
}
[data-animation="parallax"] .cd-section:first-of-type >...
JavaScript
jQuery(document).ready(function($) {
//variables
var hijacking = $('body').data('hijacking'),
animationType = $('body').data('animation'),
delta = 0,
scrollThreshold = 5,
actual = 1,
animating = false;
//DOM elements
var sectionsAvailable = $('.cd-section'),
verticalNav = $('.cd-vertical-nav'),
prevArrow = verticalNav.find('a.cd-prev'),
nextArrow = verticalNav.find('a.cd-next');
//check the media query and bind corresponding events
var MQ = deviceType(),
bindToggle = false;
bindEvents(MQ, true);
$(window).on('resize', function() {
MQ = deviceType();
bindEvents(MQ, bindToggle);
if (MQ == 'mobile') bindToggle = true;
if (MQ == 'desktop') bindToggle = false;
});
function bindEvents(MQ, bool) {
if (MQ == 'desktop' && bool) {
//bind the animation to the window scroll event, arrows click and keyboard
if (hijacking == 'on') {
initHijacking();
$(window).on('DOMMouseScroll mousewheel', scrollHijacking);
} else {
scrollAnimation();
$(window).on('scroll', scrollAnimation);
}
prevArrow.on('click', prevSection);
nextArrow.on('click', nextSection);
$(document).on('keydown', function(event) {
if (event.which == '40' && !nextArrow.hasClass('inactive')) {
event.preventDefault();
nextSection();
} else if (event.which == '38' && (!prevArrow.hasClass('inactive') || (prevArrow.hasClass('inactive') && $(window).scrollTop() != sectionsAvailable.eq(0).offset().top))) {
event.preventDefault();
prevSection();
}
});
//set navigation arrows visibility
checkNavigation();
} else if (MQ == 'mobile') {
//reset and unbind
resetSectionStyle();
$(window).off('DOMMouseScroll mousewheel', scrollHijacking);
$(window).off('scroll', scrollAnimation);
prevArrow.off('click', prevSection);
nextArrow.off('click', nextSection);
...