feat: Implement initial cinematic portfolio UI with animated components and page structure.
This commit is contained in:
1 parent
9d779390e5
commit
2ede7e98f9
18 files changed
+2107
-147
No files matched your search
@@ -0,0 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import { useRef, useState, type ReactNode } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface MagneticButtonProps {
|
||||
children: ReactNode;
|
||||
className?: string;
|
||||
href?: string;
|
||||
onClick?: () => void;
|
||||
strength?: number;
|
||||
as?: "a" | "button";
|
||||
target?: string;
|
||||
rel?: string;
|
||||
download?: boolean;
|
||||
"data-cursor"?: string;
|
||||
}
|
||||
|
||||
export default function MagneticButton({
|
||||
children,
|
||||
className = "",
|
||||
href,
|
||||
onClick,
|
||||
strength = 0.3,
|
||||
as = "button",
|
||||
target,
|
||||
rel,
|
||||
download,
|
||||
"data-cursor": dataCursor,
|
||||
}: MagneticButtonProps) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
const handleMouse = (e: React.MouseEvent) => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
|
||||
const rect = el.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
|
||||
setPosition({
|
||||
x: (e.clientX - centerX) * strength,
|
||||
y: (e.clientY - centerY) * strength,
|
||||
});
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
setPosition({ x: 0, y: 0 });
|
||||
};
|
||||
|
||||
const Tag = as === "a" ? motion.a : motion.button;
|
||||
const linkProps = as === "a" ? { href, target, rel, download } : {};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
onMouseMove={handleMouse}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
className="inline-block"
|
||||
>
|
||||
<Tag
|
||||
className={className}
|
||||
onClick={onClick}
|
||||
data-cursor={dataCursor}
|
||||
animate={{
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
}}
|
||||
transition={{
|
||||
type: "spring",
|
||||
stiffness: 350,
|
||||
damping: 15,
|
||||
mass: 0.5,
|
||||
}}
|
||||
{...linkProps}
|
||||
>
|
||||
{children}
|
||||
</Tag>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user