2009-11-27 119 views
21

創建動態滾動實現的一些好算法是什麼?該功能將在自定義UI列表中進行測試。雖然我針對移動設備(那些內置此功能的設備),但來自不同編程領域的任何算法或代碼示例也可能適用。實現動態滾動的算法

回答

23

我最近自己實現了一個。這些是我採取的步驟。

  1. 你需要衡量你的光標(或鼠標光標或手指)
  2. 實現一個簡單的粒子物理環路的速度。有關如何做到這一點的信息可以通過從滾動面的寬度派生數學發現​​here
  3. 給你的粒子「邊界」,和你的視口的寬度
  4. 不斷添加鼠標速度和之間的區別粒子速度與粒子速度的關係,所以粒子的速度只要移動就「匹配」鼠標的速度。
  5. 一旦用戶擡起手指,請停止執行第4步。物理循環負責處理慣性。
  6. 添加您的個人興趣,如「保險槓」邊距,以及根據zeno運算悖論計算的平滑滾動「錨點」。
  7. 我差點忘了:從上面獲取座標,並將其用作滾動平面的位置。

我可能很快就會開源代碼。你多久需要這個?

編輯:改變了鏈接。對不起,指出了一些錯誤的頁面。 edit2:還是不?無論如何,我鏈接到的原始頁面是當前鏈接頁面上的第一個鏈接。

+2

我會盡力在幾周內實現這一點。現在我只是在想它。感謝您的答覆。如果您決定開放您的解決方案,請在此處發佈一些消息。 – 2009-11-27 23:07:34

+0

鏈接長時間死亡現在:( – 2016-08-03 08:45:33

-1

嗯,我認爲它會像a)獲取用戶滾動b)速度的速度,當他離開他的手指時,自動滾動列表但自動滾動列表,但以降低的速度和用戶的初始速度。

21

因爲這是最初問到的,所以我已經仔細閱讀了pastrykit的源代碼,在這個框架中,蘋果已經完全複製了它們在JavaScript中的動態滾動。沒有粒子物理循環 - 觸摸的速度是在手指擡起的時刻測量的。從這一點開始,使用速度作爲輸入參數的簡單緩動功能來動畫滾動。

13

我剛剛添加了一個滾動窗口小部件到我的移動GUI框架,所以我想我會在這裏分享我的解決方案。

由於這是一個相當複雜的問題,我決定把它劃分成更小一些獨立的子任務,具體如下:

  1. 基本滾動功能:這個任務在處理中最簡單的拖動事件包括這是通過根據拖拽距離和方向來滾動內容的方式。這是相對簡單的實現,唯一棘手的方面是知道什麼時候開始拖動操作與何時將點擊事件傳遞給可滾動區域內的子部件。

  2. 滾動慣性:這是最具挑戰性的。這裏的想法是,在用戶擡起手指後,應該繼續滾動一段時間,放慢速度直到完全停止。爲此,我需要了解滾動速度。不幸的是,從單個樣本計算速度並不準確,所以當用戶滾動時,我會在循環緩衝區中記錄最後N個運動事件以及每個事件發生的時間。我發現N = 4可以在iPhone和HP TouchPad上正常工作。當手指擡起時,我可以根據記錄的動作計算慣性滾動的近似開始速度。我定義了一個負加速度係數並使用了標準運動公式(請參閱here),以便很好地滾動滾動條。如果滾動位置在仍然運動時到達邊界,我只需將速度重置爲0以防止它超出範圍(緊接着的是突然停止)。

  3. 靈活的滾動限制:當滾動到達結尾時,我不想進入突然停止狀態,而是希望小部件滾動某些內容,但會提供阻力。爲此,我將兩端允許的滾動範圍擴展了一個我定義爲小部件尺寸函數的數量。我發現在每一端添加一半寬度或高度的效果很好。讓滾動感覺提供一些阻力的技巧是在顯示的滾動位置超出範圍時調整顯示的滾動位置。我使用了縮放加減速功能(有一些很好的緩動功能here)。

  4. 彈簧行爲:因爲現在可以滾動到有效範圍之外,所以我需要一種方法在用戶將其移出範圍時將滾動條移回有效位置。這可以通過調整滾輪停止在超出範圍位置時的滾動偏移來實現。我發現調整功能給人一種很好看的彈性外觀,就是將距離當前位置到理想位置的距離除以一個常數,並將偏移量移動該量。不斷變慢的運動越大。

  5. 滾動條:最後一點是添加疊加滾動條,當滾動開始時淡入淡出,結束時淡入淡出。

+1

可以請你分享滾動慣量代碼嗎?謝謝。 – SpaceDog 2013-09-17 06:09:13

1

你看過Robert Penner的寬鬆功能嗎?

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

IIRC這些原本爲ActionScript和已經存在了很長一段時間。

+0

我從來沒有見過這些!所以非常有用。+1 – 2015-08-11 12:59:47