Добавление анимации перехода маршрута в Remix

TLDR:

Посмотрите на живой сайт по адресу thomasledoux.be. Код можно найти на Github.

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

Remix позволяет очень легко добавлять переходы в маршруты при мутации данных, используя хук useTransition(). Но я хотел просто анимировать маршрут, который запрашивается при нажатии на ссылку, и анимировать текущий активный маршрут.
Самый простой способ, который я нашел для этого, — использовать Framer Motion. Обернув все мое содержимое компонентом <AnimatePresence />, мы теперь готовы добавить фактические анимации, которые мы хотели бы иметь при переходе маршрута.
Вот как выглядит моя функция App в root.tsx (основная точка входа в приложение Remix):

import {AnimatePresence, motion} from 'framer-motion'
import {useOutlet, useLocation} from 'remix'

export default function App() {
  const outlet = useOutlet()
  const data = useLoaderData<LoaderData>()

  return (
    <ThemeProvider specifiedTheme={data.theme}>
      <Document>
        <Scripts />
        <Layout>
          <AnimatePresence exitBeforeEnter initial={false}>
            <motion.main
              key={useLocation().pathname}
              initial={{x: '-10%', opacity: 0}}
              animate={{x: '0', opacity: 1}}
              exit={{y: '-10%', opacity: 0}}
              transition={{duration: 0.3}}
            >
              {outlet}
            </motion.main>
          </AnimatePresence>
        </Layout>
      </Document>
    </ThemeProvider>
  )
}
Войти в полноэкранный режим Выход из полноэкранного режима

Как вы можете видеть, я добавил параметр exitBeforeEnter на <AnimatePresence>, потому что я хочу, чтобы за один раз рендерился только один компонент. Выходящий компонент закончит свою анимацию выхода до того, как будет отрисован входящий компонент. Поскольку я также хочу, чтобы начальная загрузка не вызывала анимацию, я использовал параметр initial={false}. Это приведет к тому, что компоненты, присутствующие при первой загрузке AnimatePresence, начнут отображаться в состоянии анимации. Только те компоненты, которые появятся после этого начального рендеринга, будут анимированы.

Сохраняя мой <Layout> вне <AnimatePresence>, мой header и footer не будут анимированы, только контент внутри страницы, как я и хотел!

В <motion.main> вы должны передать ключ, чтобы Framer мог идентифицировать уникальные маршруты, я решил передать имя пути, предоставляемое встроенным хуком useLocation() из Remix, который отлично работает.
Осталось передать реквизиты exit, initial, animate и transition, которые как бы говорят сами за себя и хорошо документированы в документации.

Это действительно базовая анимация, но мне нравится результат, он делает сайт немного более динамичным :-).
Взгляните на живой сайт по адресу thomasledoux.be. Код можно найти на Github.

Оцените статью
Procodings.ru
Добавить комментарий