Skip to example

AnimateView: Clip path

An example of using AnimateView with custom clipPath values to create a reveal animation from center outwards using Motion for React.

React

Source code

"use client"

import { AnimateView } from "motion/react-animate-view"
import { startTransition, useState } from "react"

export default function ClipPathExample() {
    const [isOpen, setIsOpen] = useState(false)

    return (
        <div className="clip-path-container">
            <button
                className="clip-path-button"
                onClick={() => startTransition(() => setIsOpen(!isOpen))}
            >
                {isOpen ? "Close" : "Open"}
            </button>
            <div className="clip-path-slot">
                {isOpen && (
                    <AnimateView
                        enter={{
                            clipPath: [
                                "circle(0% at 50% 50%)",
                                "circle(75% at 50% 50%)",
                            ],
                            transition: { duration: 0.6, ease: "easeOut" },
                        }}
                        exit={{
                            clipPath: [
                                "circle(75% at 50% 50%)",
                                "circle(0% at 50% 50%)",
                            ],
                            transition: { duration: 0.4, ease: "easeIn" },
                        }}
                    >
                        <img
                            className="clip-path-image"
                            src="/photos/amsterdam-25/image-11.jpg"
                            alt="Amsterdam"
                        />
                    </AnimateView>
                )}
            </div>
            <StyleSheet />
        </div>
    )
}

/** ==============   Styles   ================ */

function StyleSheet() {
    return (
        <style>{`
            .clip-path-container {
                display: flex;
                flex-direction: column;
                align-items: center;
                gap: 20px;
            }

            .clip-path-button {
                padding: 10px 32px;
                background-color: var(--accent);
                color: var(--black);
                border: none;
                border-radius: 10px;
                font-size: 15px;
                font-weight: 600;
                cursor: pointer;
            }

            .clip-path-button:hover {
                opacity: 0.9;
            }

            .clip-path-slot {
                width: 340px;
                height: 240px;
                border-radius: 16px;
            }

            .clip-path-image {
                width: 340px;
                height: 240px;
                object-fit: cover;
                border-radius: 16px;
            }
        `}</style>
    )
}