Fala mano, boa tarde. Eu acho esse efeito muito irado e repliquei no meu novo site pessoal que estou desenvolvendo.
A mágica toda quem faz é a lib de animação framer-motion:
Se você for ao código do Zeno vai ter esse cara:
import { AnimateSharedLayout } from 'framer-motion';
Atualmente ele foi removido e basta vc usar o layoutId.
https://www.framer.com/motion/guide-upgrade/#50
Aqui o exemplo do meu site usando o layoutId:
Github:
https://github.com/yurimutti/yurimutti.com/blob/main/src/components/layouts/navbar/index.tsx
Deploy: https://yurimutti-com.vercel.app/
JSX:
<S.Anchor onHoverStart={() => setHovered(page)}>
{isHovered && (
<S.NavHovered
layoutId="shape"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
/>
)}
{page}
</S.Anchor>
Estilos para deixar ele atrás dos links:
export const Anchor = styled(motion.a, {
position: 'relative',
height: '40px',
zIndex: 1,
padding: '2
′
,color:
′
slate12',
cursor: 'pointer',
color: '$slate1',
},
});
export const NavHovered = styled(motion.span, {
position: 'absolute',
inset: 0,
backgroundColor: 'slate6
′
,borderRadius:
′
default',
zIndex: -1,
});
Links úteis:
https://codesandbox.io/s/framer-motion-2-animatesharedlayout-animate-between-different-components-dy0bv