mirror of
https://github.com/codebox283/everydayserieswebsite.git
synced 2025-06-19 19:50:53 +00:00
75 lines
1.9 KiB
TypeScript
75 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import { cn } from "@/lib/utils";
|
|
import React, { useRef, useState, useEffect } from "react";
|
|
|
|
export const MouseParallaxImage = ({
|
|
image,
|
|
title,
|
|
className,
|
|
}: {
|
|
image: string;
|
|
title: string;
|
|
className?: string;
|
|
}) => {
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
const [isMouseEntered, setIsMouseEntered] = useState(false);
|
|
|
|
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
if (!ref.current) return;
|
|
const { left, top, width, height } = ref.current.getBoundingClientRect();
|
|
const x = (e.clientX - left - width / 2) / 25; // Adjust sensitivity
|
|
const y = (e.clientY - top - height / 2) / 25; // Inverted for natural feel
|
|
ref.current.style.transform = `rotateY(${x}deg) rotateX(${y}deg)`;
|
|
};
|
|
|
|
const handleMouseEnter = () => {
|
|
setIsMouseEntered(true);
|
|
if (ref.current) {
|
|
ref.current.style.transition = 'transform 0.2s ease-out';
|
|
}
|
|
};
|
|
|
|
const handleMouseLeave = () => {
|
|
setIsMouseEntered(false);
|
|
if (ref.current) {
|
|
ref.current.style.transform = `rotateY(0deg) rotateX(0deg)`;
|
|
ref.current.style.transition = 'transform 0.2s ease-out';
|
|
}
|
|
};
|
|
|
|
// Reset transform when mouse leaves
|
|
useEffect(() => {
|
|
if (!ref.current) return;
|
|
if (!isMouseEntered) {
|
|
ref.current.style.transform = `rotateY(0deg) rotateX(0deg)`;
|
|
}
|
|
}, [isMouseEntered]);
|
|
|
|
return (
|
|
<div
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseMove={handleMouseMove}
|
|
onMouseLeave={handleMouseLeave}
|
|
className={cn("h-full w-auto", className)}
|
|
style={{ perspective: '1000px' }}
|
|
>
|
|
<div
|
|
ref={ref}
|
|
className="h-full w-auto transition-transform duration-200 ease-linear"
|
|
style={{
|
|
transformStyle: "preserve-3d",
|
|
}}
|
|
>
|
|
<img
|
|
src={image}
|
|
height={1000}
|
|
width={1000}
|
|
className="h-full w-auto object-contain rounded-2xl"
|
|
alt={title}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|