好的,我会尝试尽可能地解释我想要做的事情。
使用Webkit-overflow-scrolling我正在创建一个具有可堆叠标题的列表,就像iPhone联系人应用程序提供的效果一样。例如。 'A'保持在顶部,直到'B'移开它等等。这在桌面上或用户仍在滚动时相对容易。
然而,一旦用户轻弹滚动条,它会以慢速减速滚动,在此期间不会触发任何事件,直到滚动条完全停止,此时为时已晚。
经过大量研究后,我发现轻弹减速持续时间始终相同(约2.4秒),只是结束位置发生变化。我还可以看到很多人通过创建自己的库来模仿iOS行为来解决这个问题,这可能是我唯一的选择。
我正试图通过获取来自动滚动元素的滚动顶部:
这应该允许我在发生之前跟踪位置和最终结果。但是,我对如何正确使用此信息以获得所需结果感到困惑。任何信息或指针都会非常有用。
修改
在遇到物理问题后,我问Physics stackexchange并收到此answer
因此我相信这段代码应该有效。我想检查以确保我将正确的逻辑应用于它
var timeStart = new Date().getTime(); //Triggered on a touchstart event
var timeEnd = new Date.getTime(); //Triggered on a touchend event
var startY = event.originalEvent.targetTouches.pageY //Pulled in from different functions containing the events
var endY = event.originalEvent.changeTouches[0].pageY //The where the touch starts and ends in px
var timeElasped = timeEnd - timeStart;
var distance = startY - endY;
var velocity = distance/timeElasped;
var result = velocity * (timeElasped - (1/4.8)*(timeElasped*timeElasped))
因此,结果应该与触发最终滚动事件时scrollTop生成的结果相同。
编辑2
可悲的是似乎没有用。因此,我不能给出正确信息的公式。
不确定我的位置是否正在接受或者我如何执行公式。
编辑3
我认为卷轴速度确实每隔325毫秒减少0.95倍。我从这个有用的article找到了这些信息。
这一观察让我相信动量滚动是一种指数衰减。它的特点是腐烂的速度。表达它有两种不同的方式:半衰期(记得放射性衰变?)或时间常数。对于后者,它与一阶系统的阶跃响应非常相关。换句话说,减速系统只是一个过阻尼的弹簧质量系统。事实证明,一切都仍然基于物理学。
amplitude = initialVelocity * scaleFactor;
step = 0;
ticker = setInterval(function() {
var delta = amplitude / timeConstant;
position += delta;
amplitude -= delta;
step += 1;
if (step > 6 * timeConstant) {
clearInterval(ticker);
}
}, updateInterval);
事实上,这就是Apple自己的PastryKit库(现在是iAd的一部分)实现减速的方式。对于每个动画节拍(16.7毫秒,目标为60 fps),它将滚动速度降低0.95倍。这对应于325毫秒的时间常数。如果你是一个数学极客,那么显然你意识到滚动速度的指数性质将产生位置的指数衰减。通过一点点涂鸦,最终你会发现325是-16.7 / ln(0.95)。
这个Google Doc应该显示公式,希望我正确地做到了。左边是标准公式。在右边,我试图将速度降低0.95(速度* 0.95)。我已经从我的测试中添加了真实信息,以显示我遇到的问题。如果所有方程都是正确的并且以正确的逻辑方式完成,则必须是数据进入。
编辑4
经过许多痛苦的时间后,我得出结论,这是针对safari mobile的webkit中的一个错误。最好的选择是使用JS库来模仿效果并等到错误得到修复。