Итак, как же реализовать touchstart?
Начнем с самого просто и будем двигаться по нарастающей. Простейший вариант реализации touchstart:
0. Тишина.
1. Начало генерироваться событие wheel. Это и есть наш touchstart
2. Предположим, что между событиями никак не может быть больше 200мс (на самом деле от 10 до 30 мс), поэтому просто через 200 мс после последнего события снова генерируем touchstart при появлении новых объектов событий.
Уже неплохо, две страницы точно не проскролятся за одно движение. Но есть существенная проблема: попытка начать новую итерацию скроллинга до конца текущей приведет только к удлинению текущей.
Чтоб решить эту проблему, необходимо понять момент, когда пользователь произвел новый жест до окончания работы предыдущей итерации.
Проанализировав объект события wheel, мы сразу обратили внимание на поле deltaY. Оно отражает силу, с которой в текущий момент времени работает устройство.
Если отобразить значения deltaY на графике, то жест будет иметь примерно такой вид:
А это то, что нам надо отловить.
Таким образом задача сводится к тому, чтобы сравнивать предыдущее значение deltaY с текущим. И если оно больше, значит пользователь начал новое осознанное движение, то есть новый touchstart произошел.
Вроде бы все отлично, интерфейс стал более отзывчив, стало можно делать любое кол-во жестов подряд, не дожидаясь окончания работы предыдущий итерации. Но на практике алгоритм давал сбой: touchstart зачастую генерировался чаще необходимого. Иногда по 2-3 раза за одну итерацию. Почему же так происходило? Анализе числового ряда deltaY из одной итерации показал, что иногда несмотря на спад итерации (то есть замедлении работы инерции, выраженным во все меньших значениях deltaY в каждом следующем событии wheel) иногда текущий deltaY может быть равен или больше предыдущего. Причем иногда это происходило через раз:
21, 17, 15, 18, 12, 14, 10, 7…
либо два подряд увеличения
21, 17, 15, 18, 19, 14, 10…
Многочисленные опыты показали, что таких ситуаций практически не бывает больше трех подряд для обоих случаев. Вносим корректировки в алгоритм: теперь touchstart генерируется только если текущий deltaY больше предыдущего и следующий deltaY больше текущего. Теперь все работает неплохо, и явных проблем больше нет.
Взяв за основу этот подход, мы написали плагин wheel-indicator. В анализе также используются другие факторы, но описывать их все в рамках этой статьи нет смысла.
Обычные мышки
Плагин также можно использовать, как легкую замену известному jquery-mousewheel в случаях, когда вам требуется только кроссбраузерно определить направление работы колесика. Если мышка пользователя триггерит черезмерно много событий, плагин также будет это нормализовать. Иногда это бывает полезно, например, скроллить колесом такую карусель не очень комфортно. Кроме этого на основе плагина можно реализовывать неблокирующие интерфейсы. Например, здесь можно скроллить в процессе анимации в любую сторону, и кол-во переходов будет равно кол-ву жестов пользователя.
Чтоб иметь возможность тестировать плагин в nodejs, необходимо, чтоб он мог экспортировать себя в формате commonjs.
Для этого добавляем проверку и экспорт констурктора:
if (typeof exports === 'object') {
module.exports = WheelIndicator;
}
Входные данные для плагина поступают через объект события после создания обработчика при помощи addEventListener. Таким образом, в тестах нам необходимо «замокать» этот метод:
global.document = {
addEventListener: function(type, handler){
currentDeltaArr.forEach(function(delta){
handler({
deltaY: delta
});
});
}
};
, где delta — это массив тестового числового ряда из deltaY. Для удобного получения таких рядов с различных устройств и ОС мы сделали тестовый стенд.
Вот собственно и все, теперь только остается зареквайрить плагин, создать инстанс и сверить полученные от плагина данные с эталонными.
Пример входящих данных для теста:
down: {
moves: [ 'down' ],
delta: [1,4,12,32,55,69,154,156,158,148,137,130,122,116,111,108,103,97,93,88,84,80,74,71,65,61,57,54,50,46,42,39,36,33,31,27,25,23,21,18,17,15,14,13,12,11,9,8,8,7,6,6,14,4,4,3,3,3,2,2,4,1,2,1,1,1,1,1,1,1,1,1,1],
device: 'Mac OSX notebook trackpad'
}
Почитать о подключении, документацию и скачать плагин вы можете на странице репозитория.
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий