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