Javascript 了解滚动动画的工作原理
我正在我的网站上制作一个Javascript 了解滚动动画的工作原理,javascript,scroll,Javascript,Scroll,我正在我的网站上制作一个滚动到功能,并以此为基础。因为我不想只是复制和粘贴代码,我正在努力理解它。除了scrollToX函数中的数学部分,我能够理解一切(花了我两天时间!) element.scrollTop = xFrom - (xFrom - xTo) * motion(t01); t01 += speed * step; 我理解实际的数学,但我不明白它为什么有效。为什么数学会产生滚动动画 document.getElementsByTagName('button')[0]。oncli
滚动到功能,并以此为基础。因为我不想只是复制和粘贴代码,我正在努力理解它。除了scrollToX函数中的数学部分
,我能够理解一切(花了我两天时间!)
element.scrollTop = xFrom - (xFrom - xTo) * motion(t01);
t01 += speed * step;
我理解实际的数学,但我不明白它为什么有效。为什么数学会产生滚动动画
document.getElementsByTagName('button')[0]。onclick=function(){
滚动至(0,1000);
}
//要移动的元素,设置动画的时间(毫秒)
函数滚动到(元素、持续时间){
var e=document.documentElement;
如果(如scrollTop==0){
var t=e.scrollTop;
++e、 滚动顶;
e=t+1==e.scrollTop-?e:document.body;
}
scrollToC(e,e.scrollTop,元素,持续时间);
}
//要移动的元素,元素或像素从,元素或像素到,设置动画的时间(毫秒)
函数scrollToC(元素、起始、结束、持续时间){
如果(持续时间1 | |速度,那么您在示例中碰巧传递的运动函数是easeOutCubic
,其定义为
function easeOutCubic(t) {
t--;
return t * t * t + 1;
}
首先,每次调用scrollToX
时,将t递增speed*step
。由于这两个变量在函数范围内都是常量,t
将以恒定速率接近1。如果将t
递减1,则函数运行到在间隔(0,1)
。当您不断调用scrollToX
时,(t-1)^3+1
将变大,但速度较慢。这是因为t
不断变大,则(t-1)
的绝对值会不断减小,并且因为(t-1)
始终小于0,(t-1)^3
将以递减率接近0,因此(t-1)^3+1
将以相同的递减率接近1。这一切都可以通过以下事实更简洁地表达:所有t<1
的d^2((t-1)^3)/dt^2<0
,但决定给出更详尽的解释
您可以将函数motion(t)
视为一个介于0和1之间的系数,乘以最终行驶距离或(xFrom xTo)
,以计算特定时间点的总行驶距离
编辑(摘自我在下面删除的评论):
t
是一个变量,其值与调用scrollToX
的次数成正比,因为scrollToX
在特定的时间间隔(或多或少)被调用,该值是时间的函数。现在我们将该数字插入任何运动函数中。现在我们以linearTween
为例,因为它只返回输入
当您将t
从0增加到.02到.04时,运动(t)
将以恒定速率增加。您可以将运动(t)
相乘,这将产生一个介于0和1之间的数字(该值将随时间变化,最终达到值1),然后将其乘以要行驶的总距离,(xFrom xTo)
,以查找特定t
的较短行驶距离。从原点xFrom
减去该较短的最终行驶距离,即可获得滚动条在特定t
处的位置
可视示例:
xTo = 100
|
|
||
||
||
xFrom = 200
竖条的第一列表示移动的总距离,在本例中等于100。第二行竖条表示运动(t)=0.6(任意选择)时移动的距离。如果我们想在运动(t)=0.6时找到滚动条顶部的位置,我们必须计算200-(100)*0.6,或一般形式的运动(t)
首先,让我引用运动的定义
tf = t0 + delta(t)
运动是位置随时间的数值变化
上述内容可以写成:
pf = p0 + motion(time)
where:
- p0 = initial position
- pf = final position
运动只有在时间存在时才能存在,因此它是时间的函数。因为任何位置都是通过运动从初始位置到达的,所以我们也可以说位置是时间的函数
上面是典型的y=f(x)
2d函数,假设函数是一条直线,运动超过1秒,函数将绘制为
该行的长度由以下公式给出:
m = (pf - p0) / (1 - 0) = pf - p0 (1)
当0
时,斜率将帮助我们找到px
,因为属于直线的任意两点的斜率相同,因此
m = (px - p0) / (t - 0) = (px - p0) / t (2)
在(2)
中替换(1)
,并查找px的值
pf - p0 = (px - p0) / t
t * (pf - p0) = px - p0
px = p0 + (pf - p0) * t
这正是你原来的方程(减号是由你方程中的某些原因分解的)
还请注意:
- 如果
t=0
则px=p0
- 如果
t=1
则px=pf
现在,关于t
的值,我们知道0感谢您提供了详细的答案!在讨论motion(t01)
之前,我想了解它是如何工作的以及为什么工作的:element.scrollTop=xFrom-(xFrom-xTo)*motion(t01);t01+=速度*步长;
现在让我们假设运动
等于linearTween
,(它只是返回参数中的内容,)上面的数学是如何以及为什么工作的?xFrom-(xFrom-xTo)*运动(t01)
,是一个lerp函数。如果我们替换运动(t01)
使用t
我们得到xFrom*(1-t)+xTo*t
。xFrom和xTo是一个星形和端点,而t(从0到1)插值xFrom和xTo(例如,t=0.3表示xFrom*70%+xTo*30%).因此,如果我们以一定的速度增加t,我们可以得到一个以该速度从xFrom到xTo的数字。但这看起来很无聊,这就是运动函数的原因。该函数获取随时间不断增加的t并重新采样
motion(0) = 0
motion(1) = 1
const linear = t => t
const quadratic = t => t * t
px = p0 + (pf - p0) * motion(t)
tf = t0 + delta(t)
px = p0 + (pf - p0) * motion(t0)
tf = t0 + k * delta(t)
// the final time will be the initial time for the next iteration
t0 = tf
k = 1 / duration