Пользователь
0,0
рейтинг
20 мая 2015 в 16:09

Разработка → Scrollport.js — новая анимация скролла

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 до цели, но мы резкого скачка не видим, потому что белый слой стал совсем не прозрачным. Плавно доезжаем до места, в то время как белый слой исчезает. Пожалуй оптимальное соотношение скорости и плавности, да и выглядит этот эффект интересно и необычно.

Заключение


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

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

Подробнее
Спецпроект

Самое читаемое Разработка

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

  • +8
    Режим «hard» очень понравился! Мгновенная смена контента (мной по крайней мере) плохо воспринимается, а здесь и скорость максимальная, и эффективная иллюстрация «что это только что произошло» присутствует.
    • +2
      Тоже понравился «hard», но хочется, чтобы расстояние за которое контент останавливается было больше раза в три, а уже после — плавная доводка. Чтобы более наглядно видеть откуда пришел — снизу или сверху.
      • +2
        Из документации:
        distance по умолчанию 5
        Расстояние в пикселях, которое остается до цели после мгновенного перемещения.

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


        Вы можете установить свои значения в передаваемых опциях. В вашем случае можно так:
        $.scrollport( '#my_target', {
          mode: 'hard',
          distance: 15,
          duration: 150
        } );
        
    • +2
      Наоборот, совсем не понравился. Может я ожидаю другого, но ощущение, что скролл просто отсутствует.
      • +3
        Ощущение как от удара по голове. Х… к, где это я? Режим оправдывает название.
  • +5
    «Эффект телепортации» — огонь! Очень понравился.
    Для всяких «лэндингов», где необходима эффектность, на мой взгляд, самое то.
    • +2
      А мне этот эффект не очень понравился, т.к. плохо видно куда листалось — вверх или вниз
      • +1
        Вы наверное имеете ввиду режим «hard». DOLARiON имел ввиду режим «soft», в этом режиме однозначно понятно, в каком направлении происходит движение.
  • 0
    Если во время промотки скриптом до анкора поскроллить мышью — промотка прекращается. Я не знаю — баг это, или фича — но это чертовски здорово. Так и должно быть. Сохраните это. Если при «классическом» $("html, body").animate({...}, 2500); так сделать (например, во время «полета» вверх после прочтения длинной статьи попытаться внезапно остановиться на определенном моменте) — терпеть фиаско очень раздражает (Tumblr, привет).
    • +10
      Это не просто фича, это настраиваемая опция. Цитирую документацию:
      interrupt_user по умолчанию true
      Если во время работы плагина пользователь совершит принудительный скролл, движение вызванное работой плагина прекратится.

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

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


      Если отключить прерывание, то во время пользовательского скролла даже экран дёргаться не будет, при обычном $.fn.animate экран начинает дребезжать.
  • +3
    Можно ещё поработать над режимами:
    — хард — кажется, что слишком дёрнулось и оттягивает назад,
    — софт — забеление на белом фоне вызывает эффект ослепления, а не телепортации.
  • +8
    Нужен моушен блюр!
    • 0
      Хм, сделаю вечером пример с SVG-filters и без jQuery.
    • 0
      Точно! Будет.
  • +1
    Еще бы API в привычном JS-сообществу camelCase (жаль, что в JS принято не unix_snake_case) и без jQuery — цены бы ему не было :)
    • +1
      Хорошая идея! Сделаю возможно передачи опций в кэмэлкейсе. Напишу нативную версию. И сделаю возможность добавления пользовательских эффектов, и новых режимов, используя API предоставляемым скроллпортом. Вот тогда будет круто!
  • 0
    Весит эта звезда в 30 раз больше чем строка, которая делает тоже самое.

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

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

      В скоре напишу нативную версию плагина.
      • 0
        А если режимы в разных js-ках написать (чтобы подключать только нужный режим)?
        • 0
          Пока что уникальная логика каждого из режимов занимает слишком мало места. Для первой версии было решено не делить режимы на разные файлы. Но я хочу сделать так, чтобы разработчик мог написать свой режим и легко внедрить его в плагин используя API. В таком случае будет удобно разбить режимы на файлы, чтобы разработчик мог увидеть живой пример, и по образу и подобию дописать свой режим.
  • +4
    Предлагаю ввести еще один режим — «физический».

    Задаться максимальным значением скорости и ускорения. Тогда прокрутка будет ускоряться при ее начале и замедляться при подходе к цели. Если расстояние прокрутки недостаточное для разгона до максимальной скорости — то достигнутая скорость будет меньше. Дополнительный плюс — человеческому мозгу нравится, когда явления на экране проходят по законам физики. Оказывается, что в раннем детстве наш мозг интенсивно «изучает» физику на феноменологическом уровне и научается различать, где законы механики соблюдаются, а где — нарушается. Это позволяет различать живые объекты от неживых. Живой объект может «нарушать» законы механики. Но некоторые законы (вроде мгновенного перемещения) не нарушают даже живые объекты, поэтому для зрительного восприятия они наиболее некомфортны.
    • 0
      Спасибо за идею. Сделаю.
  • +3
    Классическая анимация скролла умещается в одну строчку:
    $(“ html, body “).animate( { scrollTop: $( ‘#my_target’ ).offset().top }, 600 );

    Обожаю такие примеры! Одна строчка кода и тянем еще увесистый jQuery. Действительно классика)
    • +4
      Так автор сравнивает эту строчку с плагином, который также тянет jQuery.
  • +1
    >Мне нравится то, что происходит с вебом. Из неотесанных таблиц сайты превращаются в

    в тормозящие чудовища, которые приводят в ужас мой айпад третьего поколения. Когда я его покупал, весь веб на нем летал со скоростью мысли. Теперь половина сайтов еле-еле грузится, а порой сжирает всю доступную память и роняет браузер.
    Кстати, ваш плагин на нем тоже не работает — но я допускаю, что это из-за того, что система (а следовательно, и сафари) не обновлялась с момента покупки ни разу.
    • 0
      На мобильных устройствах плагин работает… не работает. Сегодня починю.
  • +1
    Если пофантазировать и развить мысль, думаю, что для добавления характера материала подойдут многие приёмы классической анимации (как реализовывать не представляю), например:
    • Растяжение контента во время прокрутки и сжатие в начале и в конце действия.
    • Anticipation начала и окончания, и использование изингов (изменение скорости от расстояния начальных и конечных точек).
    • Secondary Action, например картинки догоняют позже букв.
    • Добавить размытие контента для усиления эффекта скорости.
    • Сделать движение контента не по прямой а по дуге, пустить волну.
    • Плавно ослабить насыщенность цвета или прозрачность контента, а при завершении прокрутки усилить, чтобы отчеканить конец действия резким изменением контраста.
    • 0
      По первому пункту получилось занимательно, но требует доработки. Возможно уважаемый iserdmi доведет мысль до ума:
      .content-animate{
      	animation: scrolltest .5s;
      }
      @keyframes scrolltest {
      	0% {
      		transform: scale(1, 1);
      	}
      	50% {
      		transform: scale(0.5, 3);
      	}
      	100% {
      		transform: scale(1, 1);
      	}
      }
      
  • 0
    Вообще вопрос понятной и приятной глазу анимации прекрасно освещён в каноническом труде аниматоров студии Дисней ru.wikipedia.org/wiki/12_принципов_анимации
    К скроллбарам применимы, как минимум, принципы 1, 2, 5 и 6.
    • 0
      Главное не забыть, что мы прокручиваем материал не ради прокрутки, а ради того чтобы переместится в нужную точку. Особые украшательства во время пути будут лишь отвлекать.
      • 0
        Я тоже так думаю, но если ставится задача сделать какую-то нетривиальную анимацию, то стоит иметь в виду опыт профессионалов в этой области.
        • 0
          Область как раз другая. Обедняющее слово «анимация» обозначает лишь движение что свойственно многим областям. У Диснея цель привлечь к анимации внимание и перенести зрителя в воображаемый мир, а у дизайнера скрола сделать этот процесс минимально раздражающим и максимально естественным. Если скрол будет скакать и искрится я первым брошу камень в дизайнера.
          • 0
            Там базовые принципы не про украшательства, а про гипербализацию. Т.е. как за то же время и за то же количество кадров серьёзнее акцентировать внимание на действии, и одновременно передать плотность/массу двигающегося материала (ну и развлечь, если это надо) — ответ, не сохранять его форму и двигать нелинейно. А эти принципы про то, как конкретно менять форму и двигать.
            Линейно сдвинуть контент на нужное место — не самый наглядный и быстрый вариант.
  • 0
    // Инициализации анимации скролла к элементу с 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 А на реальном проекте интересно было бы посмотреть. В рабочий проект, без тестов я бы внедрял такой функционал с осторожностью.
    • 0
      Было бы приколько также увидеть что-то такое (прим AnimateCSS):
      // fadeInLeft, fadeInRight, fadeInBottom, fadeIntop
      $(".link a").scrollport({
          direction : "fadeInLeft"
      });
      
    • +1
      Есть такая реализация. Цитирую документацию:
      Если не передать ни одно из значений target, top или left, тогда target автоматически примет значение атрибута data-scrollport или href, или data-href.

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


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

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

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