Magnetic Button Override in Framer

Copy component

Magnetic Button Override in Framer

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

Effect

Magnetic Button Override in Framer

This is a code override for Framer that you can slap onto any element to make it magnetic. When you hover over the element, it starts following the cursor, and then snaps back to its original position when the cursor moves further away.

image of Nandi Muzsik
image of Clement Lionne

Created by

Magnetic Button Override in Framer
Magnetic Button Override in Framer
Magnetic Button Override in Framer

About the resource

This code override is a piece of cake to tweak in Framer, you just gotta adjust some of the lines in the code.

You can change the "MAX_DISTANCE" value to control how far the element will follow the cursor. You can also change the "damping" and the "stiffness" of the animation.

About the resource

This code override is a piece of cake to tweak in Framer, you just gotta adjust some of the lines in the code.

You can change the "MAX_DISTANCE" value to control how far the element will follow the cursor. You can also change the "damping" and the "stiffness" of the animation.

About the resource

This code override is a piece of cake to tweak in Framer, you just gotta adjust some of the lines in the code.

You can change the "MAX_DISTANCE" value to control how far the element will follow the cursor. You can also change the "damping" and the "stiffness" of the animation.

magnetic override customization

Magnetic override customization.

magnetic override customization

Magnetic override customization.

magnetic override customization

Magnetic override customization.

Code override

Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, and apply it to any element.

Code override

Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, and apply it to any element.

Code override

Create a code override in your project by going to the assets panel on the left, then scroll down to "code". Click the "+" button to create a new override. Replace the auto-generated code with the code below, and apply it to any element.

import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring } from "framer-motion"

const SPRING_CONFIG = { damping: 100, stiffness: 400 }
const MAX_DISTANCE = 0.5

export const withMagnet = (Component): ComponentType => {
    return (props) => {
        const [isHovered, setIsHovered] = useState(false)
        const x = useMotionValue(0)
        const y = useMotionValue(0)
        const ref = useRef(null)
        const springX = useSpring(x, SPRING_CONFIG)
        const springY = useSpring(y, SPRING_CONFIG)

        useEffect(() => {
            const calculateDistance = (e) => {
                if (ref.current) {
                    const rect = ref.current.getBoundingClientRect()
                    const centerX = rect.left + rect.width / 2
                    const centerY = rect.top + rect.height / 2
                    const distanceX = e.clientX - centerX
                    const distanceY = e.clientY - centerY

                    if (isHovered) {
                        x.set(distanceX * MAX_DISTANCE)
                        y.set(distanceY * MAX_DISTANCE)
                    } else {
                        x.set(0)
                        y.set(0)
                    }
                }
            }

            document.addEventListener("mousemove", calculateDistance)

            return () => {
                document.removeEventListener("mousemove", calculateDistance)
            }
        }, [ref, isHovered])

        return (
            <motion.div
                ref={ref}
                onMouseEnter={() => setIsHovered(true)}
                onMouseLeave={() => setIsHovered(false)}
                style={{
                    x: springX,
                    y: springY,
                    height: props.height || "auto",
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}
import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring } from "framer-motion"

const SPRING_CONFIG = { damping: 100, stiffness: 400 }
const MAX_DISTANCE = 0.5

export const withMagnet = (Component): ComponentType => {
    return (props) => {
        const [isHovered, setIsHovered] = useState(false)
        const x = useMotionValue(0)
        const y = useMotionValue(0)
        const ref = useRef(null)
        const springX = useSpring(x, SPRING_CONFIG)
        const springY = useSpring(y, SPRING_CONFIG)

        useEffect(() => {
            const calculateDistance = (e) => {
                if (ref.current) {
                    const rect = ref.current.getBoundingClientRect()
                    const centerX = rect.left + rect.width / 2
                    const centerY = rect.top + rect.height / 2
                    const distanceX = e.clientX - centerX
                    const distanceY = e.clientY - centerY

                    if (isHovered) {
                        x.set(distanceX * MAX_DISTANCE)
                        y.set(distanceY * MAX_DISTANCE)
                    } else {
                        x.set(0)
                        y.set(0)
                    }
                }
            }

            document.addEventListener("mousemove", calculateDistance)

            return () => {
                document.removeEventListener("mousemove", calculateDistance)
            }
        }, [ref, isHovered])

        return (
            <motion.div
                ref={ref}
                onMouseEnter={() => setIsHovered(true)}
                onMouseLeave={() => setIsHovered(false)}
                style={{
                    x: springX,
                    y: springY,
                    height: props.height || "auto",
                }}
            >
                <Component {...props} />
            </motion.div>
        )
    }
}
import { useState, useEffect, ComponentType, useRef } from "react"
import { motion, useMotionValue, useSpring } from "framer-motion"

const SPRING_CONFIG = { damping: 100, stiffness: 400 }
const MAX_DISTANCE = 0.5

export const withMagnet = (Component): ComponentType => {
    return (props) => {
        const [isHovered, setIsHovered] = useState(false)
        const x = useMotionValue(0)
        const y = useMotionValue(0)
        const ref = useRef(null)
        const springX = useSpring(x, SPRING_CONFIG)
        const springY = useSpring(y, SPRING_CONFIG)

        useEffect(() => {
            const calculateDistance = (e) => {
                if (ref.current) {
                    const rect = ref.current.getBoundingClientRect()
                    const centerX = rect.left + rect.width / 2
                    const centerY = rect.top + rect.height / 2
                    const distanceX = e.clientX - centerX
                    const distanceY = e.clientY - centerY

                    if (isHovered) {
                        x.set(distanceX * MAX_DISTANCE)
                        y.set(distanceY * MAX_DISTANCE)
                    } else {
                        x.set(0)
                        y.set(0)
                    }
                }
            }

            document.addEventListener("mousemove", calculateDistance)

            return () => {
                document.removeEventListener("mousemove", calculateDistance)
            }
        }, [ref, isHovered])

        return (
            <motion.div
                ref={ref}
                onMouseEnter={() => setIsHovered(true)}
                onMouseLeave={() => setIsHovered(false)}
                style={{
                    x: springX,
                    y: springY,
                    height: props.height || "auto",
                }}
            >
                <Component {...props} />
            </motion.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

  • Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

    Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

    Interactive Isometric 3D Hero

    Interactive Isometric 3D Hero

    Effect

  • Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect

    Show Once Code Override for Framer

    Show Once Code Override for Framer

    Effect