web-dev-qa-db-ja.com

動的スクロールを実装するためのアルゴリズム

動的スクロールの実装を作成するためのいくつかの優れたアルゴリズムは何ですか?この機能は、カスタムUIリストでテストされます。私はモバイルデバイス(この機能が組み込まれていないデバイス)をターゲットにしていますが、さまざまなプログラミング分野のアルゴリズムやコード例も適している可能性があります。

25

最近自分で実装しました。これらは私が取ったステップです。

  1. カーソル(マウスカーソルまたは指)の速度を測定する必要があります
  2. 単純な素粒子物理学ループを実装します。それを行う方法についての情報は見つけることができます ここ
  3. スクロール平面の幅とビューポートの幅から導出された数学を使用して、パーティクルの「境界」を指定します
  4. マウスの速度とパーティクルの速度の差をパーティクルの速度に継続的に追加します。これにより、パーティクルの速度は、移動している限り、マウスの速度と「一致」します。
  5. ユーザーが指を離したらすぐに、手順4の実行を停止します。物理ループが慣性を処理します。
  6. 「バンパー」マージンや、動きを計算するためのゼノンのパラドックスに作用するスムーズなスクロール「アンカー」ポイントなど、個人的な繁栄を追加します。
  7. 私はほとんど忘れていました:上から導き出された座標を取り、それをスクロール平面の位置として使用してください。

私はおそらくこのコードをすぐにオープンソースにするでしょう。どれくらい早くこれが必要ですか?

編集:リンクを変更しました。申し訳ありませんが、少し間違ったページを指しています。 edit2:かどうか?とにかく、私がリンクした元のページは、現在リンクされているページの最初のリンクでした。

24
Breton

これは最初に尋ねられたので、私はペストリーキットのソースコードを注意深く読みました。フレームワークはAppleがjavascriptで動的スクロールを正確に複製しました。素粒子物理学のループはありません-の速度タッチは、指を離した瞬間に測定され、その時点から、速度を入力パラメータとして使用する単純なイージング機能を使用してスクロールがアニメーション化されます。

23
Breton

モバイルGUIフレームワークにスクローラーウィジェットを追加したばかりなので、ここでソリューションを共有したいと思いました。

これはかなり複雑な問題であるため、次のように、少し独立した小さなサブタスクに分割することにしました。

  1. 基本的なスクロール機能:このタスクは、ドラッグの距離と方向に従ってコンテンツをスクロールするという最も簡単な方法でドラッグイベントを処理することで構成されていました。これは実装が比較的簡単でした。唯一注意が必要なのは、ドラッグ操作を開始するタイミングと、スクロール可能な領域内の子ウィジェットにタップイベントを渡すタイミングを知ることでした。

  2. スクロール慣性:これは最も挑戦的でした。ここでの考え方は、ユーザーが指を離した後もしばらくスクロールを続け、完全に停止するまで速度を落とすというものです。このために、私はスクロール速度のアイデアを持っている必要がありました。残念ながら、単一のサンプルから速度を計算することは正確ではないため、ユーザーがスクロールしている間、最後のN個のモーションイベントを、各イベントが発生した時間とともに循環バッファーに記録します。 N = 4は、iPhoneとHPTouchPadで問題なく動作することがわかりました。指を離すと、記録された動きから慣性スクロールのおおよその開始速度を計算できます。負の加速係数を定義し、標準のモーション式( ここ を参照)を使用して、スクロールをうまく停止させました。まだ動いている間にスクロール位置が境界に達した場合は、速度を0にリセットして、範囲外にならないようにします(次に突然の停止について説明します)。

  3. 柔軟なスクロール制限:スクロールが最後に達したときに突然停止する代わりに、ウィジェットにスクロールさせたいと思いましたが、抵抗を提供しました。このために、ウィジェットの寸法の関数として定義した量だけ、両端で許可されるスクロール範囲を拡張しました。両端に幅または高さの半分を追加するとうまくいくことがわかりました。スクロールに抵抗があるように感じさせる秘訣は、表示されるスクロール位置が範囲外のときに調整することでした。これには、スケールダウンと減速機能を使用しました(いくつかの優れたイージング機能があります ここ )。

  4. 春の行動:有効な範囲を超えてスクロールできるようになったため、ユーザーが範囲外に置いた場合にスクローラーを有効な位置に戻す方法が必要でした。これは、スクローラーが範囲外の位置で停止したときにスクロールオフセットを調整することによって実現されます。弾力のある見栄えを与えるために私が見つけた調整機能は、現在の位置から目的の位置までの距離を定数で除算し、その量だけオフセットを移動することでした。定数が大きいほど、動きは遅くなります。

  5. スクロールバー:最後の仕上げは、スクロールの開始時にフェードインし、終了時にフェードアウトするオーバーレイスクロールバーを追加することでした。

14
Miguel

ロバート・ペナーのイージング機能を見たことがありますか?

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

IIRCこれらは元々Actionscript用であり、長い間存在していました。

1
tim