拖动时处理速度/惯性

Handling Velocity/Inertia on Dragging

本文关键字:惯性 处理速度 拖动      更新时间:2023-09-26

我在 Hammer.js 的鼠标和触摸拖动事件的支持下,在我的 Web 应用程序中构建了一个垂直滑块的东西。在拖动结束时(当用户释放鼠标按钮或将手指移离屏幕时,也称为dragend事件),如果上面的一个靠近中间,它就会移动到中间,反之亦然。

问题是,当用户将鼠标从下向上拖动时,当 dragend 事件以 48% 的速度触发时(这意味着上面的那个将被移动到中间),如果速度足够高,下面的那个应该移动到中间。如何计算速度是否足够高?

我是这样解决的:

// y is the drag amount
// visible height
var height = $(this).height()
// difference
var diff = (Math.abs(y) % height) / height
// I checked Hammer.js's source. It defines velocity as the change in 16ms.
// So multiplying it by 62.5 gives you the change in 1s. 
// Not sure why I did that, but works pretty well in most situations
var inertia = event.gesture.velocityY * 62.5
if (
    (event.gesture.direction == 'up' && diff + (inertia / height) >= 0.5) ||
    (event.gesture.direction == 'down' && diff - (inertia / height) >= 0.5)
) {
    // show the one below
} else {
    // show the one above
}

在Microsoft的 WPF(现在是开源的)中,惯性速度基于最后几个位置值(及其关联的时间戳)的加权移动平均值。

参见 ManipulationSequence.cs 和 OnCompletedManipulation() 方法(目前从第 558 行开始)。在CalculateWeightedMovingAverage()方法中,平移(即 X 和 Y)、扩展和旋转的速度是根据带时间戳的值的滚动历史记录计算的。