Framer X » Animation » Example animations » 28. Variants: Nesting

28. Variants: Nesting

A child Frame doesn’t need any animate, or whileHover, etc. to be animated simultaneously. It just needs to have a set of variants with the same names as its parent.

Open Framer Motion version in CodeSandbox

Code Component

export function CC28VariantsNesting() {
    const parent = {
        variantA: { scale: 1 },
        variantB: { scale: 1.25 },
    }

    const child = {
        variantA: { bottom: 0, right: 0, rotate: 0 },
        variantB: { top: 0, left: 0, rotate: 180 },
    }

    return (
        <Frame
            // Visual & layout
            size={150}
            radius={30}
            backgroundColor="rgba(255,255,255,0.5)"
            center
            // Animation
            variants={parent}
            initial="variantA"
            whileHover="variantB"
        >
            <Frame
                // Visual & layout
                size={85}
                radius="20px 20px 30px 20px"
                backgroundColor="#fff"
                right={0}
                bottom={0}
                // Animation
                variants={child}
                transition={{
                    type: "spring",
                    damping: 10,
                    mass: 0.2,
                    stiffness: 150,
                }}
            />
        </Frame>
    )
}

Framer Motion

export function FM28VariantsNesting() {
    const parent = {
        variantA: { scale: 1 },
        variantB: { scale: 1.25 },
    }

    const child = {
        variantA: { bottom: 0, right: 0, rotate: 0 },
        variantB: { top: 0, left: 0, rotate: 180 },
    }

    return (
        <Center>
            <motion.div
                style={{
                    width: 150,
                    height: 150,
                    borderRadius: 30,
                    backgroundColor: "rgba(255,255,255,0.5)",
                    position: "relative",
                }}
                variants={parent}
                initial="variantA"
                whileHover="variantB"
            >
                <motion.div
                    style={{
                        width: 85,
                        height: 85,
                        borderRadius: "20px 20px 30px 20px",
                        backgroundColor: "#fff",
                        position: "absolute",
                        bottom: 0,
                        right: 0,
                    }}
                    variants={child}
                    transition={{
                        type: "spring",
                        damping: 10,
                        mass: 0.2,
                        stiffness: 150,
                    }}
                />
            </motion.div>
        </Center>
    )
}

Overrides

export function Parent(): Override {
    return {
        initial: "variantA",
        whileHover: "variantB",
        variants: { variantA: { scale: 1 }, variantB: { scale: 1.25 } },
    }
}

export function Child(): Override {
    return {
        variants: {
            variantA: { bottom: 0, right: 0, rotate: 0 },
            variantB: { top: 0, left: 0, rotate: 180 },
        },
        transition: {
            type: "spring",
            damping: 10,
            mass: 0.2,
            stiffness: 150,
        },
    }
}

Leave a Reply