Skip to content

Instantly share code, notes, and snippets.

@azaek
Last active August 9, 2022 10:46
Show Gist options
  • Save azaek/9400a2d04abc95c2c10d0911e1624268 to your computer and use it in GitHub Desktop.
Save azaek/9400a2d04abc95c2c10d0911e1624268 to your computer and use it in GitHub Desktop.
Image hover zoom like Chrono24
import { useRef, useState } from "react";
const ProductImage = () => {
const [x, setX] = useState(0);
const [y, setY] = useState(0);
const [l, setL] = useState(0);
const [t, setT] = useState(0);
const ref = useRef<HTMLDivElement>(null);
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
const { left, top, width, height } = e.currentTarget.getBoundingClientRect();
const x = (e.pageX - left) / width * 100;
const y = (e.pageY - top) / height * 100;
setX(x);
setY(y);
if (e.pageX - left < ref.current?.clientWidth!/2 || e.pageX - left > width - (ref.current?.clientWidth!/2)) {
setL(ref.current?.clientWidth!/2);
if (e.pageX - left < ref.current?.clientWidth!/2) {
setL(ref.current?.clientWidth!/2);
}
if (e.pageX - left > width - (ref.current?.clientWidth!/2)) {
setL(width - (ref.current?.clientWidth!/2));
}
} else {
setL(e.pageX - left);
}
if (e.pageY - top < ref.current?.clientHeight!/2 || e.pageY - top > height - (ref.current?.clientHeight!/2)) {
setT(ref.current?.clientHeight!/2);
if (e.pageY - top < ref.current?.clientHeight!/2) {
setT(ref.current?.clientHeight!/2);
}
if (e.pageY - top > height - (ref.current?.clientHeight!/2)) {
setT(height - (ref.current?.clientHeight!/2));
}
} else {
setT(e.pageY - top);
}
}
// console.log(x);
// console.log(y);
return (
<figure onMouseMove={handleMouseMove} className="w-full cursor-zoom-in relative bg-no-repeat group max-w-[500px] aspect-square bg-gradient-to-r from-[#cdcdcd] to-[#f5f5f5] flex items-center justify-center">
<img className="w-full h-full object-contain " src="/product.png" alt="" />
<div ref={ref} style={{ left: `${l}px`, top: `${t}px` }} className="w-[90%] aspect-square hidden group-hover:flex absolute translate-x-[-50%] translate-y-[-50%] m-auto z-20 bg-gradient-to-r from-[#cdcdcd] to-[#f5f5f5] s-border shadow-ds">
<div style={{ backgroundPosition: `${x}% ${y}%`, backgroundImage: `url(${"/product.png"})` }} className="w-full h-full bg-no-repeat ">
</div>
</div>
</figure>
);
}
export default ProductImage;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment