Shiny Button Component

Copy component

Copy component

Shiny Button Component

Copy component

Component

Shiny Button Component

This is a beautifully shiny skeuomorphic button, originally designed by Verse and recreated as a Framer component. This project serves as a perfect example of how we can combine overrides and component variants in Framer to achieve creative effects.

image of Nandi Muzsik
profile picture of verse

Created by

Shiny Button Component
Shiny Button Component
Shiny Button Component

About the resource

This effect mixes overrides with component variants.

First off, there's a layer inside the button that tracks the cursor thanks to a "Cursor-Follow" override when we hover over the button.

Next, we've got another override used on the button component. This one makes it scale down when clicked.

These overrides can be found in the remix, but if you want, you can also copy the code from below.

Cursor follow code override for Framer

If you want to take a look at how such a code override is built in Framer, feel free to copy this code from below and dig into it.

About the resource

This effect mixes overrides with component variants.

First off, there's a layer inside the button that tracks the cursor thanks to a "Cursor-Follow" override when we hover over the button.

Next, we've got another override used on the button component. This one makes it scale down when clicked.

These overrides can be found in the remix, but if you want, you can also copy the code from below.

Cursor follow code override for Framer

If you want to take a look at how such a code override is built in Framer, feel free to copy this code from below and dig into it.

About the resource

This effect mixes overrides with component variants.

First off, there's a layer inside the button that tracks the cursor thanks to a "Cursor-Follow" override when we hover over the button.

Next, we've got another override used on the button component. This one makes it scale down when clicked.

These overrides can be found in the remix, but if you want, you can also copy the code from below.

Cursor follow code override for Framer

If you want to take a look at how such a code override is built in Framer, feel free to copy this code from below and dig into it.

import type { ComponentType } from "react"
import { useRef, useState } from "react"
import { useEffect } from "react"
import { useSpring, animated } from "react-spring"

export function withCursorFollow(Component): ComponentType {
    return (props) => {
        const ref = useRef(null)
        const [isHovering, setIsHovering] = useState(false)
        const [originalPosition, setOriginalPosition] = useState({
            left: 0,
            top: 0,
        })
        const [centerPosition, setCenterPosition] = useState({
            left: 0,
            top: 0,
        })
        const springProps = useSpring({
            left: isHovering ? originalPosition.left : centerPosition.left,
            top: isHovering ? originalPosition.top : centerPosition.top,
            config: { mass: 1, tension: 170, friction: 26 },
        })

        useEffect(() => {
            if (!ref.current) return
            const buttonRect = ref.current.getBoundingClientRect()
            const elementRect = ref.current.getBoundingClientRect()
            setCenterPosition({
                left: buttonRect.width / 2 - elementRect.width / 2,
                top: buttonRect.height / 2 - elementRect.height / 2,
            })

            const handleMouseMove = (e) => {
                if (!ref.current) return
                if (e.target.closest("button")) {
                    setIsHovering(true)
                    const buttonRect = e.target.getBoundingClientRect()
                    const elementRect = ref.current.getBoundingClientRect()
                    setOriginalPosition({
                        left:
                            e.clientX - buttonRect.left - elementRect.width / 2,
                        top:
                            e.clientY - buttonRect.top - elementRect.height / 2,
                    })
                    setCenterPosition({
                        left: buttonRect.width / 2 - elementRect.width / 2,
                        top: buttonRect.height / 2 - elementRect.height / 2,
                    })
                } else {
                    setIsHovering(false)
                }
            }

            window.addEventListener("mousemove", handleMouseMove)
            return () => {
                window.removeEventListener("mousemove", handleMouseMove)
            }
        }, [])

        return (
            <animated.div
                ref={ref}
                style={{
                    position: "absolute",
                    pointerEvents: "none",
                    left: springProps.left,
                    top: springProps.top,
                }}
            >
                <Component {...props} />
            </animated.div>
        )
    }
}
import type { ComponentType } from "react"
import { useRef, useState } from "react"
import { useEffect } from "react"
import { useSpring, animated } from "react-spring"

export function withCursorFollow(Component): ComponentType {
    return (props) => {
        const ref = useRef(null)
        const [isHovering, setIsHovering] = useState(false)
        const [originalPosition, setOriginalPosition] = useState({
            left: 0,
            top: 0,
        })
        const [centerPosition, setCenterPosition] = useState({
            left: 0,
            top: 0,
        })
        const springProps = useSpring({
            left: isHovering ? originalPosition.left : centerPosition.left,
            top: isHovering ? originalPosition.top : centerPosition.top,
            config: { mass: 1, tension: 170, friction: 26 },
        })

        useEffect(() => {
            if (!ref.current) return
            const buttonRect = ref.current.getBoundingClientRect()
            const elementRect = ref.current.getBoundingClientRect()
            setCenterPosition({
                left: buttonRect.width / 2 - elementRect.width / 2,
                top: buttonRect.height / 2 - elementRect.height / 2,
            })

            const handleMouseMove = (e) => {
                if (!ref.current) return
                if (e.target.closest("button")) {
                    setIsHovering(true)
                    const buttonRect = e.target.getBoundingClientRect()
                    const elementRect = ref.current.getBoundingClientRect()
                    setOriginalPosition({
                        left:
                            e.clientX - buttonRect.left - elementRect.width / 2,
                        top:
                            e.clientY - buttonRect.top - elementRect.height / 2,
                    })
                    setCenterPosition({
                        left: buttonRect.width / 2 - elementRect.width / 2,
                        top: buttonRect.height / 2 - elementRect.height / 2,
                    })
                } else {
                    setIsHovering(false)
                }
            }

            window.addEventListener("mousemove", handleMouseMove)
            return () => {
                window.removeEventListener("mousemove", handleMouseMove)
            }
        }, [])

        return (
            <animated.div
                ref={ref}
                style={{
                    position: "absolute",
                    pointerEvents: "none",
                    left: springProps.left,
                    top: springProps.top,
                }}
            >
                <Component {...props} />
            </animated.div>
        )
    }
}
import type { ComponentType } from "react"
import { useRef, useState } from "react"
import { useEffect } from "react"
import { useSpring, animated } from "react-spring"

export function withCursorFollow(Component): ComponentType {
    return (props) => {
        const ref = useRef(null)
        const [isHovering, setIsHovering] = useState(false)
        const [originalPosition, setOriginalPosition] = useState({
            left: 0,
            top: 0,
        })
        const [centerPosition, setCenterPosition] = useState({
            left: 0,
            top: 0,
        })
        const springProps = useSpring({
            left: isHovering ? originalPosition.left : centerPosition.left,
            top: isHovering ? originalPosition.top : centerPosition.top,
            config: { mass: 1, tension: 170, friction: 26 },
        })

        useEffect(() => {
            if (!ref.current) return
            const buttonRect = ref.current.getBoundingClientRect()
            const elementRect = ref.current.getBoundingClientRect()
            setCenterPosition({
                left: buttonRect.width / 2 - elementRect.width / 2,
                top: buttonRect.height / 2 - elementRect.height / 2,
            })

            const handleMouseMove = (e) => {
                if (!ref.current) return
                if (e.target.closest("button")) {
                    setIsHovering(true)
                    const buttonRect = e.target.getBoundingClientRect()
                    const elementRect = ref.current.getBoundingClientRect()
                    setOriginalPosition({
                        left:
                            e.clientX - buttonRect.left - elementRect.width / 2,
                        top:
                            e.clientY - buttonRect.top - elementRect.height / 2,
                    })
                    setCenterPosition({
                        left: buttonRect.width / 2 - elementRect.width / 2,
                        top: buttonRect.height / 2 - elementRect.height / 2,
                    })
                } else {
                    setIsHovering(false)
                }
            }

            window.addEventListener("mousemove", handleMouseMove)
            return () => {
                window.removeEventListener("mousemove", handleMouseMove)
            }
        }, [])

        return (
            <animated.div
                ref={ref}
                style={{
                    position: "absolute",
                    pointerEvents: "none",
                    left: springProps.left,
                    top: springProps.top,
                }}
            >
                <Component {...props} />
            </animated.div>
        )
    }
}

Scale on click source code

Feel free to copy the code and create the code override from scratch in any of your projects.

Scale on click source code

Feel free to copy the code and create the code override from scratch in any of your projects.

Scale on click source code

Feel free to copy the code and create the code override from scratch in any of your projects.

import type { ComponentType } from "react"
import { useState } from "react"

export function onClick(Component): ComponentType {
    return (props) => {
        const [isClicked, setIsClicked] = useState(false)

        return (
            <Component
                {...props}
                onMouseDown={() => setIsClicked(true)}
                onMouseUp={() => setIsClicked(false)}
                animate={
                    isClicked ? { scale: 0.99, y: 1.5 } : { scale: 1, y: 0 }
                }
                transition={{ duration: 0.1 }}
            />
        )
    }
}
import type { ComponentType } from "react"
import { useState } from "react"

export function onClick(Component): ComponentType {
    return (props) => {
        const [isClicked, setIsClicked] = useState(false)

        return (
            <Component
                {...props}
                onMouseDown={() => setIsClicked(true)}
                onMouseUp={() => setIsClicked(false)}
                animate={
                    isClicked ? { scale: 0.99, y: 1.5 } : { scale: 1, y: 0 }
                }
                transition={{ duration: 0.1 }}
            />
        )
    }
}
import type { ComponentType } from "react"
import { useState } from "react"

export function onClick(Component): ComponentType {
    return (props) => {
        const [isClicked, setIsClicked] = useState(false)

        return (
            <Component
                {...props}
                onMouseDown={() => setIsClicked(true)}
                onMouseUp={() => setIsClicked(false)}
                animate={
                    isClicked ? { scale: 0.99, y: 1.5 } : { scale: 1, y: 0 }
                }
                transition={{ duration: 0.1 }}
            />
        )
    }
}

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

Framer Navigator

Learn the fundamentals of Framer for free.

Build your ideas with ease by learning the basics of website building with Framer.

Nandi portrait's background
Nandi's portrait

More resources

More resources

    3D Look Component for Framer

    3D Look Component for Framer

    Component

    3D Look Component for Framer

    3D Look Component for Framer

    Component

    3D Look Component for Framer

    3D Look Component for Framer

    Component

    SVG Component for Framer

    SVG Component for Framer

    Component

    SVG Component for Framer

    SVG Component for Framer

    Component

    SVG Component for Framer

    SVG Component for Framer

    Component