I am trying to do rotation animation but for some reason right after rotation, the element appears to be offset from the actual location for a fraction of seconds.
Here's my code:
import { useAppDispatch, useAppSelector } from '@/redux/hooks';
import { updateShowMore } from '@/slices/navigation.slice';
import React from 'react';
import { BsJustify } from 'react-icons/bs';
import { MdOutlineClose } from 'react-icons/md';
import classes from './ViewIcon.module.css';
import { motion, AnimatePresence } from 'framer-motion';
export default function ViewIcon() {
const { showMore } = useAppSelector((state) => state.navigation);
const dispatch = useAppDispatch();
const toggleResults = (value: boolean) => dispatch(updateShowMore(value));
return (
<React.Fragment>
<AnimatePresence>
{showMore && (
<motion.div
initial={{ rotateZ: -180, origin: 0 }}
animate={{ rotateZ: 0 }}
exit={{ rotateZ: 0 }}
key={'exit-animation-hide'}
>
<MdOutlineClose
className={classes.ShowMore}
onClick={() => toggleResults(false)}
/>
</motion.div>
)}
</AnimatePresence>
<AnimatePresence>
{!showMore && (
<motion.div
initial={{ rotateZ: 180 }}
animate={{ rotateZ: 0 }}
exit={{ rotateZ: 0 }}
key={'exit-animation-show'}
>
<BsJustify
className={classes.ShowMore}
onClick={() => toggleResults(true)}
/>
</motion.div>
)}
</AnimatePresence>
</React.Fragment>
);
}
Ideally I want as the first one turns and disappears, the second one to turn and appear but it seems to do a wierd behaviour while disappearing it appears to the left for certain amount of time.
The way AnimatePresence
works is that it keeps exiting elements in the virtual DOM long enough for them to complete their exit animation before being removed. This means even though you have a simple boolean that determines which icon to show, during the transition between the two icons both are actually present in the DOM.
I can't see the rest of your code, but I'm guessing that the parent element of this component is set to display: flex
, or you have some equivalent styling that causes the icons the space themselves out when both are present in the title bar.
One fix for this would be to have the icons contained by a div
instead of a React.Fragment
, and position the icons absolutely within that div so they appear on top of one another when both are present in the div.
The parent element will then space the single div
element to the far right even when both icon elements are present within it.