It would be great to get some realworld examples. When it"s production ready, we would like to see some real scenarios, like page transitions in use with react router dom.
`
const AnimationSettings = {
transition: { duration: 0.5 },
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
};
const Routes = () => {
const { location } = React.useContext(__RouterContext);
return (
<Route path="/board/:id" component={({ match }) => <BoardDetail boardId={match.params.id} />} />
<Route path="/dashboard" exact component={Dashboard} />
<Route path="/projects" exact component={Projects} />
<Route path="/createboard" exact component={CreateBoard} />
<Route path="/statistic/:id" component={({ match }) => <Statistic questionId={match.params.id} />} />
</Switch>
</AnimatePresence>
);
};
export default Routes;
`
I'll take a crack at a React Router example today
Edit: Actually there's a few PRs waiting to land for AnimatePresence that should make this easier to pull off. But next week I'll get an example in.
Here is a working example:
import React from 'react';
import { Route, Switch, __RouterContext } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
import CreateBoard from '../components/CreateBoard/CreateBoard';
import Dashboard from '../views/Dashboard';
import BoardDetail from '../components/BoardDetail/BoardDetail';
import Statistic from '../components/Statistic/Statistic';
import Projects from '../views/Projects';
const Routes = ({ transitionType, damping, stiffness, duration, easing }) => {
const { location } = React.useContext(__RouterContext);
const animation = {
initial: { opacity: 0 },
active: {
opacity: 1,
transition: {
delay: 0.3,
when: 'beforeChildren',
staggerChildren: 0.1,
},
},
exit: { opacity: 0, y: 200 },
};
const transition =
transitionType === 'spring' ? { type: 'spring', damping, stiffness } : { type: 'tween', duration, ease: easing };
return (
<AnimatePresence>
<motion.div
key={location.key}
initial={animation.initial}
animate={animation.active}
exit={animation.exit}
transition={transition}
//positionTransition
>
<Switch location={location}>
<Route exact path="/" component={Dashboard} />
<Route path="/board/:id" component={({ match }) => <BoardDetail boardId={match.params.id} />} />
<Route path="/dashboard" exact component={Dashboard} />
<Route path="/projects" exact component={Projects} />
<Route path="/createboard" exact component={CreateBoard} />
<Route path="/statistic/:id" component={({ match }) => <Statistic questionId={match.params.id} />} />
</Switch>
</motion.div>
</AnimatePresence>
);
};
export default Routes;
And inside my board if could also do some nice staggering effects while loading in data:
import React from 'react';
import ProjectCard from '../components/ProjectCard/ProjectCard';
import { Grid } from '@material-ui/core';
import { gql } from 'apollo-boost';
import { useQuery } from '@apollo/react-hooks';
import { motion } from 'framer-motion';
const container = {
hidden: { opacity: 1, scale: 0 },
visible: {
opacity: 1,
scale: 1,
transition: {
delay: 0.3,
when: 'beforeChildren',
staggerChildren: 0.1,
},
},
};
const item = {
hidden: { y: 20, opacity: 0 },
visible: {
y: 0,
opacity: 1,
},
};
const ALL_BOARDS = gql`
query allBoards {
allBoards: board {
id
name
}
}
`;
const Projects = () => {
const { data, loading } = useQuery(ALL_BOARDS);
if (loading) {
return <div>Loading</div>;
}
return (
<motion.div variants={container} initial="hidden" animate="visible">
<Grid container spacing={4}>
{data.allBoards.map(board => (
<Grid item lg={3} sm={6} xl={3} xs={12} key={board.id}>
<motion.div key={board.id} variants={item}>
<ProjectCard projectId={board.id} projectName={board.name} />
</motion.div>
</Grid>
))}
</Grid>
</motion.div>
);
};
export default Projects;
An example to do the same with Next.js would be super awesome :D
I will have a look into it 馃檹
React Router example: https://codesandbox.io/s/framer-motion-x-react-router-n7qhp
I'm working on a Next.js example: https://github.com/natemoo-re/next.js/tree/example-framer-motion/examples/with-framer-motion
https://codesandbox.io/s/nextjs-framer-motion-9tto6
If anyone could help with a small write-up in the README, I think it would be a great way to introduce Next.js users to Framer Motion.
cc @sourcewars @BjoernRave
@natemoo-re so every component in the pages folder has to be wrapped with a motion component? Isn't there a way, where you define the animation once inside _app.s instead of every page?
Nope, they don't have to be wrapped immediately with a motion component (and they aren't.) They just have to follow the docs for using AnimatePresence with custom components.
The only requirement is that the first
motioncomponent within the custom component has anexitproperty defined.
To answer your question practically, you could just use a motion component directly in _app as long as you pass router.route as the key prop. It should be the first child of AnimatePresence and the Component should be its child.
Using Next's reccomended Layout component pattern would be another way to set a global route animation.
@natemoo-re ah okay, now I understand. Great, thanks alot for this :) Was easier than I thought :D
Here is a very basic example with Gatsby if anyone is interested:
Please use useLocation() instead of useContext(__RouterContext). Thanks :)
Note that if you choose to animate your page transitions with AnimatePresence, currently you won't be able to use AnimatePresence again inside of your pages: #746
Most helpful comment
Here is a working example:
And inside my board if could also do some nice staggering effects while loading in data: