Animation » Example Animations » 34. Swapping elements

34. Swapping elements

You can synchronize layout animations by wrapping the elements in an <AnimateSharedLayout>. And by giving elements the same layoutId, you can animate between them.

Code component

Here the colored pills behind the options (with a style of selectionStyle) all have the same layoutId value: "selected".

When one is removed and another is added (when the value of the selected state changes), <AnimateSharedLayout> adds an animation from the old one to the new one.

const tabs = [
    { name: "Red", color: "#f00" },
    { name: "Purple", color: "#b1f" },
    { name: "Orange", color: "#f90" },
    { name: "Green", color: "#0c0" },
]

export default function CC_34_Swapping_elements(props) {
    const [selected, setSelected] = React.useState(0)

    return (
        <div>
            <div style={containerStyle}>
                <AnimateSharedLayout>
                    {tabs.map(({ name, color }, i) => (
                        <motion.div
                            style={tabStyle}
                            key={i}
                            initial={{
                                color: i === selected ? "#fff" : "#222",
                            }}
                            animate={{
                                color: i === selected ? "#fff" : "#222",
                            }}
                            onTap={() => setSelected(i)}
                        >
                            {name}
                            {i === selected && (
                                <motion.div
                                    style={selectionStyle}
                                    layoutId="selected"
                                    initial={{ backgroundColor: color }}
                                    animate={{ backgroundColor: color }}
                                />
                            )}
                        </motion.div>
                    ))}
                </AnimateSharedLayout>
            </div>
        </div>
    )
}

const containerStyle: React.CSSProperties = {
    borderRadius: 21,
    backgroundColor: "rgba(255, 255, 255, 0.2)",
    padding: 6,
    display: "flex",
    alignContent: "flex-start",
    alignItems: "start",
    justifyContent: "start",
}

const tabStyle: React.CSSProperties = {
    height: 30,
    position: "relative",
    padding: "3px 15px",
    margin: 0,
    fontFamily: "sans-serif",
    fontSize: 20,
    fontWeight: 700,
    cursor: "pointer",
    zIndex: 1,
}

const selectionStyle: React.CSSProperties = {
    width: "100%",
    height: "100%",
    borderRadius: 15,
    position: "absolute",
    top: 0,
    left: 0,
    zIndex: -1,
}

Code override

Layout animations don’t work with code overrides, as demonstrated in the previous example.


Leave a Reply