84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
"use client";
|
|
|
|
import { motion, useMotionTemplate, useMotionValue, useSpring } from "framer-motion";
|
|
import Image from "next/image";
|
|
|
|
export function AnimatedLogo() {
|
|
const rotateX = useMotionValue(0);
|
|
const rotateY = useMotionValue(0);
|
|
const springX = useSpring(rotateX, { stiffness: 180, damping: 18 });
|
|
const springY = useSpring(rotateY, { stiffness: 180, damping: 18 });
|
|
const glowX = useMotionTemplate`${springY}px`;
|
|
const glowY = useMotionTemplate`${springX}px`;
|
|
|
|
function handlePointerMove(event: React.PointerEvent<HTMLDivElement>) {
|
|
const rect = event.currentTarget.getBoundingClientRect();
|
|
const offsetX = event.clientX - rect.left - rect.width / 2;
|
|
const offsetY = event.clientY - rect.top - rect.height / 2;
|
|
|
|
rotateX.set((-offsetY / rect.height) * 14);
|
|
rotateY.set((offsetX / rect.width) * 14);
|
|
}
|
|
|
|
function handlePointerLeave() {
|
|
rotateX.set(0);
|
|
rotateY.set(0);
|
|
}
|
|
|
|
return (
|
|
<motion.div
|
|
onPointerMove={handlePointerMove}
|
|
onPointerLeave={handlePointerLeave}
|
|
animate={{
|
|
y: [0, -6, 0],
|
|
scale: [1, 1.015, 1],
|
|
}}
|
|
transition={{
|
|
duration: 8,
|
|
repeat: Number.POSITIVE_INFINITY,
|
|
ease: "easeInOut",
|
|
}}
|
|
style={{
|
|
rotateX: springX,
|
|
rotateY: springY,
|
|
transformPerspective: 900,
|
|
}}
|
|
className="relative mx-auto flex w-fit items-center justify-center"
|
|
>
|
|
<motion.div
|
|
animate={{
|
|
opacity: [0.28, 0.42, 0.28],
|
|
scale: [0.96, 1.04, 0.96],
|
|
}}
|
|
transition={{
|
|
duration: 6,
|
|
repeat: Number.POSITIVE_INFINITY,
|
|
ease: "easeInOut",
|
|
}}
|
|
style={{
|
|
x: glowX,
|
|
y: glowY,
|
|
}}
|
|
className="absolute inset-0 -z-10 rounded-full bg-brand-primary/20 blur-3xl"
|
|
/>
|
|
|
|
<Image
|
|
src="/logos/light-primary.svg"
|
|
alt="mohfarawati"
|
|
width={220}
|
|
height={52}
|
|
className="block h-auto w-[140px] dark:hidden sm:w-[180px] lg:w-[220px]"
|
|
priority
|
|
/>
|
|
<Image
|
|
src="/logos/dark-primary.svg"
|
|
alt="mohfarawati"
|
|
width={220}
|
|
height={52}
|
|
className="hidden h-auto w-[140px] dark:block sm:w-[180px] lg:w-[220px]"
|
|
priority
|
|
/>
|
|
</motion.div>
|
|
);
|
|
}
|