Help Replicating This

As a tool to learn new techniques, I'm recreating things I find on the web. Today I'm trying to do the mouseover image effect seen on this website (while in desktop screen sizes) https://en.bazil.fr/ I managed to get close with this react hook...
import { useEffect, useRef } from "react";

export default function useMouseMove() {
const imageRef = useRef();
const yCap = 1;
const xCap = 3;

useEffect(() => {
const handleMouseMove = (event) => {
const { clientX, clientY } = event;
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;

let posX = ((clientX - centerX) / centerX) * 100; // as a percentage of half the viewport width
let posY = ((clientY - centerY) / centerY) * 100; // as a percentage of half the viewport height

// Calculate the distance of the mouse from the center of the viewport
const distance = Math.sqrt(
Math.pow(clientX - centerX, 2) + Math.pow(clientY - centerY, 2)
);

// Use the distance to calculate the scaling factor
const scaleFactor = Math.pow(distance, 2);

posX *= scaleFactor;
posY *= scaleFactor;

const cappedPosX = Math.min(Math.max(posX, xCap * -1), xCap);
const cappedPosY = Math.min(Math.max(posY, yCap * -1), yCap);

imageRef.current.style.transform = `translate(${cappedPosX}vw, ${cappedPosY}vh)`;
};

window.addEventListener("mousemove", handleMouseMove);

return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);

return imageRef;
}
import { useEffect, useRef } from "react";

export default function useMouseMove() {
const imageRef = useRef();
const yCap = 1;
const xCap = 3;

useEffect(() => {
const handleMouseMove = (event) => {
const { clientX, clientY } = event;
const centerX = window.innerWidth / 2;
const centerY = window.innerHeight / 2;

let posX = ((clientX - centerX) / centerX) * 100; // as a percentage of half the viewport width
let posY = ((clientY - centerY) / centerY) * 100; // as a percentage of half the viewport height

// Calculate the distance of the mouse from the center of the viewport
const distance = Math.sqrt(
Math.pow(clientX - centerX, 2) + Math.pow(clientY - centerY, 2)
);

// Use the distance to calculate the scaling factor
const scaleFactor = Math.pow(distance, 2);

posX *= scaleFactor;
posY *= scaleFactor;

const cappedPosX = Math.min(Math.max(posX, xCap * -1), xCap);
const cappedPosY = Math.min(Math.max(posY, yCap * -1), yCap);

imageRef.current.style.transform = `translate(${cappedPosX}vw, ${cappedPosY}vh)`;
};

window.addEventListener("mousemove", handleMouseMove);

return () => {
window.removeEventListener("mousemove", handleMouseMove);
};
}, []);

return imageRef;
}
... I noticed in dev tools that his image translated up to 3vw and 1vh respectively... but his is buttery smooth, and almost elasticated. The further the mouse moves away from the origin the less the image moves. Mine just stops at the movement cap... I made a sandbox Any advice in getting this to work would be amazing. Thanks!
Bazil Hamard - Freelance webdesigner & photographer - Paris
Webdesigner, Webflow expert & photographer, I help you to create your graphic identity, to perpetuate your brand image and to design a website adapted to your needs.
1 Reply
EIO
EIO5mo ago
What you're looking for is apparently the opposite of the effect Hyperplexed did here: https://codepen.io/Hyperplexed/pen/wvQzbGz You'd just need to fine tune it to your use case. One easy step to begin is to pay attention to the mouse.multiplier object. See where it was defined, play with the values and see how it affects the overall effect.