mirror of
https://github.com/MODSetter/SurfSense.git
synced 2025-09-02 18:49:09 +00:00
89 lines
1.8 KiB
TypeScript
89 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
type MotionStyle,
|
|
motion,
|
|
type SpringOptions,
|
|
useMotionTemplate,
|
|
useMotionValue,
|
|
useSpring,
|
|
useTransform,
|
|
} from "framer-motion";
|
|
import type React from "react";
|
|
import { useRef } from "react";
|
|
|
|
type TiltProps = {
|
|
children: React.ReactNode;
|
|
className?: string;
|
|
style?: MotionStyle;
|
|
rotationFactor?: number;
|
|
isRevese?: boolean;
|
|
springOptions?: SpringOptions;
|
|
};
|
|
|
|
export function Tilt({
|
|
children,
|
|
className,
|
|
style,
|
|
rotationFactor = 15,
|
|
isRevese = false,
|
|
springOptions,
|
|
}: TiltProps) {
|
|
const ref = useRef<HTMLDivElement>(null);
|
|
|
|
const x = useMotionValue(0);
|
|
const y = useMotionValue(0);
|
|
|
|
const xSpring = useSpring(x, springOptions);
|
|
const ySpring = useSpring(y, springOptions);
|
|
|
|
const rotateX = useTransform(
|
|
ySpring,
|
|
[-0.5, 0.5],
|
|
isRevese ? [rotationFactor, -rotationFactor] : [-rotationFactor, rotationFactor]
|
|
);
|
|
const rotateY = useTransform(
|
|
xSpring,
|
|
[-0.5, 0.5],
|
|
isRevese ? [-rotationFactor, rotationFactor] : [rotationFactor, -rotationFactor]
|
|
);
|
|
|
|
const transform = useMotionTemplate`perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
|
|
|
|
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
|
|
if (!ref.current) return;
|
|
|
|
const rect = ref.current.getBoundingClientRect();
|
|
const width = rect.width;
|
|
const height = rect.height;
|
|
const mouseX = e.clientX - rect.left;
|
|
const mouseY = e.clientY - rect.top;
|
|
|
|
const xPos = mouseX / width - 0.5;
|
|
const yPos = mouseY / height - 0.5;
|
|
|
|
x.set(xPos);
|
|
y.set(yPos);
|
|
};
|
|
|
|
const handleMouseLeave = () => {
|
|
x.set(0);
|
|
y.set(0);
|
|
};
|
|
|
|
return (
|
|
<motion.div
|
|
ref={ref}
|
|
className={className}
|
|
style={{
|
|
transformStyle: "preserve-3d",
|
|
...style,
|
|
transform,
|
|
}}
|
|
onMouseMove={handleMouseMove}
|
|
onMouseLeave={handleMouseLeave}
|
|
>
|
|
{children}
|
|
</motion.div>
|
|
);
|
|
}
|