Эта проблема
При создании приложения OneJournal я хотел обеспечить функциональность смахивания для перехода между записями журнала. Однако это создало проблему, потому что список записей журнала бесконечен. В то время я использовал Framer Motion для других анимаций и решил создать карусель с этим вместо использования другой библиотеки, которая потенциально увеличила бы размер пакета, а не реализовала ее самостоятельно.
Framer Motion предоставляет удобный набор примитивов для создания сложных анимаций, и, используя эти примитивы, мы можем достичь бесконечной карусели с очень небольшим количеством кода. Статья разбита на три раздела, в которых мы будем постепенно создавать эту карусель.
- Определение интерфейса для нашей карусели
- Размещение элементов на экране
- Добавление поведения перетаскивания.
Если вас интересует только конечный результат, вы можете прокрутить страницу вниз и найти ссылку на Codesandbox и Github.
VirtualizedPage
Интерфейс
Нам нужно будет динамически отображать дочерние элементы на основе текущего видимого индекса, а также страницы слева и справа от этого индекса. Для этого мы можем использовать свойства рендеринга и передавать индекс, который мы хотим отображать. Это очень похоже на то, как это делает React-window.
Теперь, когда мы знаем, как будет выглядеть интерфейс, мы можем начать думать о создании компонентов. Мы разделим проблему на два разных компонента.
Один будет отвечать за организацию всего, а другой - за отрисовку дочерних страниц.
Размещение различных предметов в карусели
Теперь, когда у нас есть основы и определен API, мы можем начать работу над позиционированием различных элементов или страниц в карусели.
В нашем простом случае мы разместим страницы рядом друг с другом. Это можно сделать, указав левую и правую стороны страницы на основе индекса. Поскольку overflowX
установлен в hidden
на родительском элементе, страницы слева и справа не будут видны, пока мы не начнем перетаскивание.
style={{ ...pageStyle, left: `${index * 100}%`, right: `${index * 100}%` }}
Добавить поведение перетаскивания
Чтобы добавить поведение перетаскивания, нам нужно будет синхронизировать все элементы друг с другом. К счастью, framer-motion предоставляет ловушку для этого, nameduseMotionValue
.
Теперь у нас есть кое-что, куда вы можете перетаскивать элементы, но у нас все еще есть несколько проблем, которые нужно решить.
- Карусель отображает только элементы с index
-1, 0, 1
и никогда не обновляется. - Карусель не привязывается к элементу при отпускании
Чтобы выполнить оба этих требования, нам нужно будет обновить текущий индекс и оживить x
до правильного значения. Для простоты мы будем обновлять индекс, когда пользователь перетаскивает элемент более чем на 1/4 ширины контейнера.
Подведение итогов
Используя примитивы, предоставляемые движением кадра, мы можем легко создать нашу собственную версию многоразовой карусели. Этот компонент используется для обзора журнала, навигации по календарю и галереи изображений внутри приложения.
Вы можете найти окончательный результат здесь:
https://codesandbox.io/s/github/koenvg/infinite-carousel-with-framer-motion
https://github.com/ koenvg / бесконечная карусель с движением кадра