Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit animation with framer-motion #414

Closed
mohas opened this issue Feb 12, 2024 · 7 comments
Closed

Exit animation with framer-motion #414

mohas opened this issue Feb 12, 2024 · 7 comments

Comments

@mohas
Copy link

mohas commented Feb 12, 2024

Hi, I've setup a simple demo to demonstrate that exit animation using framer-motion package does not work, does anyone have any idea how to make it to work?

https://codesandbox.io/p/sandbox/elastic-violet-9t9r4h

here is documentation on AnimatePresense component:
https://www.framer.com/motion/animate-presence/

any ideas or contributions are welcome thank you

@molefrog
Copy link
Owner

Is the link correct? I got 404 when I try to open the demo

@mohas
Copy link
Author

mohas commented Feb 13, 2024

sorry for the confusion it can be viewed now

@molefrog
Copy link
Owner

Per framer-motion docs:

AnimatePresence works by detecting when direct children are removed from the React tree.

The issue is that Route is the direct child here, not the route's content. You might need to perform matching manually to conditionally render the child of AnimatePresence like so:

export default function RouteAnimated() {
  const [match] = useRoute("/")

  return (
    <div className="App">
      <AnimatePresence mode="wait">
        {match &&
          <motion.div
            initial="in"
            animate="stay"
            exit="out"
            variants={animateVariants}
            transition={{ duration: 1 }}
          >
            Page 1
            <br />
            <Link to="/2">To 2</Link>
          </motion.div>
          }
      </AnimatePresence>
    </div>
  );
}

@mohas
Copy link
Author

mohas commented Feb 16, 2024

if I do it like this would I be losing anything that wouter offers, what will be the pros and cons?

@molefrog
Copy link
Owner

molefrog commented Feb 20, 2024

if I do it like this would I be losing anything that wouter offers, what will be the pros and cons?

I know but there is currently no way to achieve that using Route. Even if you look at the React Router example from framer-motion docs, you will see that they use useRoutes instead to manually get the element needed for rendering.

We don't ship useRoutes yet, but I spent some time implementing it using current API, and it worked!

const useRoutes = (routes) => {
  // save the length of the `routes` array that we receive on the first render
  const [routesLen] = useState(() => routes.length);

  // because we call `useRoute` inside a loop the number of routes can't be changed!
  // otherwise, it breaks the rule of hooks and will cause React to break
  if (routesLen !== routes.length) {
    throw new Error(
      "The length of `routes` array provided to `useRoutes` must be constant!"
    );
  }

  const matches = routes.map((def) => {
    return useRoute(def.path);
  });

  for (let [index, match] of matches.entries()) {
    const [isMatch, params] = match;

    if (isMatch) {
      return cloneElement(routes[index].element, { params });
    }
  }

  return null;
};

I think I can update the README and add this to the FAQ. I would also consider adding useRoutes, though I am not sure yet if this should be part of the core.

@molefrog
Copy link
Owner

I have added an FAQ item to the README on using wouter with framer-motion.

@eriksachse
Copy link

eriksachse commented Mar 27, 2024

Here is a working CSB: https://codesandbox.io/p/sandbox/romantic-wind-s5ghpj
GitHub in case I have to remove it from CSB: https://github.com/eriksachse/romantic-wind-s5ghpj

Edit: Make sure to use {cloneElement(element, { key: location})} instead of {cloneElement(element, { key: location.pathname })} I think something changed somewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants