Web animations can significantly enhance user experience, making interfaces more interactive and engaging. In this post, we’ll walk through creating a magnetic animation effect using GreenSock Animation Platform (GSAP) in a nextjs component. This animation makes an element follow the user’s cursor with an elastic motion, creating a magnetic effect.
Table of contents
Open Table of contents
Setting Up Your Project
Before we dive into the code, ensure you have a nextjs project set up. You can create a new nextjs project using Create Nextjs:
npx create-next-app@latest magnetic-effect
cd magnetic-effect
Next, install GSAP:
npm install gsap
Creating the Magnetic Effect Component
Now Create a new component file, Magnetic.jsx, and follow Step-by-Step.
Importing Dependencies
First, we import the necessary dependencies from React and GSAP:
import React, { useEffect, useRef } from 'react'
import gsap from 'gsap';
Creating the Magnetic Component
We define the Magnetic component, which takes children as props. This allows us to wrap any element with the magnetic effect.
export default function Magnetic({ children }) {
const magnetic = useRef(null);
We use the useRef hook to create a reference to the DOM element that will have the magnetic effect.
Setting Up GSAP Animations
Inside the useEffect hook, we define the GSAP animations:
useEffect(() => {
const xTo = gsap.quickTo(magnetic.current, "x", { duration: 1, ease: "elastic.out(1, 0.3)" });
const yTo = gsap.quickTo(magnetic.current, "y", { duration: 1, ease: "elastic.out(1, 0.3)" });
The gsap.quickTo function creates quick setters for the x and y properties with a duration of 1 second and an elastic easing effect.
Handling Mouse Events
Next, we add event listeners for mousemove and mouseleave:
magnetic.current.addEventListener("mousemove", (e) => {
const { clientX, clientY } = e;
const { height, width, left, top } = magnetic.current.getBoundingClientRect();
const x = clientX - (left + width / 2);
const y = clientY - (top + height / 2);
xTo(x * 0.35);
yTo(y * 0.35);
});
magnetic.current.addEventListener("mouseleave", () => {
xTo(0);
yTo(0);
});
- mousemove: Calculates the
xandydistances from the element’s center to the cursor and animates the element towards the cursor position with a factor of 0.35. - mouseleave: Resets the element’s position to the center when the cursor leaves the element.
Returning the Element
Finally, we use React.cloneElement to attach the ref to the child element:
return React.cloneElement(children, { ref: magnetic });
}
Using the Magnetic Component
To use the Magnetic component, wrap any element you want to have the magnetic effect:
import React from 'react';
import Magnetic from './Magnetic';
function App() {
return (
<div className="App">
<Magnetic>
<button className="magnetic-button">Hover over me!</button>
</Magnetic>
</div>
);
}
export default App;
Here is final Code:
import React, { useEffect, useRef } from 'react'
import gsap from 'gsap';
export default function Magnetic({ children }) {
const magnetic = useRef(null);
useEffect(() => {
const xTo = gsap.quickTo(magnetic.current, "x", { duration: 1, ease: "elastic.out(1, 0.3)" });
const yTo = gsap.quickTo(magnetic.current, "y", { duration: 1, ease: "elastic.out(1, 0.3)" });
magnetic.current.addEventListener("mousemove", (e) => {
const { clientX, clientY } = e;
const { height, width, left, top } = magnetic.current.getBoundingClientRect();
const x = clientX - (left + width / 2);
const y = clientY - (top + height / 2);
xTo(x * 0.35);
yTo(y * 0.35);
});
magnetic.current.addEventListener("mouseleave", () => {
xTo(0);
yTo(0);
});
}, []);
return React.cloneElement(children, { ref: magnetic });
}
Conclusion
By following this guide, you’ve created a magnetic animation effect using GSAP. This effect adds a layer of interactivity to your elements, making them more engaging for users. Experiment with different easing effects and durations to achieve the desired feel for your animations. Happy coding!