Before You Add AI to Your Product: Ask This First
What is the Magnetic Parallax Effect?
The Magnetic Parallax Effect creates a subtle movement in an element based on the user’s mouse position. The effect gives a sense of depth by shifting both the parent container and its child element slightly as the user moves their cursor over it. This effect is widely used in interactive UI elements like buttons, cards and hero sections to enhance user engagement.
Why GSAP?
When it comes to animations on the web, GSAP stands out for its performance, flexibility, and ease of use. Unlike CSS animations, GSAP provides:
1. Smooth performance – Handles complex animations efficiently without frame drops.
2. Cross-browser compatibility – Works consistently across all modern browsers.
3. Advanced easing & sequencing – Offers fine control over animations with timelines and easing functions.
4. Flexible control – Pause, reverse, or dynamically modify animations in real time.
With GSAP, you can create stunning effects like parallax, scroll-based animations, magnetic interactions, and more with minimal effort.
GSAP concepts pre-requisites.
- Tweens
- Timelines
- Ease functions
Get more info on GSAP here
Overview

The parallaxIt
function pulls both container and child elements at different distances when the pointer moves over them.
The movement distance varies based on the movement
and parallaxMultiplier
values, higher multiplier values create more child movement and vice versa.
When the parallaxMultiplier
values are positive, the child appears to float above the container, creating depth perception. Negative values make the child seem to sit behind the container.
The magnetic pull intensifies near the container’s edges and diminishes toward its center.
https://codepen.io/saurabhsutar192/pen/mydmNyx
Let’s break down the implementation of this effect using GSAP.
Understanding the Code
Function: parallaxMagneticAnimation
This function initializes the parallax effect by adding event listeners to a container.
const parallaxAnimation = ({
child,
movement = 10,
container,
duration = 1,
parallaxMultiplier = 0.5,
scale = 1,
ease = "circ.out",
}: {
child?: HTMLElement | SVGElement;
movement?: number;
container: HTMLElement;
duration?: number;
ease?: string;
parallaxMultiplier?: number;
scale?: number;
}) => {
container.addEventListener("mousemove", (e) => {
e.currentTarget &&
parallaxIt({
e: e,
container: e.currentTarget as HTMLElement,
child,
movement,
parallaxMultiplier,
scale,
duration,
ease,
});
});
container.addEventListener("mouseleave", (e) => {
resetParallax({
container: e.currentTarget as HTMLButtonElement,
child,
duration,
ease,
});
});
};
The default values given to each parameter are my personal preference, feel free to experiment and customize according to your taste.
Explanation:
container.addEventListener("mousemove", …)
→ Triggers theparallaxIt
function whenever the mouse moves over the container.container.addEventListener("mouseleave", …)
→ CallsresetParallax
to return the element to its original position when the mouse leaves.
Function: parallaxIt
This function calculates the movement of the container and its child based on mouse position.
const parallaxIt = ({
e,
child,
movement,
container,
duration,
ease,
parallaxMultiplier,
scale,
}: {
e: MouseEvent;
child?: HTMLElement | SVGElement;
movement: number;
container: HTMLElement;
duration: number;
ease: string;
parallaxMultiplier: number;
scale: number;
}) => {
const { left, top, width, height } = container.getBoundingClientRect();
const movementX = ((e.clientX - left - width / 2) * movement) / 100;
const movementY = ((e.clientY - top - height / 2) * movement) / 100;
const parallaxAnim = gsap.timeline();
parallaxAnim.to(container, {
x: movementX,
y: movementY,
duration,
scale,
ease,
});
child &&
parallaxAnim.to(
child,
{
x: movementX * parallaxMultiplier,
y: movementY * parallaxMultiplier,
duration,
ease,
},
"<"
);
};
child
can be optional resulting only the magnetic effect, omitting the Parallax Effect.
Parameters:
1. e: Mouse event object that contains cursor position data.
2. child: (Optional) An inner element that also moves for a layered effect.
3. movement: (Optional) Controls the distance of movement.
4. container: Container element that will initiate the animation.
5. duration: (Optional) Length of the animation in seconds, increase it for more slower effect.
6. ease: (Optional) Animation easing function.
7. parallaxMultiplier: (Optional) Controls the depth effect between container and child.
8. scale: (Optional) Amount of hover scaling.
Explanation:
1. Calculate the Movement values of each axis:
i. Find the container’s left
, top
, width
, and height
using getBoundingClientRect()
ii. Calculate the movement direction for each axis by subtracting the container’s position and half its dimensions from the cursor’s current page position.
iii. Example :
- If the cursor is at 500px from the top, the container’s top position is 500px (cursor at container’s top), and the container height is 200px, the calculation is :
500-500-200/2= -100
. This means a 100px upward movement.
- If the cursor is at the container’s vertical center, the calculation becomes :
600-500-200/2 = 0
, resulting in no vertical movement.
iv. The same calculation principle applies to the horizontal axis.
v. Apply the movement multiplier by multiplying the direction value by movement / 100
2. Create GSAP Animation using GSAP timeline
:
i. Initiate a timeline.
ii. Move the container slightly in the x
and y
directions based on the movementX
and movementY
values calculated.
iii. Use the rest of the animation parameters like duration, ease,
etc.
iv. Optionally scale the element (scale
parameter) for a more pronounced effect.
v. Move the child element (child
) with a slightly different distance using parallaxMultiplier
.
Function: resetParallax
This function resets the element’s position when the mouse leaves.
const resetParallax = ({
container,
child,
duration,
ease,
}: {
child?: HTMLElement | SVGElement;
container: HTMLElement;
duration: number;
ease: string;
}) => {
const resetAnim = gsap.timeline();
resetAnim.to(container, {
x: 0,
y: 0,
scale: 1,
duration,
ease,
});
child &&
resetAnim.to(
child,
{
x: 0,
y: 0,
scale: 1,
duration,
ease,
},
"<"
);
};
Explanation:
- Smoothly resets the container and child elements back to their original position using GSAP.
Conclusion
This GSAP-powered Magnetic Parallax Effect enhances UI interactions by adding depth and movement. By tweaking parameters like movement
, scale
, and parallaxMultiplier
, you can create various engaging animations.
Stay tuned for more GSAP effect breakdowns!