0

我目前正在研究网络上的视差效果。

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

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

效果应该可以跨所有视口进行缩放。这意味着元素正在移动的元素的高度和宽度应该无关紧要。

当用户滚动了屏幕高度的一半时,“移动元素”应该在精确的中心。由于用户将滚动屏幕的一半,因此元素已经是垂直的。我们现在只担心水平方向。

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


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

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

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

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


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


  1. 让我们画出一个屏幕尺寸。(假设 1000 * 500)
  2. 计算此图的两个点 ->

屏幕系数:(500 / 1000) = 0.5 1. 第一点很容易。假设我们滚动了 0px -> (0.5 * 0) = 0 “移动元素”根本不会移动。2. 对于第二个元素,我们将占据中心。只是为了方便。

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

  1. 将结果放在图表中,并在这些点之间画一条线。 图形

在上图中,您可以看到,每当用户向下滚动时,“移动元素”将跟随这条线(x 轴上的值)。

我的问题

我真的希望我描述得足够好,可以理解。现在谈谈我的问题。

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

手绘图

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

正如您在此图中看到的那样,“移动元素”不会在图中间移动那么多。(我在我的画中做了一点,但你明白了。)

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


我的想法:

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

该图看起来像这样:

图3

上面的(手绘)图表适用于 1000x600 像素的屏幕,因为“移动元素”在未完成滚动时转换为 -300 像素,在滚动 100% 时转换为 300 像素。

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

为了清楚起见,我需要一个“始终”从 Y= (-screen-width/2) 和 X = 0 开始的函数。它应该始终穿过点 (sreen-height; (screen-width//2)) 和函数应该是 x^3 的形式(为了获得正确的缓动)


我真的希望我能很好地解释自己,我真的希望有人能在这里帮助我。

4

2 回答 2

1

来自 math.stackexchange 的回答

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

该函数必须是一个函数,该函数将输出移动元素它相对于页面水平中心的水平位置(以像素为单位),基于从元素第一次可见以来滚动的像素量。该功能必须在边缘“更陡峭”,并在中间短暂停留,并且可以在所有可能的屏幕尺寸上使用。这意味着必须根据两个变量(屏幕高度和-宽度)定位数学函数。


他们在 math.stackexchange 上得出的答案:

数学函数

在此示例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 上有一个工作示例。你可以在这里找到它。

于 2017-03-29T13:42:53.910 回答
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 是文档height 和 s 是元素的大小

我可以看到三次函数被绘制成你想要的轨迹,所以我一直在用不同的函数进行测试,我有这个工作示例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

于 2017-03-28T22:02:05.160 回答