Galaxy Button Component

Galaxy Button Component

Galaxy Button Component

Galaxy Button Component

Component

Component

Component

Component

Galaxy Button Component

Galaxy Button Component

Galaxy Button Component

Galaxy Button Component

This is a remake of the galaxy button first showcased on the Genius website. It's a truly engaging effect that can certainly elevate your site to new heights.

This is a remake of the galaxy button first showcased on the Genius website. It's a truly engaging effect that can certainly elevate your site to new heights.

This is a remake of the galaxy button first showcased on the Genius website. It's a truly engaging effect that can certainly elevate your site to new heights.

This is a remake of the galaxy button first showcased on the Genius website. It's a truly engaging effect that can certainly elevate your site to new heights.

Galaxy Button Component
Galaxy Button Component
Galaxy Button Component
Galaxy Button Component

Copy component

Copy component

Copy component

Copy component

Features

This button component utilizes two variants: a "default" and a "hover" variant. In the hover state, the background image (the galaxy) becomes visible. This has a code override applied, causing it to move with the cursor.

Step 01 outline

Step / 01

Remix the project.

Step 2 outline

Step / 02

See how it's built.

Step 3 outline

Step / 03

Try recreating it for practice.

Code override

You can also copy this code to create a new code override in your project, which will make the galaxy background move as you hover over the button.

// © Framer University. All rights reserved.

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:
                            buttonRect.left +
                            buttonRect.width / 2 -
                            (e.clientX + elementRect.width / 2),
                        top:
                            buttonRect.top +
                            buttonRect.height / 2 -
                            (e.clientY + 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,
                    transform: "translate3d(0, 0, 0)",
                    transformStyle: "preserve-3d",
                }}
            >
                <Component {...props} />
            </animated.div>
        )
    }
}
// © Framer University. All rights reserved.

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:
                            buttonRect.left +
                            buttonRect.width / 2 -
                            (e.clientX + elementRect.width / 2),
                        top:
                            buttonRect.top +
                            buttonRect.height / 2 -
                            (e.clientY + 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,
                    transform: "translate3d(0, 0, 0)",
                    transformStyle: "preserve-3d",
                }}
            >
                <Component {...props} />
            </animated.div>
        )
    }
}

Free Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.

Free
Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.

Free Framer Course

Learn how to create stunning websites with ease by learning the fundamentals of Framer.