Megu
Chakra UI + Framer Motionで画面遷移時のTransition設定

Chakra UI + Framer Motionで画面遷移時のTransition設定

2022.04.23

Chakra UI
Framer Motion
Next.js

Chakra UIはFramer Motionを基盤に作られており、Framer Motionとの連携がスムーズにできます。
Next.JSにて画面遷移時に、下から上に向かって表示されるTransitionを作成したのでそのメモ。

/pages/_app.jsの設定

全ページでTransitionが使用できるように子コンポーネントをWrap。
ChakraUIのコンポーネントも後々使用するのでChakraProvider > AnimatePresence となるようにする。

function MyApp({ Component, pageProps, router }: AppProps) {
  return (
    <>
      <ChakraProvider theme={darkTheme} resetCSS>
        <AnimatePresence
          exitBeforeEnter
          onExitComplete={() => window.scrollTo(0, 0)}
        >
          <Layout>
            <Component key={router.asPath} {...pageProps} />
          </Layout>
        </AnimatePresence>
      </ChakraProvider>
    </>
  )
}

export default MyAppT

Transition Componentの作成

components/VisibilitySection.tsx

import { ReactNode, VFC } from 'react'
import { chakra, ChakraProps, shouldForwardProp } from '@chakra-ui/react'
import { motion } from 'framer-motion'

type Props = {
  children: ReactNode
  delay?: number
  chakraProps?: ChakraProps
}

const ChakraBox = chakra(motion.div, {
  shouldForwardProp: prop => {
    return shouldForwardProp(prop) || prop === 'transition'
  }
})

const VisibilitySection: VFC<Props> = props => {
  const { children, delay = 0, chakraProps } = props
  return (
    <ChakraBox
      {...chakraProps}
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: 20 }}
      // @ts-ignore no problem in operation, although type error appears.
      transition={{
        duration: 0.8,
        delay,
        type: 'spring'
      }}
    >
      {children}
    </ChakraBox>
  )
}

export default VisibilitySection

任意のページで使用

import VisibilitySection from '../components/VisibilitySection'
...
...
<VisibilitySection delay={0.4} chakraProps={{ mb: 10 }}>
  <p>Sample Text...!!</p>
</VisibilitySection>

参考

● https://chakra-ui.com/guides/integrations/with-framer
● https://www.framer.com/docs/
● https://github.com/craftzdog/craftzdog-homepage