如何使用touchstart和touchend手势获取滚动的当前位置

时间:2012-08-01 13:30:36

标签: javascript ios webkit mobile-safari

好的,我会尝试尽可能地解释我想要做的事情。

使用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库来模仿效果并等到错误得到修复。

  • 主要原因是停止所需的时间总是在变化,因此为了准确读数,会有太多变量发生变化。

0 个答案:

没有答案