复杂的数学水平视差缓和函数

时间:2017-03-28 12:37:26

标签: javascript jquery math parallax math-functions

我目前正在深入研究网络上的视差效应。

  

视差滚动是计算机图形和网页设计中的一种技术,其中背景图像通过相机移动比前景图像慢,在2D场景中创建深度幻觉并增加沉浸感。   〜维基百科

我想创建一个小容器(可以是图像或任何块级元素),并在用户滚动时在屏幕上水平移动它。

效果应该可以在所有视口中展开。这意味着元素移动的元素的高度和宽度无关紧要。

当用户滚动屏幕高度的一半时,“移动元素”应位于确切的中心。由于用户将滚动屏幕的一半,因此元素将垂直。我们现在只是横向担心。

我已经考虑过这个问题了一段时间,并想出了一个很好的想法。

  1. 获取您希望“移动元素”移动的元素的高度和宽度。例如,高1000像素,宽600像素的屏幕。

  2. 将宽度除以高度。例如(600px / 1000px = 3/5 = 0.6)

  3. 获取用户滚动的像素数量,并将其乘以我们刚刚创建的数字。例如(500px * 0.6 = 300px)。如您所见,这是确切的中心。

  4. 将元素在屏幕上按刚刚计算的像素数量移动。

  5. 即使对于每个屏幕尺寸,此计算也能正常工作,但它是线性的。这意味着元素将始终以相同的速度在屏幕上移动。让我告诉你我的意思。

    1. 让我们画一个屏幕尺寸。 (比方说1000 * 500)
    2. 计算此图表的两个点 - >
    3.   

      屏幕因子:(500/1000)= 0.5   1.第一点很简单。假设我们正好滚动0px - > (0.5 * 0)= 0   “移动元素”根本不会移动。   对于第二个元素,我们将占据中心位置。为方便起见。

      垂直中心为500px - > (0.5 * 500)= 250 px(正好是水平中心)

      1. 将结果放入图表中并在点中绘制一条线。 graph
      2. 在上图中,您可以看到每当用户向下滚动时,“移动元素”将跟随该行(x轴上的值)。

        我的问题

        我真的希望我能够很好地理解这一切。现在回答我的问题。

        我想要创建的是一个移动元素,它会在屏幕边缘变得更快,并在中间减慢一点。如果我们以与我们刚刚相同的方式绘制出来。 (创建一个图表,我们可以在其中滚动像素数量并查看元素应该水平放置的位置)它看起来像这样:

        Hand drawn graph

        很抱歉图像质量不佳,但这是我遇到问题的部分。

        正如您在此图中所看到的,“移动元素”在图形中间不会移动太多。 (我在绘图中做了一点但是你得到了一般的想法。)

        我需要的是一个数学函数,它采用三个参数(屏幕高度,宽度和滚动的像素数量)并返回“移动元素”的水平位置。

        我的想法:

        我的想法是将元素放置在页面的死点,然后根据滚动的距离左右移动(使用CSS和JavaScript进行翻译)。

        图表看起来像这样:

        Graph-3

        上面的(手绘)图表适用于1000x600px的屏幕,因为“移动元素”在没有滚动时转换为-300px而在滚动100%时转换为300px。

        但是我不知道如何创建一个对每个屏幕尺寸都适用的数学函数。

        要清楚我需要一个“始终”从Y =( - screen-width / 2)和X = 0开始的功能。它应该总是越过点(sreen-height;(屏幕宽度// 2) )并且函数应该是x ^ 3的形式(为了得到正确的缓和)

        我真的希望我能够很好地解释自己,我真的希望有人可以帮助我。

2 个答案:

答案 0 :(得分:1)

来自math.stackexchange的回答

除了在这里提出我的问题之外,我还继续将这个问题发布在math.stackexchange.com上。 Stackoverflow的数学姐妹网站。那里有人帮我找到了我的问题的答案。

该函数必须是一个函数,根据自元素首次可见时滚动的像素数量,相对于页面的水平中心输出移动元素的水平位置(以像素为单位)。该功能必须在边缘“更陡峭”,并在中间轻松停留,并可用于每个可能的屏幕尺寸。这意味着必须根据两个变量(屏幕高度和宽度)来定位数学函数。

他们在math.stackexchange上提出了答案:

math function

在此示例中,s-width是屏幕的宽度(以像素为单位)。 s-height是屏幕的高度(以像素为单位)。 px-scrolled是自元素首次可见以来滚动的像素数量。

输出pos是相对于屏幕中心的移动元素水平位置(以像素为单位)。

如果您将所有这些数学运算放入JavaScript中,您将获得以下结果:

var pos = ((4*win_width)/(Math.pow(win_height, 3))) * Math.pow(px_since_visible - (win_height/2),3)

在codepen上有一个工作示例。你可以找到它here

答案 1 :(得分:0)

您可以使用实际绘制该轨迹的函数 f 来定位它。

这是我提出的想法:

  1. 创建函数轨迹 f ,使f(0)= 0,f(1)= 1(添加更多约束以重现您正在寻找的效果,例如:f( 0.5)= 0.5)
  2. 在每个滚动事件中,将x设置为滚动的数量,并使用坐标(f(x)*(w - s),x *(h - s))定位元素,其中w是文档宽度,h是文档高度,s是元素的大小
  3. 我可以看到立方函数被绘制成你想要的轨迹,所以我一直在测试不同的函数,我有这个有效的例子https://codepen.io/anon/pen/YZJxGa

    var element = $('.element')
    var height = $(document).height()
    var scrollable = $('body').height() - $(window).height()
    var width = $('body').width();
    
    $(window).scroll(function () {
      var winH = $(window).scrollTop()
      var x;
    
      // Determine the amount of px scrolled since the element first came into view.
      console.log(winH, scrollable)
      x = (winH/scrollable) > 1 ? 1 : (winH/scrollable);
    
      var posY = x * (height - 120);
      var posX = (-1.000800320128*x
    +6.0024009603841*x**2-4.0016006402561*x**3)*(width - 120)
    
      console.log(posY)
    
      if (x > 0) { 
        console.log(`translate(${posX}px, ${posY}px, 0)`)
        element.css({
          'transform': `translate3d(${posX}px, ${posY}px, 0)`
          })
      }
    })
    

    您可以使用我刚刚找到http://skisickness.com/2010/04/28/的工具生成更多立方函数,或者使用您只想找到a,b,c和d的值来解决几个线性方程组的问题 f(x)= ax ^ 3 + bx ^ 2 + cx + d