1st question: Can't figure out why .animate linear slows down when it comes to its destination point. What am I missing ?
Weird thing is that going from middle pic upward it always works perfectly (only in that one case).
2nd question: Is there a way to disable user from scrolling while animation is on-going ?
[edit] I have cut out pictures so it is easier to debug [/edit]
$(document).ready( function (){
var scrollCheck = 0;
var heightVal = window.innerHeight;
$(window).resize(function(){
window.scroll(0,0);
heightVal = window.innerHeight;
hControl1 = heightVal -1;
scrollCheck = 0;
});
var isScrolling = false;
window.addEventListener("scroll", throttleScroll, false);
function throttleScroll(e) {
if (isScrolling == false) {
window.requestAnimationFrame(function() {
scrolling(e);
isScrolling = false;
//console.log("Scrolling");
});
}
isScrolling = true;
}
document.addEventListener("DOMContentLoaded", scrolling, false);
function scrolling(e) {
var yValue = $(window).scrollTop();
//1st photo, scroll down
if ( yValue > 0 && scrollCheck === 0 ){
$('body').stop().animate({scrollTop:heightVal}, 700, 'linear');
if ( window.pageYOffset === heightVal ){
scrollCheck = 1;
//console.log(window.pageYOffset);
}
}//2nd photo, scroll up
else if( yValue < heightVal && scrollCheck === 1 ){
$('body').stop().animate({scrollTop:(-heightVal)}, 700, 'linear');
if ( window.pageYOffset === 0 ){
scrollCheck = 0;
}
}//2nd photo, scroll down
else if( yValue > heightVal && scrollCheck === 1 ){
$('body').stop().animate({scrollTop:(heightVal*2)}, 700, 'linear');
if ( window.pageYOffset === (heightVal*2) ){
scrollCheck = 2;
}
}//3rd photo, scroll up
else if( yValue < heightVal*2 && scrollCheck === 2){
$('body').stop().animate({scrollTop:(heightVal)}, 700, 'linear');
if ( window.pageYOffset === heightVal ){
scrollCheck = 1;
}
}
}//end of scrolling(e) funcion
}); //end of $(document).ready
html,body{
margin: 0;
height: 100%;
width: 100%;
}
#section1,#section2,#section3{
height: 100%;
width: 100%;
vertical-align: top;
}
#section1{
background-color: grey;
}
#section2{
background-color: green;
}
#section3{
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='section1'></div>
<div id='section2'></div>
<div id='section3'></div>
animate()
won't run linearly because you're calling it every time the scroll
event is triggered. This happens because when you do this:
$("body").stop().animate({scrollTop: 0}, 700);
isScrolling = false;
The computer doesn't wait for the animation to complete to continue the program flow; instead, it starts the animation and procceeds, assigning false
to the isScrolling
variable immediately. In addition, your usage of requestAnimationFrame
wasn't necessary, and it led the isScrolling = false
assignment to run after isScrolling = true
with virtually no delay — due to the asynchronous nature of those functions.
This causes the scroll
event listener to call the animate()
function every time it's triggered, because isScrolling
is never true
.
The problem can be solved by waiting for the animate()
callback to assign false
to isScrolling
, removing the requestAnimationFrame
call and it's isScrolling = false;
assignment.
One last thing...
Weird thing is that going from middle pic upward it always works perfectly (only in that one case).
No, it doesn't, but it looks like so because you set it to {scrollTop: -heightVal}
, while it should be {scrollTop: 0}
.
Note that I highly, HIGHLY recommend an extensive refactoring of functions and variable names. No one other than you can understand your code in less than 30 minutes.
Here's the result of all the changes above mentioned, including better naming:
$(document).ready( function (){
var currentSection = 0;
var windowHeight = window.innerHeight;
$(window).resize(function(){
window.scroll(0,0);
windowHeight = window.innerHeight;
hControl1 = windowHeight -1;
currentSection = 0;
});
var isScrolling = false;
window.addEventListener("scroll", scrollSnappingController, false);
function scrollSnappingController(e) {
if (isScrolling === false) {
snapScrollToNextSection(e);
console.log("first")
isScrolling = true;
console.log("second")
}
}
function scrollEnded () {
isScrolling = false;
}
document.addEventListener("DOMContentLoaded", snapScrollToNextSection, false);
var section1 = $("#section1");
var section2 = $("#section2");
var section3 = $("#section3");
function snapScrollToNextSection(e) {
var scrollPosition = $(window).scrollTop();
//1st photo goin down
if ( scrollPosition > 0 && currentSection === 0 ){
$('body').stop().animate({scrollTop: windowHeight}, 700, 'linear', scrollEnded);
if ( scrollPosition === windowHeight ){
currentSection = 1;
}
}
else if( scrollPosition < windowHeight && currentSection === 1 ){
$('body').stop().animate({scrollTop:(0)}, 700, 'linear', scrollEnded);
if ( scrollPosition === 0 ){
currentSection = 0;
}
}
else if( scrollPosition > windowHeight && currentSection === 1 ){
$('body').stop().animate({scrollTop:(windowHeight*2)}, 700, 'linear', scrollEnded);
if ( scrollPosition === (windowHeight*2) ){
currentSection = 2;
}
}
else if( scrollPosition < windowHeight*2 && currentSection === 2){
$('body').stop().animate({scrollTop:(windowHeight)}, 700, 'linear', scrollEnded);
if ( scrollPosition === windowHeight ){
currentSection = 1;
}
}
}
});
html,body{
margin: 0;
height: 100%;
width: 100%;
}
img{
display: block;
height:100%;
width:100%;
margin: 0;
padding:0;
}
#section1,#section2,#section3{
height: 100%;
width: 100%;
vertical-align: top;
}
#section1{
background-color: grey;
}
#section2{
background-color: green;
}
#section3{
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='section1'></div>
<div id='section2'></div>
<div id='section3'></div>