自定义视差滚动问题

时间:2015-09-16 22:42:23

标签: javascript jquery parallax

我有一个网站的自定义视差滚动部分。各个地方都有气泡,它们都以不同的速度滚动。

http://goo.gl/jZhVrJ(你会发现讲话气泡在页面的一半)

第一次向下滚动时,一切正常,元素位于我想要的位置。以下是它应该如何显示的屏幕截图:

enter image description here

但是,如果您向后滚动到顶部,然后再次向下 - 每次返回该部分时,气泡的位置都不同。如果你做了足够多次,你可以将语音气泡完全置于该内容块之外。这是最终看起来不正确的屏幕截图: enter image description here

这里的一般概念是我已定位每个语音泡泡。然后,当用户滚动代码时,更改“顶部”按钮。每个泡沫的属性。如果用户向下滚动,则会缩小“顶部”。值。如果它们向上滚动,则会增加顶部'值。每个气泡都是不同的放大镜,因此气泡似乎以不同的速度移动。

这也使用" inview"插件所以滚动只在用户在视图中有该块时发生。

以下是进行视差滚动的JS代码:

var $window = $(window);
var windowHeight = $window.height();
var $quoteBG = $('.philosophy');
var quote1 = $("#quote1");
var quote2 = $("#quote2");
var quote3 = $("#quote3");
var quote4 = $("#quote4");
var quote5 = $("#quote5");
var quote6 = $("#quote6");
var quote7 = $("#quote7");
var quote8 = $("#quote8");
var quote9 = $("#quote9");

var scrolldirection = '-';
var lastScrollTop = 0;
var modifier = '-';
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
       scrolldirection = 'down';
   } else {
      scrolldirection = 'up';
   }
   lastScrollTop = st;
});

//function to be called whenever the window is scrolled or resized
function Move(){ 

    //if the second section is in view...
    if($quoteBG.hasClass("inview")){

        if ( scrolldirection == 'down' ) {
            modifier = '-';
        } else {
            modifier = '+';
        }

        quote1.css( 'top', modifier+'=2');
        quote2.css( 'top', modifier+'=1');
        quote3.css( 'top', modifier+'=3');
        quote4.css( 'top', modifier+'=2.1');
        quote5.css( 'top', modifier+'=2.5');
        quote6.css( 'top', modifier+'=3');
        quote7.css( 'top', modifier+'=2');
        quote8.css( 'top', modifier+'=1.5');
        quote9.css( 'top', modifier+'=3');

    }
}

$window.resize(function(){ //if the user resizes the window...
    Move(); //move the background images in relation to the movement of the scrollbar
});        

$window.bind('scroll', function(){ //when the user is scrolling...
    Move(); //move the background images in relation to the movement of the scrollbar
});

1 个答案:

答案 0 :(得分:1)

我不得不将以下代码添加到您的小提琴中以使其正常工作:

$quoteBG.on('inview', function (evt, isInView) {
    if (isInView) {
        $quoteBG.addClass("inview");
    }
    else {
        $quoteBG.removeClass("inview");
    }
});

固定版本位于:http://jsfiddle.net/up15ns6t/2/

玩完之后,我发现了几个问题。

第一个问题是我从一开始就怀疑的:你的位置计算是通过每次滚动事件触发时加上或减去固定数量来完成的。这样做的问题是,无论窗口滚动多远,您都要进行相同的调整。例如,当窗口在事件之间滚动1个像素并且在事件之间滚动100个像素时,您将第一个引用调整为2像素。这使得结果不确定。

如果我这样做,我会尝试提出一种确定性算法,根据窗口的滚动位置计算每个报价的位置。或者,您可以尝试使用加/减方法,但在计算中包括自上次事件以来窗口滚动的数量。

我在玩它时注意到的另一件事是,当父div(.philosophy)被隐藏时,位置不会更新。因此,如果您继续滚动查看,引号会逐渐爬升。此行为是由以下代码行引起的:

if($quoteBG.hasClass("inview")){

你需要包含一个"或者之前在视图中#34;这个逻辑的案例。

我现在没有更多时间玩它并想出一个可行的版本,但也许你可以使用这些想法让它发挥作用。

更新1
我在你的小提琴中创建了一个简单的确定性算法,并将其应用于单引号div,以防止事情变得太混乱。它首先计算可见的背景div的数量:

var windowHeight = $window.height();
var backgroundTop = Math.round($quoteBG.offset().top);
var st = $window.scrollTop();
var visibleHeight = (windowHeight + st) - backgroundTop;

如果背景div低于视图端口的底部,则visibleHeight值将为负数。一旦变为正数,我就会基于此计算报价div的新位置。

在页面加载时,我记录了引用div的初始位置并为其定义了一个运动比率:

var motion1 = 0.5;
var baseTop1 = $quote1.position().top;

滚动时,我会将这些与visibleHeight结合使用来计算引用的位置:

var position1 = baseTop1 + Math.round(visibleHeight * motion1)

因此,在此示例中,引号以背景速度的一半向下滚动(由于motion1 = 0.5)。

更新的小提琴在这里:http://jsfiddle.net/up15ns6t/5/

需要注意的一点是,位置计算不能处理报价偏离背景底部的情况。如果你想在它下面添加一些东西,你可能需要添加一些检查以防止引用移动得太远。