|
const btnArr = [ |
|
{id: 1,text: "Hover Me"}, |
|
{id: 2,text: "I am Magnetic"}, |
|
{id: 3,text: "Read More"}, |
|
] |
|
const App = () => { |
|
return ( |
|
<div className="App"> |
|
{btnArr.map((item) => ( |
|
<MagneticButton key={item.id} item={item} /> |
|
))} |
|
</div> |
|
) |
|
} |
|
|
|
//-------------------------------------------------------------------------------------------------------------------- |
|
|
|
import React, { useEffect, useRef } from 'react'; |
|
import './MagneticButton.css'; |
|
|
|
const MagneticButton = ({ item }) => { |
|
const btnRef = useRef(null); |
|
|
|
useEffect(() => { |
|
if (btnRef && btnRef.current) { |
|
const btn = btnRef.current; |
|
btn.addEventListener('mousemove', onMouseMove); |
|
btn.addEventListener('mouseout', onMouseOut); |
|
return () => { |
|
btn.removeEventListener('mousemove', onMouseMove); |
|
btn.removeEventListener('mouseout', onMouseOut); |
|
} |
|
} |
|
}, []) |
|
|
|
const onMouseMove = (e) => { |
|
const btn = btnRef.current; |
|
const bounds = btn.getBoundingClientRect(); |
|
const x = e.pageX - bounds.left - bounds.width / 2; |
|
const y = e.pageY - bounds.top - bounds.height / 2; |
|
btn.children[0].style.transform = "translate(" + x * 0.3 + "px, " + y * 0.5 + "px)" |
|
} |
|
|
|
const onMouseOut = (e) => { |
|
const btn = btnRef.current; |
|
btn.children[0].style.transform = "translate(0px, 0px)" |
|
} |
|
|
|
return ( |
|
<a href="#!" ref={btnRef} className="MagneticButton"> |
|
<span> |
|
{item.text} |
|
</span> |
|
</a> |
|
) |
|
} |
|
|
|
export default MagneticButton; |
|
|
|
//-------------------------------------------------------------------------------------------------------------------- |
|
MagneticButton CSS |
|
.MagneticButton { |
|
|
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
user-select: none; |
|
cursor: pointer; |
|
margin: 4rem; |
|
} |
|
.MagneticButton span { |
|
width: 200px; |
|
height: 200px; |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
border: 1px solid #000; |
|
border-radius: 50%; |
|
transition: transform 0.4s linear; |
|
} |