复杂的数学水平视差缓动函数
Complex mathematical horizontal parallax easing function
我目前正在研究 Web 上的视差效果。
Parallax scrolling is a technique in computer graphics and web design, where background images move by the camera slower than foreground images, creating an illusion of depth in a 2D scene and adding to the immersion.
~ Wikipedia
我想创建一个小容器(可以是图像,或任何块级元素)并在用户滚动时水平移动它。
效果应该可以在所有视口中缩放。这意味着元素正在移动的元素的高度和宽度无关紧要。
当用户滚动到屏幕高度的一半时,"moving element" 应该位于正中央。由于用户将滚动屏幕的一半,因此该元素将已经垂直。我们现在只担心横向。
这个问题我已经考虑了一段时间,并且想出了一个很好的主意。
获取您希望 "moving element" 移动的元素的高度和宽度。例如,屏幕高 1000 像素,宽 600 像素。
宽度除以高度。例如 (600px / 1000px = 3/5 = 0.6)
将用户滚动的像素数量乘以我们刚刚创建的数字。例如 (500px * 0.6 = 300px)。如您所见,这是准确的中心。
将元素在屏幕上移动刚刚计算的像素数量。
即使对于每个屏幕尺寸,此计算也能正常工作,但它是线性的。这意味着元素将始终以相同的速度在屏幕上移动。让我告诉你我的意思。
- 让我们画出一个屏幕尺寸。 (假设 1000 * 500)
- 为此图计算两个点 ->
screen factor: (500 / 1000) = 0.5
1. The first point is going to be easy. Let's say we scrolled exactly 0px -> (0.5 * 0) = 0
The "Moving element" will not have moved at all.
2. For the second element we'll take the center. Just for convenience.
垂直中心在 500px -> (0.5 * 500) = 250 px(正好是水平中心)
- 将结果放在图表中并通过点画一条线。
在上图中,您可以看到每当用户向下滚动时,"moving element" 将跟随该线(x 轴上的值)。
我的问题
我真的希望我描述得足够好,可以理解。现在回答我的问题。
我想要创建的是一个移动元素,它会在屏幕边缘移动得更快,在中间稍微慢一些。如果我们以与刚才相同的方式将其绘制出来。 (创建一个图表,我们可以在其中获取滚动的像素数量并查看元素应该水平放置的位置)它看起来像这样:
抱歉图像质量不佳,但这是我遇到问题的部分。
正如您在此图中所见,"moving element" 不会在图表中间移动那么多。 (我在我的绘图中做了一点,但你明白了大致的想法。)
我需要的是一个数学函数,它采用三个参数(屏幕高度、宽度和滚动的像素数量)和 returns "moving element" 的水平位置。
我的想法:
我的想法是将元素定位在页面的死角,然后根据滚动的距离左右移动它(使用 CSS 和 JavaScript 进行翻译) .
图表看起来像这样:
上面的(手绘)图表适用于 1000x600 像素的屏幕,因为 "moving element" 在未完成滚动时转换为 -300 像素,在滚动 100% 时转换为 300 像素。
但是我不知道如何创建适用于所有屏幕尺寸的数学函数。
为了清楚起见,我需要一个 "always" 从 Y= (-screen-width/2) 和 X = 0 开始的函数。它应该始终穿过点 (sreen-height; (screen-width) //2)) 并且函数应该是 x^3 的形式(为了得到正确的缓动)
我真的希望我自己解释得足够好,我真的希望有人能在这里帮助我。
您可以使用实际绘制该轨迹的函数 f 定位它。
这是我提出的想法:
- 创建函数轨迹 f 使得 f(0) = 0 和 f(1) = 1(添加更多约束以重现您正在寻找的效果, 例如: f(0.5) = 0.5)
- 在每个滚动事件中,将 x 设置为滚动量并使用坐标 (f(x) * (w - s), x * (h - s)) 定位元素,其中 w 是文档宽度, h是文档高度,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
来自math.stackexchange
的回答
除了在这里问我的问题外,我还继续在 math.stackexchange.com 上发布了这个问题。 Whosebug 的数学姊妹站点。有人帮我找到了问题的答案。
该函数必须是一个函数,该函数将根据自元素首次可见以来滚动的像素数量输出移动元素相对于页面水平中心的水平位置(以像素为单位)。该功能必须在边缘 "steeper" 并在中间缓和到一个短暂的停止,并且可以在所有可能的屏幕尺寸上使用。这意味着数学函数必须根据屏幕高度和宽度这两个变量来定位。
他们在 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 上有一个可用的示例。你可以找到它 here.
我目前正在研究 Web 上的视差效果。
Parallax scrolling is a technique in computer graphics and web design, where background images move by the camera slower than foreground images, creating an illusion of depth in a 2D scene and adding to the immersion. ~ Wikipedia
我想创建一个小容器(可以是图像,或任何块级元素)并在用户滚动时水平移动它。
效果应该可以在所有视口中缩放。这意味着元素正在移动的元素的高度和宽度无关紧要。
当用户滚动到屏幕高度的一半时,"moving element" 应该位于正中央。由于用户将滚动屏幕的一半,因此该元素将已经垂直。我们现在只担心横向。
这个问题我已经考虑了一段时间,并且想出了一个很好的主意。
获取您希望 "moving element" 移动的元素的高度和宽度。例如,屏幕高 1000 像素,宽 600 像素。
宽度除以高度。例如 (600px / 1000px = 3/5 = 0.6)
将用户滚动的像素数量乘以我们刚刚创建的数字。例如 (500px * 0.6 = 300px)。如您所见,这是准确的中心。
将元素在屏幕上移动刚刚计算的像素数量。
即使对于每个屏幕尺寸,此计算也能正常工作,但它是线性的。这意味着元素将始终以相同的速度在屏幕上移动。让我告诉你我的意思。
- 让我们画出一个屏幕尺寸。 (假设 1000 * 500)
- 为此图计算两个点 ->
screen factor: (500 / 1000) = 0.5 1. The first point is going to be easy. Let's say we scrolled exactly 0px -> (0.5 * 0) = 0 The "Moving element" will not have moved at all. 2. For the second element we'll take the center. Just for convenience.
垂直中心在 500px -> (0.5 * 500) = 250 px(正好是水平中心)
- 将结果放在图表中并通过点画一条线。
在上图中,您可以看到每当用户向下滚动时,"moving element" 将跟随该线(x 轴上的值)。
我的问题
我真的希望我描述得足够好,可以理解。现在回答我的问题。
我想要创建的是一个移动元素,它会在屏幕边缘移动得更快,在中间稍微慢一些。如果我们以与刚才相同的方式将其绘制出来。 (创建一个图表,我们可以在其中获取滚动的像素数量并查看元素应该水平放置的位置)它看起来像这样:
抱歉图像质量不佳,但这是我遇到问题的部分。
正如您在此图中所见,"moving element" 不会在图表中间移动那么多。 (我在我的绘图中做了一点,但你明白了大致的想法。)
我需要的是一个数学函数,它采用三个参数(屏幕高度、宽度和滚动的像素数量)和 returns "moving element" 的水平位置。
我的想法:
我的想法是将元素定位在页面的死角,然后根据滚动的距离左右移动它(使用 CSS 和 JavaScript 进行翻译) .
图表看起来像这样:
上面的(手绘)图表适用于 1000x600 像素的屏幕,因为 "moving element" 在未完成滚动时转换为 -300 像素,在滚动 100% 时转换为 300 像素。
但是我不知道如何创建适用于所有屏幕尺寸的数学函数。
为了清楚起见,我需要一个 "always" 从 Y= (-screen-width/2) 和 X = 0 开始的函数。它应该始终穿过点 (sreen-height; (screen-width) //2)) 并且函数应该是 x^3 的形式(为了得到正确的缓动)
我真的希望我自己解释得足够好,我真的希望有人能在这里帮助我。
您可以使用实际绘制该轨迹的函数 f 定位它。
这是我提出的想法:
- 创建函数轨迹 f 使得 f(0) = 0 和 f(1) = 1(添加更多约束以重现您正在寻找的效果, 例如: f(0.5) = 0.5)
- 在每个滚动事件中,将 x 设置为滚动量并使用坐标 (f(x) * (w - s), x * (h - s)) 定位元素,其中 w 是文档宽度, h是文档高度,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
来自math.stackexchange
的回答除了在这里问我的问题外,我还继续在 math.stackexchange.com 上发布了这个问题。 Whosebug 的数学姊妹站点。有人帮我找到了问题的答案。
该函数必须是一个函数,该函数将根据自元素首次可见以来滚动的像素数量输出移动元素相对于页面水平中心的水平位置(以像素为单位)。该功能必须在边缘 "steeper" 并在中间缓和到一个短暂的停止,并且可以在所有可能的屏幕尺寸上使用。这意味着数学函数必须根据屏幕高度和宽度这两个变量来定位。
他们在 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)