Animation » Example Animations » 22. Keyframes: Morphing an SVG path

22. Keyframes: Morphing an SVG path

Every SVG <path> has a d attribute that describes its shape, and you can animate it by turning it into a motion.path, also with keyframes.

Code component

export default function CC_22_Keyframes_Morphing_an_SVG_path(props) {
    return (
        <div>
            <svg
                style={{
                    width: 200,
                    height: 200,
                    background: "rgba(255, 255, 255, 0.4)",
                    borderRadius: 30,
                }}
            >
                <motion.path
                    style={{
                        stroke: "#70f",
                        strokeWidth: 20,
                        strokeLinecap: "round",
                        fill: "transparent",
                    }}
                    d="M 40,40 Q 160,40 160,160"
                    animate={{
                        d: [
                            "M 40,40 Q 160,40 160,160",
                            "M 160,40 Q 100,100 40,160",
                            "M 160,160 Q 100,160 40,160",
                            "M 160,40 Q 100,160 40,40",
                            "M 160,40 Q 100,40 40,40",
                            "M 40,40 Q 160,40 160,160",
                        ],
                    }}
                    transition={{
                        repeat: Infinity,
                        ease: "easeInOut",
                        duration: 6,
                        times: [0, 0.16, 0.33, 0.5, 0.66, 0.83],
                    }}
                />
            </svg>
        </div>
    )
}

Code override

A Graphic on the canvas is also (technically) an SVG, but you can’t attach an override to it. So how do you animate an SVG with code overrides? By inserting the SVG as the override’s children:

export function Keyframes_Morphing_an_SVG_path(Component): ComponentType {
    return (props) => {
        return (
            <Component
                {...props}
                children={
                    <svg style={{ width: 200, height: 200 }}>
                        <motion.path
                            style={{
                                stroke: "#70f",
                                strokeWidth: 20,
                                strokeLinecap: "round",
                                fill: "transparent",
                            }}
                            animate={{
                                d: [
                                    "M 40,40 Q 160,40 160,160",
                                    "M 160,40 Q 100,100 40,160",
                                    "M 160,160 Q 100,160 40,160",
                                    "M 160,40 Q 100,160 40,40",
                                    "M 160,40 Q 100,40 40,40",
                                    "M 40,40 Q 160,40 160,160",
                                ],
                            }}
                            transition={{
                                repeat: Infinity,
                                ease: "easeInOut",
                                duration: 6,
                                times: [0, 0.16, 0.33, 0.5, 0.66, 0.83],
                            }}
                        />
                    </svg>
                }
            />
        )
    }
}

Other examples of using children in a code component: 20. SVG path length and 30. SVG gradient animation.


Leave a Reply