I have a project with next.js page router
I'm making a page transition with framer-motion and I want the paragraph to have the value of the current document.title
It works fine the issue is let's say if I'm on the about page and the title is about when I move to contact the paragraph animation will show about then contact, and if I went from contact to home I will see contact then home
import React, { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { useRouter } from 'next/router';
import { text, curve, translate } from './animation';
const anim = (variants: { [key: string]: any }) => {
return {
variants,
initial: "initial",
animate: "enter",
exit: "exit"
}
}
export default function Curve({ children, backgroundColor }: { children: React.ReactNode, backgroundColor: string }) {
const router = useRouter();
const [dimensions, setDimensions] = useState<{ width: number | null, height: number | null }>({ width: null, height: null });
const [pageTitle, setPageTitle] = useState<string | null>(null);
useEffect(() => {
function resize() {
setDimensions({
width: window.innerWidth,
height: window.innerHeight
})
}
resize();
window.addEventListener("resize", resize)
return () => {
window.removeEventListener("resize", resize);
}
}, [])
useEffect(() => {
setPageTitle(document.title || null);
const handleRouteChange = (url: string) => {
setPageTitle(document.title || null);
};
router.events.on('routeChangeComplete', handleRouteChange);
return () => {
router.events.off('routeChangeComplete', handleRouteChange);
};
}, [router.events]);
return (
<div className='page curve' style={{ backgroundColor }}>
<div style={{ opacity: dimensions.width == null ? 1 : 0 }} className='background' />
<motion.p className='route' {...anim(text)}>
{pageTitle}
</motion.p>
{dimensions.width != null && <SVG {...dimensions} />}
{children}
</div>
)
}
const SVG = ({ height, width }: { height: number | null, width: number | null }) => {
if (width == null || height == null) {
return null;
}
const initialPath = `
M0 300
Q${width / 2} 0 ${width} 300
L${width} ${height + 300}
Q${width / 2} ${height + 600} 0 ${height + 300}
L0 0
`
const targetPath = `
M0 300
Q${width / 2} 0 ${width} 300
L${width} ${height}
Q${width / 2} ${height} 0 ${height}
L0 0
`
return (
<motion.svg {...anim(translate)}>
<motion.path {...anim(curve(initialPath, targetPath))} />
</motion.svg>
)
}
