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

Есть много способов анимировать движущийся индикатор снаружи, но как насчет анимации внутри?

Давайте погрузимся и разберемся, как это создать в React, а затем преобразовать в хуки.

Создайте наши круги

Давайте начнем с создания серии кругов. Обычно это количество страниц, которые вам нужно пролистать, но я выбрал произвольное число (8).

Чтобы создать параллельные круги, мы даем нашему background классу display: flex, который автоматически принимает значение по умолчанию flex-direction: row.

Наш круг имеет определенный размер с небольшим полем справа, чтобы отделить каждый круг. Ключевым моментом, которого следует избегать, является то, что мы устанавливаем для него значения position: relative и overflow: hidden.

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

Добавить индикаторы движения

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

Они того же размера, что и окружающий круг, но добавление position: absolute и left: 0; top: 0 позволяет нам точно покрыть круг позади него.

Индикаторы анимации

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

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

Мы корректируем наш translateX на основе текущего выбранного индекса, на который мы смотрим, по сравнению с индексом круга, который мы визуализируем.

Когда наша страница выбрана, мы хотим, чтобы наш translateX находился на 0, чтобы он полностью покрыл фоновый круг. Итак, мы можем провести небольшую математику, и когда текущее index страницы за вычетом текущего круга рендеринга будет 0, тогда у нас будет translateX(0).

В противном случае все остальное умножается на размер круга и смещение.

Следует отметить, что мы никогда не ограничиваем движение отметками 40 или -40. Итак, если круг рендеринга имеет индекс 2, но наша выбранная страница находится в 6, это означает, что мы на расстоянии 4 страниц.

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

Автоматизировать движение

Теперь давайте автоматизируем наши движения, поскольку мы на самом деле ни к чему это не подключили. В нашем componentDidMount мы обновим наш state и увеличим его на 1.

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

Мы добавляем немного логики, чтобы после того, как наш текущий index подошел к концу, мы изменили направление его движения на приращение -1. Как только мы вернемся к началу, мы вернемся к положительному движению 1.

Преобразовать в крючки

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

Итак, сначала мы переключаем компонент нашего класса на функциональный компонент.

Сначала займемся состоянием. Единственное состояние, которое у нас было, - это текущий индекс, поэтому мы импортируем useState из React.

Когда мы вызываем его в первый раз, когда компонент монтируется, он принимает начальное значение, наше начальное значение - 0. Это вернет массив из 2 частей. Значение в массиве с индексом 0 - это значение состояния, а второе - средство обновления. Программа обновления эквивалентна setState, но для этой конкретной ловушки.

Затем у нас было componentDidMount, чтобы настроить интервал. Хук useEffect добавляет эту концепцию к нашим функциональным компонентам. Когда компонент монтируется, этот код будет запущен, поэтому будет создан наш интервал, а затем мы сможем ссылаться на наш setIndex для обновления индекса каждые 500ms.

Возвращаемое значение из нашего useEffect хука - это наша очистка, и когда мы хотим очистить наш эффект, нам нужно clearInterval, поскольку это побочный эффект, который был создан в нашей useEffect ловушке.

Наконец, поскольку мы хотим, чтобы это выполнялось только один раз, а не очищать интервал, если произойдет обновление, нам нужно передать [] в качестве второго аргумента useEffect. Это массив, который React будет сравнивать, если что-то изменится. Если это так, он запускает очистку и повторно запускает эффект. Передача пустого массива указывает React запускать этот эффект только один раз и очищать его при отключении компонента.

Ранее приращение было изменяемой ссылкой на класс. Обычно в React refs используются исключительно для получения ссылок на DOM / Elements. Хук useRef создает изменяемую ссылку, которую можно использовать не только для получения ссылок на DOM.

Мы можем хранить изменяемые данные, которые не принадлежат состоянию, но нам нужно время от времени повторять рендеринг. Значение для изменения сохраняется в current. Поэтому, если мы хотим получить доступ к значению или обновить его, нам нужно использовать increment.current;

Все вместе это выглядит так.

Конец

Теперь у вас есть возможность отображать действительно крутые анимированные индикаторы нумерации страниц! Посмотрите их вживую в Code Sandbox

Первоначально опубликовано на сайте codedaily.io 13 января 2019 г.