Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. JavaScript

Создание идеальной карусели, часть 1

by
Difficulty:AdvancedLength:LongLanguages:
This post is part of a series called Create the Perfect Carousel.
Create the Perfect Carousel, Part 2

Russian (Pусский) translation by Svetlana (you can also view the original English article)

Карусели являются основным продуктом сайтов для потоковой передачи и электронной коммерции. Оба Amazon и Netflix используют их в качестве выдающихся инструментов навигации. В этом уроке мы будем оценивать дизайн взаимодействия и того, и другого, и использовать наши результаты для реализации идеальной карусели.

В этой серии учебников мы также изучим некоторые функции движка движения по движению «Popmotion (Попмотион)». Он предлагает анимационные инструменты, такие как tweens (полезно для разбивки на страницы), отслеживание указателей (для прокрутки) и весеннюю физику (для наших восхитительных штрихов).

Часть 1 будет оценивать, как Amazon и Netflix реализовали прокрутку. Затем мы реализуем карусель, который можно прокручивать прикосновением.

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

Идеальный?

Что нужно, чтобы карусель была «идеальной»? Он должен быть доступен:

  • Мышь. Он должен предлагать предыдущие и следующие кнопки, которые легко нажимать и не скрывать контент.
  • Коснитесь (сенсорный ввод): он должен отследить палец, а затем прокрутиться с тем же импульсом, что и при падении пальца с экрана.
  • Колесико прокрутки: Часто пропускается, Apple Magic Mouse и многие треки для ноутбука обеспечивают плавное горизонтальное прокручивание. Мы должны использовать эти возможности!
  • Клавиатура. Многие пользователи предпочитают не использовать или использовать мышь для навигации. Важно сделать нашу карусель доступной, чтобы пользователи могли использовать наш продукт.

Наконец, мы сделаем еще один шаг вперед и сделаем это уверенным, восхитительным элементом UX, сделав карусель отчетливо и в явном виде с весенней физикой, когда ползунок достигнет конца.

Установка

Во-первых, давайте получим HTML и CSS, необходимые для создания рудиментарной карусели, разворачивая этот CodePen.

Перо настроено на Sass для предварительной обработки CSS и Babel для трансляции JavaScript ES6. Я также включил Popmotion, к которому можно получить доступ с помощью window.popmotion.

Вы можете скопировать код в локальный проект, если хотите, но вы должны убедиться, что ваша среда поддерживает Sass и ES6. Вам также потребуется установить Popmotion с npm install popmotion.

Создание новой карусели

На любой данной странице у нас может быть много каруселей. Поэтому нам нужен способ инкапсуляции состояния и функциональности каждого из них.

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

В своем редакторе JavaScript добавьте эту простую функцию:

Мы добавим код этой карусели в эту функцию карусели.

Способы  прокрутки и для чего она.

Наша первая задача - сделать карусельный свиток. Мы можем сделать два способа:

Прокрутка собственного браузера

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

Однако есть и недостатки такого подхода:

  • Содержимое вне контейнера не будет видно, что может быть ограничительным для нашего дизайна.
  • Это также ограничивает способы использования анимаций, чтобы показать, что мы достигли конца.
  • Настольные браузеры будут иметь уродливую (хотя и доступную!) Горизонтальную полосу прокрутки.

В качестве альтернативы:

Анимация translateX

Мы также могли бы анимировать свойство translateX в карусели. Это было бы очень универсально, поскольку мы могли бы реализовать именно тот дизайн, который нам нравится. translateX также очень эффективен, поскольку в отличие от свойства CSS left он может обрабатываться графическим процессором устройства.

С другой стороны, нам придется переопределить функциональность прокрутки с помощью JavaScript. Это больше работы, больше кода.

Как проложить прокрутку Amazon и Netflix?

Оба карусели Amazon и Netflix делают разные компромиссы в решении этой проблемы.

Amazon оживляет свойство карусели слева в режиме «рабочий стол». Анимация слева - невероятно плохой выбор, так как изменение этого параметра приводит к пересчету компоновки. Это интенсивность процессора, и более старые машины будут бороться за 60 кадров в секунду.

Тот, кто принял решение анимировать левый, а не translate X, должен быть настоящим идиотом (spoiler (прерыватель потока): это я, еще в 2012 году. В те дни мы не были такими просвещенными).

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

Screenshot of Amazon illustrating lack of design bleed

Netflix правильно анимирует свойство translateX carousel, и он делает это на всех устройствах. Это позволяет им иметь дизайн, который выходит за пределы карусели:

Screenshot of Netflix carousel illustrating design bleed

Это, в свою очередь, позволяет им придумывать дизайн, где предметы увеличены за пределами краев x и y карусели, а окружающие предметы перемещаются с пути:

Screenshot of Netflix carousel illustrating enlarged item

К сожалению, повторная реализация прокрутки Netflix для сенсорных устройств неудовлетворительна: в ней используется система разбиения на страницы на жестов, которая кажется медленной и громоздкой. Кроме того, для горизонтальных колес прокрутки не учитывается.

Мы можем сделать лучше. Давайте сделаем код!

Прокрутка Как Pro

Наш первый шаг - захватить узел .slider. Пока мы на нем, давайте возьмем элементы, которые он содержит, чтобы мы могли определить размер ползунка.

Измерение карусели 

Мы можем определить видимую область ползунка, измеряя его ширину:

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

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

После измерения sliderVisibleWidth напишите:

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

Благодаря этим измерениям мы готовы начать прокрутку нашей карусели.

Настройка translateX

Popmotion поставляется с рендерером CSS для простой и эффективной настройки свойств CSS. Он также имеет функцию значения, которая может использоваться для отслеживания чисел и, что важно (как мы вскоре увидим), запросить их скорость.

В верхней части вашего файла JavaScript импортируйте их так:

атем на линии после установки minXOffset создайте рендеринг CSS для нашего слайдера:

И создайте значение для отслеживания смещения x слайдера и обновите свойство translateX слайдера, когда оно изменится:

Теперь перемещение ползунка горизонтально так же просто, как и запись:

Попробуй! 

Сенсорная прокрутка

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

В нашей функции startTouchScroll мы хотим:

  • Остановите любые другие действия, включив slider (слайдер)X.
  • Найдите точку касания начала.
  • Прослушайте следующее событие touchmove, чтобы узнать, перетаскивается ли пользователь по вертикали или по горизонтали.

После document.addEventListener добавьте:

Это остановит любые другие действия (например, прокрутку импульсов с физическим питанием, которые мы будем использовать в stopTouchScroll), перемещая ползунок. Это позволит пользователю немедленно «поймать» слайдер, если он прокручивает элемент или заголовок, на который они хотят щелкнуть.

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

Мы хотим поделиться этим touchOrigin между обработчиками событий. Итак, после let action; (действия;) Добавить:

Вернемся в наш обработчик startTouchScroll, добавьте:

Теперь мы можем добавить touchmove (прослушиватель) событий  в документ, чтобы определить направление перетаскивания на основе этого touchOrigin:

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

Popmotion включает некоторые полезные калькуляторы для измерения таких вещей, как расстояние между двумя координатами x / y. Мы можем импортировать таких:

Тогда измерение расстояния между двумя точками зависит от использования калькулятора расстояния:

Теперь, если касание переместилось, мы можем отключить этот прослушиватель событий.

Измерьте угол между двумя точками с помощью калькулятора угла:

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

Эта функция возвращает true, если заданный угол находится в пределах -90 +/- 45 градусов (прямо вверх) или 90 +/- 45 градусов (прямо вниз). Таким образом, мы можем добавить другое предложение возврата, если эта функция вернет true.

Отслеживание указателя

Теперь мы знаем, что пользователь пытается прокрутить карусель, мы можем начать отслеживать их пальцы. Popmotion предлагает действие указателя, которое выводит координаты x / y мыши или указателя касания.

Во-первых, указатель импорта:

Чтобы отслеживать сенсорный ввод, предоставьте исходное событие указателю:

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

Трансформаторы - это чистые функции, которые принимают значение и возвращают его - да-трансформируются. Например: const double = (v) => v * 2.

applyOffset - это валютная функция. Это означает, что когда мы вызываем его, он создает новую функцию, которая затем может быть передана значение. Сначала мы вызываем его числом, которое мы хотим измерить смещение, в этом случае текущее значение action.x и число, чтобы применить это смещение к. В этом случае это наш sliderX.

Поэтому наша функция applyOffset будет выглядеть так:

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

Остановка, со стилем

Карусель теперь перетаскивается прикосновением! Вы можете проверить это, используя эмуляцию устройства в Инструментах разработчика Chrome.

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

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

Во-первых, добавьте его в наш постоянно растущий список импорта:

Затем, в конце нашей функции stopTouchScroll, добавьте:

Здесь от и скорость устанавливаются с текущим значением и скоростью sliderX. Это гарантирует, что наше физическое моделирование имеет те же начальные начальные условия, что и перемещение движения пользователя.

трение устанавливается равным 0,2. Трение задается как значение от 0 до 1, при этом 0 не является трением вообще, а 1 является абсолютным трением. Попробуйте сыграть с этим значением, чтобы увидеть, какое изменение он внесет в «чувство» карусели, когда пользователь перестает перетаскивать.

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

Границы

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

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

Во-первых, импортный зажим:

Мы хотим использовать эту функцию зажима на нашей карусели, поэтому добавьте эту строку после определения minXOffset:

Мы собираемся изменить два выхода, которые мы установили в наших действиях, используя некоторую легкую функциональную композицию с трансформатором трубы.

труба

Когда мы вызываем функцию, мы пишем ее так:

Если мы хотим передать результат этой функции другой функции, мы можем написать следующее:

Это становится немного трудным для чтения, и это только ухудшается, когда мы добавляем все больше и больше функций.

С трубой мы можем создать новую функцию из foo и bar, которую мы можем использовать повторно:

Он также написан в естественном порядке начала -> завершения, что облегчает его выполнение. Мы можем использовать это, чтобы составить applyOffset и clamp в одну функцию. Импорт трубы:

Замените обратный вызов вывода нашего указателя на:

И замените выходной обратный вызов физики:

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

Теперь, когда вы тащите и бросаете карусель, он не сдвинется с места за пределы своих границ.

Резкая остановка не очень удовлетворяет. Но это проблема для более поздней части!

Вывод

Это все для части 1. До сих пор мы рассмотрели существующие карусели, чтобы увидеть сильные и слабые стороны различных подходов к прокрутке. Мы использовали отслеживание входных данных Popmotion и физику для того, чтобы наглядно анимировать наш перевод карусели translateX с сенсорной прокруткой. Мы также познакомились с функциональным составом и карриными функциями.

Вы можете получить прокомментированную версию «истории до сих пор» на этом CodePen.

В следующих выпусках мы рассмотрим:

  • прокрутка с помощью колеса мыши
  • повторное измерение карусели при изменении размера окна
  • разбиение на страницы, доступность клавиатуры и мыши
  • восхитительные прикосновения, с помощью источника физики

Ждем Вас там!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.