Shiny Button Component

Copy component

Shiny Button Component

Copy component

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

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 image 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

  • Creative design studio banner featuring staggered typography and motion-inspired visuals

    Staggered Text Cycle Component for Framer

    Component

    Creative design studio banner featuring staggered typography and motion-inspired visuals

    Staggered Text Cycle Component for Framer

    Component

    Creative design studio banner featuring staggered typography and motion-inspired visuals

    Staggered Text Cycle Component for Framer

    Component

  • 3D slideshow showcasing modern cycling and lifestyle themes

    Smooth 3D Slideshow in Framer

    Component

    3D slideshow showcasing modern cycling and lifestyle themes

    Smooth 3D Slideshow in Framer

    Component

    3D slideshow showcasing modern cycling and lifestyle themes

    Smooth 3D Slideshow in Framer

    Component