线性缓动减慢
Linear easing slows down
第一个问题:
无法弄清楚为什么 .animate linear 在到达目的地点时会变慢。
我错过了什么?
奇怪的是,从中间的图片向上看,它总是完美无缺(仅在这种情况下)。
第二题:
有没有办法在动画播放时禁止用户滚动?
[编辑]
图片我都剪掉了方便调试
[/编辑]
$(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()
不会 运行 线性,因为每次触发 scroll
事件时你都会调用它。发生这种情况是因为当您这样做时:
$("body").stop().animate({scrollTop: 0}, 700);
isScrolling = false;
计算机不会等待动画完成继续程序流程;相反,它启动动画并继续,立即将 false
分配给 isScrolling
变量。此外,您对 requestAnimationFrame
的使用不是必需的,它导致 isScrolling = true
之后 isScrolling = false
分配给 运行 几乎没有延迟 — 由于 asynchronous nature 这些功能。
这会导致 scroll
事件侦听器在每次触发时调用 animate()
函数,因为 isScrolling
永远不会是 true
.
问题可以通过等待animate()
回调将false
赋值给isScrolling
,移除requestAnimationFrame
调用和isScrolling = false;
赋值来解决.
最后一件事...
Weird thing is that going from middle pic upward it always works perfectly (only in that one case).
不,不是,但看起来是这样,因为你将它设置为 {scrollTop: -heightVal}
,而它应该是 {scrollTop: 0}
。
请注意,我非常非常推荐对函数和变量名进行广泛的重构。不到 30 分钟,除了您以外,没有人能理解您的代码。
这是上述所有更改的结果,包括更好的命名:
$(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>
第一个问题: 无法弄清楚为什么 .animate linear 在到达目的地点时会变慢。 我错过了什么?
奇怪的是,从中间的图片向上看,它总是完美无缺(仅在这种情况下)。
第二题: 有没有办法在动画播放时禁止用户滚动?
[编辑] 图片我都剪掉了方便调试 [/编辑]
$(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()
不会 运行 线性,因为每次触发 scroll
事件时你都会调用它。发生这种情况是因为当您这样做时:
$("body").stop().animate({scrollTop: 0}, 700);
isScrolling = false;
计算机不会等待动画完成继续程序流程;相反,它启动动画并继续,立即将 false
分配给 isScrolling
变量。此外,您对 requestAnimationFrame
的使用不是必需的,它导致 isScrolling = true
之后 isScrolling = false
分配给 运行 几乎没有延迟 — 由于 asynchronous nature 这些功能。
这会导致 scroll
事件侦听器在每次触发时调用 animate()
函数,因为 isScrolling
永远不会是 true
.
问题可以通过等待animate()
回调将false
赋值给isScrolling
,移除requestAnimationFrame
调用和isScrolling = false;
赋值来解决.
最后一件事...
Weird thing is that going from middle pic upward it always works perfectly (only in that one case).
不,不是,但看起来是这样,因为你将它设置为 {scrollTop: -heightVal}
,而它应该是 {scrollTop: 0}
。
请注意,我非常非常推荐对函数和变量名进行广泛的重构。不到 30 分钟,除了您以外,没有人能理解您的代码。
这是上述所有更改的结果,包括更好的命名:
$(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>