Search

17. SVG path length

17. SVG path length

Most of these examples use motion.divs, but you can animate any HTML or SVG element with Framer Motion; there are even a few extra properties for SVG paths.

⚡️ Some Examples – 17 – SVG path length
open in CodeSandbox

This is primarily a simple animate-driven animation, toggled by the isChecked state.

When isChecked is false:

  • The motion.div will have a scale of 0.8 and a 50% transparent white backgroundColor,
  • and the pathLength of the motion.path will be 0.

When isChecked is true:

  • The motion.div will have a scale of 1, and its backgroundColor becomes fully opaque,
  • and the pathLength of the motion.path will be 0.9.
export function Example() {
    const [isChecked, setIsChecked] = useState(true);
    const pathLength = useMotionValue(0);
    const opacity = useTransform(pathLength, [0.05, 0.15], [0, 1]);

    return (
        <motion.div
            style={{
                width: 150,
                height: 150,
                borderRadius: 30,
                backgroundColor: "rgba(255,255,255,0.5)",
                cursor: "pointer"
            }}
            animate={{
                scale: isChecked ? 1 : 0.8,
                backgroundColor: isChecked
                    ? "rgba(255, 255, 255, 1)"
                    : "rgba(255, 255, 255, 0.5)"
            }}
            transition={{ type: "spring", stiffness: 300, damping: 20 }}
            onTap={() => setIsChecked(!isChecked)}
        >
            <svg xmlns="http://www.w3.org/2000/svg" width="150" height="150">
                <motion.path
                    d="M38 74.707l24.647 24.646L116.5 45.5"
                    fill="transparent"
                    strokeWidth="20"
                    stroke="#39e"
                    strokeLinecap="round"
                    animate={{ pathLength: isChecked ? 0.9 : 0 }}
                    style={{ pathLength, opacity }}
                    // transition={{ duration: 3 }}
                />
            </svg>
        </motion.div>
    );
}

But we’re also hooking into the pathLength animation to change the motion.path’s opacity.

A pathLength Motion value is passed to the path’s pathLength property, and a useTransform() is used to change the path’s opacity at the very beginning of the pathLength animation: The checkmark quickly fades in when pathLength changes from 0.05 to 0.15.

export function Example() {
    const [isChecked, setIsChecked] = useState(true);
    const pathLength = useMotionValue(0);
    const opacity = useTransform(pathLength, [0.05, 0.15], [0, 1]);

    return (
        <motion.div
            style={{
                width: 150,
                height: 150,
                borderRadius: 30,
                backgroundColor: "rgba(255,255,255,0.5)",
                cursor: "pointer"
            }}
            animate={{
                scale: isChecked ? 1 : 0.8,
                backgroundColor: isChecked
                    ? "rgba(255, 255, 255, 1)"
                    : "rgba(255, 255, 255, 0.5)"
            }}
            transition={{ type: "spring", stiffness: 300, damping: 20 }}
            onTap={() => setIsChecked(!isChecked)}
        >
            <svg xmlns="http://www.w3.org/2000/svg" width="150" height="150">
                <motion.path
                    d="M38 74.707l24.647 24.646L116.5 45.5"
                    fill="transparent"
                    strokeWidth="20"
                    stroke="#39e"
                    strokeLinecap="round"
                    animate={{ pathLength: isChecked ? 0.9 : 0 }}
                    style={{ pathLength, opacity }}
                    // transition={{ duration: 3 }}
                />
            </svg>
        </motion.div>
    );
}

It’s hardly noticeable, but you can uncomment the transition line inside the motion.path to see a three-second-long version of the animation.

Leave a Reply

plugins premium WordPress
Scroll to Top