Эффект кинетической прокрутки сейчас можно встретить практически везде. Это действительно удобно при управлении пальцами или стилусом и довольно забавно при прокрутке мышкой.
В вебе такой эффект пока только приживается. Да и не так уж просто придумать, где он будет удобен… В голову приходят пожалуй лишь scroll bar’ы, которые используются для прокрутки некоторого контента, в основном картинок, внутри страницы. Для примера, можно посмотреть реализацию галереи практически на любом сайте. Согласитесь, было бы значительно интереснее, если бы ползунок не останавливался сразу, как только отпустили кнопку мыши, а продолжал бы двигаться дальше по инерции, постепенно останавливаясь…
Я попытаюсь рассмотреть процесс создания такого эффекта «кинетического» scroll bar’a. Что получилось в итоге можно посмотреть здесь
Для начала, рассмотрим общий алгоритм (перетаскивание ползунка + «допрокрутка»). Он, на удивление, простой:
Как видно, все довольно просто. Очевидно, что подобный алгоритм универсален и подходит не только для JS…
Для удобства можно использовать библиотеку jQuery и easing эффекты из jQuery UI.
HTML код будет следующим:
Где track – область, в которой бегает ползунок, а thumb – сам ползунок.
CSS:
Теперь можно перейти к написанию самого скрипта. Писать я буду в обычном процедурном стиле, поскольку это учебный пример… при желании можно переписать на прототипах или оформить в виде jQuery плагина.
Введем следующие глобальные переменные:
Первым делом запретим некоторым рыжим браузерам пытаться перетаскивать наш ползунок:
Обрабатываем mouseDown на объекте:
Обрабатываем mouseMove, но уже не на объекте, а на всем документе
Здесь встречается необъявленная переменная maxBorderOut, которая обозначает максимальное количество пикселей, на которое можно утащить ползунок за границы области.
И, наконец, mouseUp:
Переменная lapse определяет некоторую погрешность. То есть, если dx меньше чем эта погрешность, то анимация не происходит. Величина подбиралась на глаз, и может быть выбрана не совсем удачно.
Переменная impulse – величина некоторого импульса воздействующего на ползунок, и определяющего расстояние необходимое для перемещения. По сути, коэффициент умножающийся на dx. Подбирался так же на глаз.
Speed – скорость анимации.
Изменяя значения этих параметров, scroll bar можно настроить под конкретные нужды. При необходимости, сделать вертикальный скролл не должно составить труда.
Здесь рассмотрена не полноценная реализация scroll bar’a, а лишь та часть, которая отвечает непосредственно за перетаскивание и «кинетическую» прокрутку. Код получился довольно простой, а эффект весьма интересный.
Использовать можно, к примеру, при реализации постраничной навигации, галереи изображений и т.п…
UPD Сделал jQuery плагин, скачать можно здесь. Как работает, можно посмотреть на примере простенькой карусели…
Использовать довольно просто:
В вебе такой эффект пока только приживается. Да и не так уж просто придумать, где он будет удобен… В голову приходят пожалуй лишь scroll bar’ы, которые используются для прокрутки некоторого контента, в основном картинок, внутри страницы. Для примера, можно посмотреть реализацию галереи практически на любом сайте. Согласитесь, было бы значительно интереснее, если бы ползунок не останавливался сразу, как только отпустили кнопку мыши, а продолжал бы двигаться дальше по инерции, постепенно останавливаясь…
Я попытаюсь рассмотреть процесс создания такого эффекта «кинетического» scroll bar’a. Что получилось в итоге можно посмотреть здесь
Алгоритм
Для начала, рассмотрим общий алгоритм (перетаскивание ползунка + «допрокрутка»). Он, на удивление, простой:
- Отловить mouseDown на объекте, запомнить координаты нажатия.
- Отслеживать mouseMove. Если был клик (пункт 1), перенести объект на новое место, в противном случае ничего не делать.
- Замерить скорость. Достаточно просто определить dx: изменение координаты x объекта за одно событие mouseMove.
- Отловить mouseUp. На основе последнего найденного dx, можно рассчитать некоторый импульс и найти расстояние, до которого нужно перенести объект.
- Используя формулы затухания, анимировать перемещение объекта на нужное расстояние.
Как видно, все довольно просто. Очевидно, что подобный алгоритм универсален и подходит не только для JS…
Реализация
Для удобства можно использовать библиотеку jQuery и easing эффекты из jQuery UI.
HTML код будет следующим:
<div id="track">
<div id="thumb"></div>
</div>
Где track – область, в которой бегает ползунок, а thumb – сам ползунок.
CSS:
#track {
width: 500px;
position: relative;
display: block;
height: 22px;
margin: 20px;
border: solid 1px #000;
overflow: hidden;
}
#track #thumb {
width: 70px;
height: 22px;
position: absolute;
background-color: gray;
left: 200px;
}
Теперь можно перейти к написанию самого скрипта. Писать я буду в обычном процедурном стиле, поскольку это учебный пример… при желании можно переписать на прототипах или оформить в виде jQuery плагина.
Введем следующие глобальные переменные:
- $track (jQuery объект) – область scroll bar’a
- $thumb (jQuery объект) – ползунок
- isClicked (bool) – переменная, определяющая кликнули по ползунку или нет.
- clickPointX (int) – x координта клика на объекте
- dx (int) – изменение координаты x объекта за одно событие mouseMove.
var $track = $('#track');
var $thumb = $('#thumb');
var isClicked = false;
var clickPointX = 0;
var dx = 0;
Первым делом запретим некоторым рыжим браузерам пытаться перетаскивать наш ползунок:
$thumb.bind('dragstart', false);
Обрабатываем mouseDown на объекте:
$thumb.mousedown( function(e) {
// Координаты клика на объекте
clickPointX = e.pageX - $(this).offset().left;
isClicked = true;
$thumb.stop(); // Останавливаем анимацию ползунка
});
Обрабатываем mouseMove, но уже не на объекте, а на всем документе
$(document).mousemove( function(e) {
if (isClicked) {
// Новое положение ползунка, в зависимости от текущих
// координат мыши
var x = (e.pageX - $track.offset().left - clickPointX);
// Входит ли ползунок в границы области
if (x < -maxBorderOut) {
x = -maxBorderOut;
}
if ( (x + $thumb.width()) > ($track.width() + maxBorderOut)) {
x = $track.width() - $thumb.width() + maxBorderOut;
}
// Текущее положение
var selfLeft = parseInt($thumb.css('left'));
$thumb.css({'left': x + 'px' });
dx = x - selfLeft;
}
});
Здесь встречается необъявленная переменная maxBorderOut, которая обозначает максимальное количество пикселей, на которое можно утащить ползунок за границы области.
И, наконец, mouseUp:
$(document).mouseup( function(e) {
if (isClicked) {
if (Math.abs(dx) < lapse) {
dx = 0;
}
var selfLeft = parseInt($thumb.css('left'));
// Новое положение ползунка
// "impulse * dx" как раз та величина, на которую необходимо доскроллить
var x = (selfLeft + impulse * dx);
// Проверка, не выходит ли ползунок за границы области scroll box'a
if (x < 0) {
x = 0;
}
if ( (x + $thumb.width()) > $track.width() ) {
x = $track.width() - $thumb.width();
}
// Сама анимация перемещения
$thumb.stop().animate({'left': x + 'px'}, speed, 'easeOutQuart');
}
isClicked = false;
});
Переменная lapse определяет некоторую погрешность. То есть, если dx меньше чем эта погрешность, то анимация не происходит. Величина подбиралась на глаз, и может быть выбрана не совсем удачно.
Переменная impulse – величина некоторого импульса воздействующего на ползунок, и определяющего расстояние необходимое для перемещения. По сути, коэффициент умножающийся на dx. Подбирался так же на глаз.
Speed – скорость анимации.
Изменяя значения этих параметров, scroll bar можно настроить под конкретные нужды. При необходимости, сделать вертикальный скролл не должно составить труда.
Заключение
Здесь рассмотрена не полноценная реализация scroll bar’a, а лишь та часть, которая отвечает непосредственно за перетаскивание и «кинетическую» прокрутку. Код получился довольно простой, а эффект весьма интересный.
Использовать можно, к примеру, при реализации постраничной навигации, галереи изображений и т.п…
UPD Сделал jQuery плагин, скачать можно здесь. Как работает, можно посмотреть на примере простенькой карусели…
Использовать довольно просто:
<div id="track"></div>
$('#track').kineticBar()