わかりました、私は私ができる限り最善を尽くそうとしていることを説明しようとします。
Webkit-overflow-scrollingを使用して、iPhoneの連絡先アプリが提供する効果とよく似た、スタック可能なヘッダーを持つリストを作成しています。たとえば、「A」は「B」が邪魔にならないように移動するまで上部に留まります。これは、デスクトップ上またはユーザーがまだスクロールしているときに比較的簡単に実行できます。
ただし、ユーザーがスクローラーをフリックすると、ゆっくりと減速して自動的にスクロールします。この期間中は、スクローラーが完全に停止するまで、手遅れになるまでイベントは発生しません。
多くの調査の結果、フリックの減速時間は常に同じ(約2.4秒)であり、終了位置が変わるだけであることがわかりました。また、iOSの動作を模倣する独自のライブラリを作成することで、多くの人がこれを回避していることもわかります。これが私の唯一の選択肢かもしれません。
要素がそれ自体でスクロールするので、次のようにして要素のスクロールトップを計算しようとしています。
- タッチ開始位置
- タッチ終了位置
- これら2つのジェスチャーの時間差
これにより、位置と最終結果を発生前に追跡できるようになります。ただし、この情報を正しく使用して目的の結果を得る方法に少しこだわっています。どんな情報やポインタも非常に役に立ちます。
編集
物理学で立ち往生した後、私は物理学のスタック交換で尋ね、この答えを受け取りました
したがって、このコードは機能するはずです。正しいロジックを適用していることを確認したい
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
スクローラーの速度は325msごとに0.95分の1に減少すると思います。私はこの有用な記事からこの情報を見つけました。
この観察により、運動量のスクロールは一種の指数関数的減衰であると私は信じました。それは崩壊の速度によって特徴づけられます。それを表現する2つの異なる方法があります:半減期(放射性崩壊を覚えていますか?)または時定数。後者の場合、それは一次システムのステップ応答に非常に関連しています。言い換えれば、減速システムは単なる過減衰ばね質量システムです。結局のところ、すべてはまだ物理学に基づいています。
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の一部)に減速が実装されている方法です。アニメーションティックごとにスクロール速度が0.95分の1に低下します(16.7ミリ秒、60 fpsをターゲット)。これは、325ミリ秒の時定数に相当します。あなたが数学オタクなら、明らかにあなたはスクロール速度の指数関数的性質がその位置の指数関数的減衰をもたらすことを理解しています。少し走り書きすると、最終的に325が-16.7 / ln(0.95)であることがわかります。
このGoogleドキュメントには数式が表示されているはずですが、うまくいけば正しく実行できます。左側は標準の式です。右側では、速度を0.95(速度* 0.95)下げようとしました。私が抱えている問題を示すために、テストからの実際の情報を追加しました。すべての方程式が正しく、論理的に正しく行われている場合、それは入力されるデータである必要があります。
編集4
多くの苦痛な時間を過ごした後、私はこれがサファリモバイル用のウェブキットのバグであると結論付けました。最善のオプションは、JS libを使用して効果を模倣し、バグが修正されるまで待つことです。
- 停止にかかる主な理由は常に変化するため、正確な読み取りを行うには変数が多すぎるために変化します。