27

有哪些好的算法可以创建动态滚动实现?该功能将在自定义 UI 列表上进行测试。虽然我的目标是移动设备(那些没有内置此功能的设备),但来自不同编程领域的任何算法或代码示例也可能适用。

4

6 回答 6

26

我最近自己实现了一个。这些是我采取的步骤。

  1. 您需要测量光标的速度(鼠标光标或手指)
  2. 实现一个简单的粒子物理循环。可以在此处找到有关如何执行此操作的信息
  3. 使用从滚动平面的宽度和视口的宽度得出的数学来给你的粒子“边界”
  4. 不断地将鼠标速度和粒子速度之间的差值添加到粒子的速度中,这样粒子的速度就会“匹配”鼠标的速度,只要它在移动。
  5. 用户一抬起手指就停止执行第 4 步。物理循环负责惯性。
  6. 添加您的个人风格,例如“缓冲”边距,以及平滑滚动的“锚点”,这些点在芝诺悖论上运行以计算运动。
  7. 我差点忘了:取从上面得出的坐标,并将其用作滚动平面的位置。

我可能很快就会开源这个代码。你多久需要这个?

编辑:更改了链接。抱歉,指点了一点错误的页面。编辑2:与否?无论如何,我链接到的原始页面是当前链接页面上的第一个链接。

于 2009-11-27T22:03:30.000 回答
26

由于最初有人问过这个问题,因此我仔细阅读了 pastrykit 的源代码,苹果在其中完全复制了他们在 javascript 中的动态滚动的框架。没有粒子物理循环——触摸速度是在手指抬起的那一刻测量的。从那时起,滚动使用一个简单的缓动函数来设置动画,该缓动函数使用速度作为输入参数。

于 2010-09-02T16:04:39.820 回答
15

我刚刚在我的移动 GUI 框架中添加了一个滚动小部件,所以我想我会在这里分享我的解决方案。

由于这是一个相当复杂的问题,我决定将其分成更小的、有些独立的子任务,如下所示:

  1. 基本滚动功能:此任务包括以最简单的方式处理拖动事件,即根据拖动距离和方向滚动内容。这实现起来相对简单,唯一棘手的方面是知道何时开始拖动操作以及何时将点击事件传递给可滚动区域内的子窗口小部件。

  2. 滚动惯性:这个是最具挑战性的。这里的想法是,在用户抬起手指后,滚动应该继续一段时间,然后放慢速度直到完全停止。为此,我需要了解滚动速度。不幸的是,从单个样本中计算速度并不准确,因此当用户滚动时,我将最后 N 个运动事件记录在循环缓冲区中,以及每个事件发生的时间。我发现 N=4 在 iPhone 和 HP TouchPad 上工作得很好。当手指抬起时,我可以从记录的运动中计算出惯性滚动的近似起始速度。我定义了一个负加速度系数并使用了标准运动公式(见这里) 让滚动很好地消失。如果滚动位置在运动中到达边界,我只需将速度重置为 0 以防止它超出范围(接下来会解决突然停止问题)。

  3. 灵活的滚动限制:而不是在滚动到达末尾时突然停止,我希望小部件滚动一些,但提供阻力。为此,我将两端允许的滚动范围扩展了一个我定义为小部件尺寸函数的量。我发现在每一端添加一半的宽度或高度效果很好。让滚动感觉它提供了一些阻力的技巧是在它们超出范围时调整显示的滚动位置。为此,我使用了缩小和减速功能(这里有一些很好的缓动功能

  4. 弹簧行为:由于现在可以滚动超出有效范围,因此如果用户将滚动条超出范围,我需要一种将滚动条带回有效位置的方法。这是通过在滚动条停止在超出范围的位置时调整滚动偏移量来实现的。我发现可以提供很好的弹性外观的调整功能是将当前位置到所需位置的距离除以一个常数,然后将偏移量移动该量。常数越大,运动越慢。

  5. 滚动条:最后一点是添加覆盖滚动条,滚动开始时淡入,滚动结束时淡出。

于 2011-08-29T00:08:51.130 回答
2

你看过 Robert Penner 的缓动函数吗?

http://www.robertpenner.com/easing/

IIRC 这些最初是用于 Actionscript 并且已经存在了很长时间。

于 2013-06-27T19:12:42.243 回答
0

我搜索了很多。将它们结合在一起,我提出了我的解决方案。

  1. 当指针向下时,您应该计算每次调用 onTouchMove 处理程序的像素差异。在触摸端将此值保存在某个变量中,例如,我们将其称为 diffPx
  2. 使用 requestAnimationFrame 进行连续动量滚动。只要diffPx不会达到某个极限值(我使用 0.25),在每一帧上滚动你的容器diffPx =* 0.95。
  3. 一个重要的限制。仅当指针上的diffPx超过限制值(我使用 5px)时才执行第 2 步。

https://developer.mozilla.org/ru/docs/Web/API/window/requestAnimationFrame

于 2021-12-23T11:32:27.977 回答
-1

好吧,我认为这类似于a)获取用户滚动的速度b)当他离开手指时,自动滚动列表,但速度随着用户所拥有的初始速度而降低。

于 2009-11-27T21:56:23.130 回答