image

Анимация скролла к месту страницы с момента изобретения почти не подвергалась никаким модификациям, никак не украшалась. Да никому и не надо вроде, и так все работает. Говоришь куда скроллить и за сколько нужно добраться. Всё.

Я решил на анимацию скролла посмотреть под другим углом. Не потому что сейчас с ним что-то не так, а потому что можно и поинтереснее. В результате некоторых наблюдений и всплесков фантазии удалось придумать 3 способа для более интересной анимации. В итоге завернул все в плагин «Scrollport.js» с 3 новыми и 1 классическим режимом. Смотрите демо и проходите под кат.

Классическая анимация скролла умещается в одну строчку:
$(“ html, body “).animate( { scrollTop: $( ‘#my_target’ ).offset().top }, 600 );

Строчка эта весит 78 байт. Однако существует очень популярный плагин jQuery.scrollTo на момент написания статьи у него 2132 звёздочек, а используется он более чем на 30 000 сайтах! Весит эта звезда в 30 раз больше чем строка, которая делает тоже самое. Есть, конечно, у этого плагина куча всяких примочек, но они для редких случаев.

Я не считаю целесообразным использовать плагин, если одна строка делает то же самое. «Scrollport.js» хоть и пожирнее упомянутого плагина, но зато делает вещи, которые в одну строчку не уместятся. А в качестве бонуса добавлена вспомогательная функция для создания ссылок, которые будут инициировать анимацию скролла.

Как использовать


Подключите JS файл с плагином, пишите:

// Инициализации анимации скролла к элементу с id «my_target».
$.scrollport( ‘#my_target’ );

// При нажатии на ссылку с id «my_link», будет инициирована  анимация скролла к элементу с id «my_target». 
$( ‘#my_link’ ).scrollport_link( ‘#my_target’ );

// Инициализации анимации скролла с указанием настроек, в которых также указан режим работы плагина «roll».
$.scrollport( ‘#my_target’, { mode: ‘roll’, speed: 1500 } );

В плагин можно передавать различные настройки, обращаться к API, да и способов вызова анимации множество. За подробностями обратитесь к ридми репозитория на гитхабе.

4 разновидности режимов


В настройках к плагину можно передать один из 4 режимов: usual, roll, hard или soft. Рассмотрим каждый по порядку.

Usual

Классика. Плагину нужно знать, куда перемещать скролл, и за какое время нужно оказаться на месте. Вы такое видели сотни раз, и каких-то уникальных замечаний по этому режиму дать не могу.

Хотя есть одна вещь, которая раздражает. Если сказано, что на месте нужно оказаться за одну секунду, то всё выглядит не плохо на больших и средних расстояниях. Но если мы вызываем анимацию за 100 пикселей до цели, за 1 секунду можно успеть утомиться от анимации. Второй режим разрешает эту придирку.

Roll

Та же классика вид с боку. Нужно знать куда перемещаться и с какой скоростью. Выглядит немного приятнее и интеллектуальнее что ли.

По умолчанию стоит скорость 2500 пикселей в секунду. Если ехать 100 пикселей, эта скорость может оказаться великоватой и сложится впечатление, что слишком уж резко мы оказались на месте. Чтобы этой неприятности избежать, можно указать минимальное время, по умолчанию 300 миллисекунд. То есть быстрее чем за это время у цели вы не окажетесь.

Большое расстояние может преодолеваться слишком долго, для этого введен параметр ограничивающий максимальное время ожидания.

Случайный посетитель вряд ли ощутит разницу между режимами «roll» и «usual», но как ценителя красоты в динамике режим «roll» меня привлекает больше.

Hard

Резкое перемещение к месту за 5 пикселей до цели, далее скролл плавно докатится до места. Идею этого режима я украл у вконтакте. Можете зайти на свою страничку, немного опустить ленту новостей и кликнуть на полосу «наверх» в левой части экрана, потом еще раз туда же.

Иногда нежные режимы «roll» и «usual» хочется заменить чем-то более грубым и примитивным. Но не на столько варварским, что бы уж совсем как при переходе по якорной ссылке.

Soft

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

Заключение


Некоторые найдут этот плагин привлекательным, новым и интересным. Остальным же предлагаю воспринять эту статью, как свежий взгляд на привычные вещи. Мне интересно услышать ваше мнение о плагин режимах. Если кто-то предложит еще парочку режимов, я буду очень рад.

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

Комментарии (38)


  1. zencd
    20.05.2015 16:33
    +8

    Режим «hard» очень понравился! Мгновенная смена контента (мной по крайней мере) плохо воспринимается, а здесь и скорость максимальная, и эффективная иллюстрация «что это только что произошло» присутствует.


    1. Torvald3d
      20.05.2015 19:34
      +2

      Тоже понравился «hard», но хочется, чтобы расстояние за которое контент останавливается было больше раза в три, а уже после — плавная доводка. Чтобы более наглядно видеть откуда пришел — снизу или сверху.


      1. iserdmi Автор
        20.05.2015 19:52
        +2

        Из документации:

        distance по умолчанию 5
        Расстояние в пикселях, которое остается до цели после мгновенного перемещения.

        duration по умолчанию 50
        Время, за которое будет пройден оставшийся путь.


        Вы можете установить свои значения в передаваемых опциях. В вашем случае можно так:
        $.scrollport( '#my_target', {
          mode: 'hard',
          distance: 15,
          duration: 150
        } );
        


    1. Funcraft
      20.05.2015 23:50
      +2

      Наоборот, совсем не понравился. Может я ожидаю другого, но ощущение, что скролл просто отсутствует.


  1. DOLARiON
    20.05.2015 16:57
    +5

    «Эффект телепортации» — огонь! Очень понравился.
    Для всяких «лэндингов», где необходима эффектность, на мой взгляд, самое то.


    1. Lungo
      20.05.2015 22:12
      +2

      А мне этот эффект не очень понравился, т.к. плохо видно куда листалось — вверх или вниз


  1. cmepthuk
    20.05.2015 17:09

    Если во время промотки скриптом до анкора поскроллить мышью — промотка прекращается. Я не знаю — баг это, или фича — но это чертовски здорово. Так и должно быть. Сохраните это. Если при «классическом» $("html, body").animate({...}, 2500); так сделать (например, во время «полета» вверх после прочтения длинной статьи попытаться внезапно остановиться на определенном моменте) — терпеть фиаско очень раздражает (Tumblr, привет).


    1. iserdmi Автор
      20.05.2015 17:25
      +10

      Это не просто фича, это настраиваемая опция. Цитирую документацию:

      interrupt_user по умолчанию true
      Если во время работы плагина пользователь совершит принудительный скролл, движение вызванное работой плагина прекратится.

      interrupt_scrollport по умолчанию true
      Если во время работы плагина будет инициировано новое движение, прежнее прекратится. При значении false вызванное поверх существующего движение выполнено не будет.

      interrupt
      Принимает значение true или false, устанавливая такое же значение для опций interrupt_user и interrupt_scrollport


      Если отключить прерывание, то во время пользовательского скролла даже экран дёргаться не будет, при обычном $.fn.animate экран начинает дребезжать.


  1. webkumo
    20.05.2015 17:09
    +3

    Можно ещё поработать над режимами:
    — хард — кажется, что слишком дёрнулось и оттягивает назад,
    — софт — забеление на белом фоне вызывает эффект ослепления, а не телепортации.


  1. Pomidoroff
    20.05.2015 17:16
    +8

    Нужен моушен блюр!


    1. dannote
      20.05.2015 18:18

      Хм, сделаю вечером пример с SVG-filters и без jQuery.


    1. iserdmi Автор
      20.05.2015 18:19

      Точно! Будет.


  1. VasilioRuzanni
    20.05.2015 17:55
    +1

    Еще бы API в привычном JS-сообществу camelCase (жаль, что в JS принято не unix_snake_case) и без jQuery — цены бы ему не было :)


    1. iserdmi Автор
      20.05.2015 18:22
      +1

      Хорошая идея! Сделаю возможно передачи опций в кэмэлкейсе. Напишу нативную версию. И сделаю возможность добавления пользовательских эффектов, и новых режимов, используя API предоставляемым скроллпортом. Вот тогда будет круто!


  1. beat
    20.05.2015 17:58

    Весит эта звезда в 30 раз больше чем строка, которая делает тоже самое.

    а что бы ваша «звезда» работала нужно подключить jQuery + плагин на 500 строк просто для того чтобы прыгнуть к нужному контенту


    1. iserdmi Автор
      20.05.2015 18:18

      Та «звезда» также джэйкверизависима. Вы чаще тянете джэйквери не только потому, что вам нужна анимация скролла, скорее есть еще что-то для чего вы его используете. Минифицированная версия джэйквери весит ? киллобайта. Пишите строку в 78 байтов, итого получается 84 клиллобайта. Если берёте плагин «звезда», становится 86,4 киллбоайта. Если берёте «Scrollport.js» общий вес составит 95 киллобайт. Разве большая разница между 86,4 и 95 киллобайтами, однако в моем плагине 4 разных режима, в том числе тот для которого создан плагин «jQuery.scrollTo». Строчка кода указанная в статье тоже, кстати, требует подключения jQuery. Но в большинстве случаев функциональности строчки вполне хватает, так зачем же тянуть плагин в 2,4 киллобайта, если результат тот же?

      Если у вас уже подключен джэйквери, и нужно просто «прыгнуть к нужному контенту», не используйте плагина, напишите строчку кода. Если у вас не подключен джэйквери, то, конечно, лучше найти решение на нативном яваскрипте.

      В скоре напишу нативную версию плагина.


      1. webkumo
        20.05.2015 21:40

        А если режимы в разных js-ках написать (чтобы подключать только нужный режим)?


  1. MichaelBorisov
    20.05.2015 20:55
    +4

    Предлагаю ввести еще один режим — «физический».

    Задаться максимальным значением скорости и ускорения. Тогда прокрутка будет ускоряться при ее начале и замедляться при подходе к цели. Если расстояние прокрутки недостаточное для разгона до максимальной скорости — то достигнутая скорость будет меньше. Дополнительный плюс — человеческому мозгу нравится, когда явления на экране проходят по законам физики. Оказывается, что в раннем детстве наш мозг интенсивно «изучает» физику на феноменологическом уровне и научается различать, где законы механики соблюдаются, а где — нарушается. Это позволяет различать живые объекты от неживых. Живой объект может «нарушать» законы механики. Но некоторые законы (вроде мгновенного перемещения) не нарушают даже живые объекты, поэтому для зрительного восприятия они наиболее некомфортны.


  1. Invision70
    20.05.2015 21:58
    +3

    Классическая анимация скролла умещается в одну строчку:
    $(“ html, body “).animate( { scrollTop: $( ‘#my_target’ ).offset().top }, 600 );

    Обожаю такие примеры! Одна строчка кода и тянем еще увесистый jQuery. Действительно классика)


  1. jaguard
    20.05.2015 23:37
    +1

    >Мне нравится то, что происходит с вебом. Из неотесанных таблиц сайты превращаются в

    в тормозящие чудовища, которые приводят в ужас мой айпад третьего поколения. Когда я его покупал, весь веб на нем летал со скоростью мысли. Теперь половина сайтов еле-еле грузится, а порой сжирает всю доступную память и роняет браузер.
    Кстати, ваш плагин на нем тоже не работает — но я допускаю, что это из-за того, что система (а следовательно, и сафари) не обновлялась с момента покупки ни разу.


  1. vovkasolovev
    21.05.2015 02:06
    +1

    Если пофантазировать и развить мысль, думаю, что для добавления характера материала подойдут многие приёмы классической анимации (как реализовывать не представляю), например:

    • Растяжение контента во время прокрутки и сжатие в начале и в конце действия.
    • Anticipation начала и окончания, и использование изингов (изменение скорости от расстояния начальных и конечных точек).
    • Secondary Action, например картинки догоняют позже букв.
    • Добавить размытие контента для усиления эффекта скорости.
    • Сделать движение контента не по прямой а по дуге, пустить волну.
    • Плавно ослабить насыщенность цвета или прозрачность контента, а при завершении прокрутки усилить, чтобы отчеканить конец действия резким изменением контраста.


  1. wdmaster
    25.05.2015 03:57

    // Инициализации анимации скролла к элементу с id «my_target».
    $.scrollport( ‘#my_target’ );
    
    // При нажатии на ссылку с id «my_link», будет инициирована  анимация скролла к элементу с id «my_target». 
    $( ‘#my_link’ ).scrollport_link( ‘#my_target’ );
    
    // Инициализации анимации скролла с указанием настроек, в которых также указан режим работы плагина «roll».
    $.scrollport( ‘#my_target’, { mode: ‘roll’, speed: 1500 } );
    

    Не увидел более логичную реализацию
    $(".link a").scrollport();
    

    Где id остановки берется из хеша у атрибута href тега a. В основном именно такая реализация навигации по странице чаще всего используется. Так как может появиться необходимость поделиться URL с хешем. Хеш также должен меняться в адресной строке.
    Мне понравился плагин, думаю, его можно использовать для эффектного скролла на промо страницах.
    Но когда нажал на ссылку в демо и, логически, страница должна листаться вниз, а она выезжает сверху, это сбивает с толку, теряется ориентация и приходится смотреть на вертикальный скролл браузера, чтобы сообразить, в каком месте ты находишься. Для страниц с документацией явно не подойдет :D А на реальном проекте интересно было бы посмотреть. В рабочий проект, без тестов я бы внедрял такой функционал с осторожностью.


    1. wdmaster
      25.05.2015 04:02

      Было бы приколько также увидеть что-то такое (прим AnimateCSS):

      // fadeInLeft, fadeInRight, fadeInBottom, fadeIntop
      $(".link a").scrollport({
          direction : "fadeInLeft"
      });
      


    1. iserdmi Автор
      25.05.2015 15:16
      +1

      Есть такая реализация. Цитирую документацию:

      Если не передать ни одно из значений target, top или left, тогда target автоматически примет значение атрибута data-scrollport или href, или data-href.

      link.scrollport_link( [ target ] [, options ] );


      Причем вы можете прописать к ссылке атрибут data-scrollport и ссылка автоматически станет скроллпорт ссылкой, даже ничего не придется в своем яваскрипте прописывать.


    1. paulradzkov
      25.05.2015 16:31
      +1

      Хеш также должен меняться в адресной строке.

      Поддерживаю. Важно улучшать поведение не ломая доступности. Эта опция должна быть включена по-умолчанию, но с возможностью выключить изменение url, если вдруг понадобится.


  1. xaja
    27.05.2015 22:33

    iPad iOS6 — не работает. какие-то моргания и все.