Алгоритм реализации кинетической прокрутки - PullRequest
24 голосов
/ 28 ноября 2009

Какие есть хорошие алгоритмы для создания кинетической реализации прокрутки? Эта функция будет протестирована в списке пользовательских интерфейсов. Хотя я нацеливаюсь на мобильные устройства (те, которые не имеют этой встроенной функции), может подойти любой алгоритм или пример кода из другой области программирования.

Ответы [ 5 ]

24 голосов
/ 28 ноября 2009

Я недавно внедрил один сам. Вот шаги, которые я предпринял.

  1. Вам необходимо измерить скорость вашего курсора (либо курсора мыши, либо пальца)
  2. Реализация простого цикла физики элементарных частиц. Информацию о том, как это сделать, можно найти здесь
  3. присвойте частицам "границы", используя математику, полученную из ширины плоскости прокрутки и ширины области просмотра
  4. постоянно Добавляйте разницу между скоростью мыши и скоростью частицы к скорости частицы, чтобы скорость частицы «соответствовала» скорости мыши на протяжении всего ее движения.
  5. Прекратите выполнять шаг 4, как только пользователь поднимает палец. Физическая петля заботится об инерции.
  6. Добавьте свои личные процветания, такие как «бамперные» поля и плавные прокручивающиеся «опорные» точки, которые оперируют парадоксом Зенона при расчете движения.
  7. Я чуть не забыл: возьмите координаты, полученные сверху, и используйте его как местоположение вашей плоскости прокрутки.

Возможно, скоро я открою исходный код. Как скоро вам это нужно?

изменить: изменил ссылку. Извините, указал на немного не ту страницу. edit2: или нет? В любом случае, исходная страница, на которую я ссылался, была первой ссылкой на текущей связанной странице.

21 голосов
/ 02 сентября 2010

С тех пор, как это было первоначально задано, я с тех пор внимательно прочитал исходный код для пастрыкита, фреймворка, в котором apple точно дублировала кинетическую прокрутку в javascript. Там нет петли физики частиц - скорость прикосновения измеряется в тот момент, когда палец поднят. С этого момента прокрутка анимируется с помощью простой функции замедления, которая использует скорость в качестве входного параметра.

14 голосов
/ 29 августа 2011

Я только что добавил виджет скроллера в мою мобильную среду графического интерфейса, поэтому я решил поделиться своим решением здесь.

Поскольку это довольно сложный вопрос, я решил разделить его на несколько несколько независимых подзадач следующим образом:

  1. Основные функции прокрутки : эта задача состояла в том, чтобы обрабатывать события перетаскивания самым простым способом, а именно путем прокрутки содержимого в соответствии с расстоянием перетаскивания и направлением. Это было относительно просто реализовать, единственным сложным аспектом было знать, когда начинать операцию перетаскивания, а не когда передавать событие касания дочернему виджету внутри прокручиваемой области.

  2. Инерция прокрутки : эта была самой сложной. Идея заключается в том, что прокрутка должна продолжаться в течение некоторого времени после того, как пользователь поднимает палец, замедляясь до полной остановки. Для этого мне нужно было иметь представление о скорости прокрутки. К сожалению, вычисление скорости по одной выборке не является точным, поэтому, пока пользователь выполняет прокрутку, я записываю последние N событий движения в кольцевой буфер, а также время, когда происходило каждое событие. Я обнаружил, что N = 4 отлично работает на iPhone и на сенсорной панели HP. Когда палец поднят, я могу вычислить приблизительную начальную скорость для инерционной прокрутки из записанного движения. Я определил отрицательный коэффициент ускорения и использовал стандартные формулы движения (см. здесь ), чтобы прокрутка хорошо угасла. Если положение прокрутки достигает границы, все еще находясь в движении, я просто сбрасываю скорость на 0, чтобы предотвратить ее выход за пределы диапазона (следующий резкий останов решается).

  3. Гибкие пределы прокрутки : вместо того, чтобы резко останавливаться при достижении конца прокрутки, я хотел, чтобы виджет прокручивал некоторые из них, но предлагал сопротивление. Для этого я расширил допустимый диапазон прокрутки на обоих концах на величину, которую я определил как функцию от размеров виджета. Я обнаружил, что добавление половины ширины или высоты на каждом конце работает хорошо. Уловка, чтобы придать прокрутке ощущение, что она оказывает некоторое сопротивление, состояла в том, чтобы отрегулировать отображаемые положения прокрутки, когда они находятся вне диапазона. Для этого я использовал функцию уменьшения и замедления (здесь есть несколько хороших функций замедления ).

  4. Пружинное поведение : так как теперь можно прокручивать допустимый диапазон, мне нужен был способ вернуть скроллер в правильное положение, если пользователь оставил его вне диапазона. Это достигается путем регулировки смещения прокрутки, когда скроллер останавливается в положении вне диапазона. Функция регулировки, которую я нашел, чтобы придать приятный пружинящий вид, состояла в том, чтобы разделить расстояние от текущей позиции до желаемой позиции на константу и переместить смещение на эту величину. Чем больше константа, тем медленнее движение.

  5. Полосы прокрутки : последний штрих - добавить накладные полосы прокрутки, которые исчезают, когда начинается прокрутка, и исчезают, когда она заканчивается.

1 голос
/ 27 июня 2013

Вы смотрели на функции ослабления Роберта Пеннера?

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

IIRC изначально были для Actionscript и существуют уже давно.

0 голосов
/ 28 ноября 2009

Ну, я думаю, что это было бы что-то вроде: а) получить скорость того, как быстро пользователь прокручивал б), когда он оставляет палец, автоматически прокручивать список, но с уменьшающейся скоростью с начальной скоростью того, что имел пользователь.

...