Galaxy Button Component

Copy component

Copy component

Galaxy Button Component

Copy component

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.

image of Nandi Muzsik

Created by

Galaxy Button Component
Galaxy Button Component
Galaxy Button Component
Framer Tutorial: Creating A Galaxy Button Animation

Related Lesson

Framer Tutorial: Creating A Galaxy Button Animation

Framer Tutorial: Creating A Galaxy Button Animation

Related Lesson

Framer Tutorial: Creating A Galaxy Button Animation

Framer Tutorial: Creating A Galaxy Button Animation

Related Lesson

Framer Tutorial: Creating A Galaxy Button Animation

About the resource

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.

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.

About the resource

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.

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.

About the resource

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.

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.

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>
        )
    }
}
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>
        )
    }
}
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 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