Search code examples
reactjsframer-motion

When I use framer-motion I can't get the 'when:beforeChildrfen/afterChildren' property to work


I've created a React component to experiment with the when property of Framer Motion. My setup includes a parent element and its child element. I intended for the child element to complete its movement before the parent element starts its animation. However, the when: "afterChildren" property doesn't seem to work as expected, because both the parent and the child move simultaneously. Here's the code snippet for reference:

import React from 'react';
import { motion } from "framer-motion";

function App() {
    const parentVariant = {
        initial: {
            x: '0vw',
        },
        animate: {
            x: '100vw',
            transition: {
                duration: 40,
                when: "afterChildren",
            },
        },
    };

    const childVariant = {
        initial: {
            x: '0vw',
        },
        animate: {
            x: '100vw',
            transition: {
              
                duration: 40,
            },
        },
    };

    return (
        <div className="App">
            <motion.div
                variants={parentVariant}
                style={{ width: "100px", height: "100px", backgroundColor: "gray" }}
                initial="initial"
                animate="animate"
            >
                <motion.div
                    variants={childVariant}
                    style={{ width: "50px", height: "50px", backgroundColor: "red" }}
                    initial="initial"
                    animate="animate"
                />
            </motion.div>
        </div>
    );
}

export default App;

Having set the when: "afterChildren" property on the parent, I expect it to perform its animation once the child has completed theirs.


Solution

  • Remove the initial and animate prop from the childVariant.

    <motion.div
      variants={parentVariant}
      style={{ width: "100px", height: "100px", backgroundColor: "gray" }}
      initial="initial"
      animate="animate"
    >
      <motion.div
        variants={childVariant}
        style={{ width: "50px", height: "50px", backgroundColor: "red" }}
      />
    </motion.div>
    

    I've hit this issue before and couldn't find out why I needed to remove those props. I noticed that each example in the Framer Motion docs on Orchestration don't have an initial or animate props on the children elements and gave it a shot and it worked. My guess is that passing those props tells the component to ignore any sort of orchestration and immediately animate based on the animation variants and transition properties.

    Here is a working example.