Files
portifolio-evandrodevbr/app/components/Logo.tsx
T
Evandro Fonseca Junior 08dd046887 feat: add animated components for enhanced UI/UX
- Introduced DrawLine component for drawing animations.
- Added LazyRevealImage component for lazy loading images with reveal animations.
- Implemented TextDiffuseReveal for animated text reveals with staggered effects.
- Created TopProgressBar for a dynamic loading indicator.
- Added PointCloud mock for testing animations.
- Developed useReducedMotion hook to handle user preferences for reduced motion.
- Centralized animation configurations in config.ts for easier management.
- Defined animation variants in variants.ts for consistent animation effects.
- Established AnimationProvider to supply global animation settings.
- Created tests for AnimationProvider and useReducedMotion hook.
- Added SVG assets for branding and UI elements.
- Documented frontend review plan and hero circuit board animation plan.
2026-03-15 21:06:43 -03:00

185 lines
4.7 KiB
TypeScript

"use client";
import { motion, useReducedMotion } from "framer-motion";
interface LogoProps {
variant?: "mark" | "wordmark" | "icon";
size?: "sm" | "md" | "lg" | "xl";
theme?: "dark" | "light" | "accent";
className?: string;
showTagline?: boolean;
}
const sizeMap = {
sm: { width: 32, height: 32 },
md: { width: 48, height: 48 },
lg: { width: 64, height: 64 },
xl: { width: 120, height: 80 },
};
export function Logo({
variant = "mark",
size = "md",
theme = "dark",
className = "",
showTagline = false,
}: Readonly<LogoProps>) {
const dimensions = sizeMap[size];
const shouldReduceMotion = useReducedMotion();
const colors = {
dark: {
primary: "#FFFFFF",
slash: "#CCFF00",
},
light: {
primary: "#0A0A0A",
slash: "#0A0A0A",
},
accent: {
primary: "#0A0A0A",
slash: "rgba(0,0,0,.3)",
},
};
const c = colors[theme];
const hoverMotion = shouldReduceMotion
? undefined
: {
scale: 1.03,
rotate: -2,
};
const hoverTransition = {
type: "spring" as const,
stiffness: 280,
damping: 18,
};
if (variant === "icon") {
return (
<motion.svg
width={dimensions.width}
height={dimensions.height}
viewBox="0 0 64 64"
fill="none"
className={className}
role="img"
aria-label="Evandro icon logo"
whileHover={hoverMotion}
transition={hoverTransition}
>
<title>Evandro icon logo</title>
<rect width="64" height="64" rx="14" fill={c.primary} />
<rect
x="10"
y="10"
width="7"
height="44"
fill={theme === "dark" ? "#0A0A0A" : c.primary}
/>
<rect
x="17"
y="10"
width="18"
height="7"
fill={theme === "dark" ? "#0A0A0A" : c.primary}
/>
<rect
x="17"
y="28.5"
width="14"
height="7"
fill={theme === "dark" ? "#0A0A0A" : c.primary}
/>
<rect
x="17"
y="47"
width="18"
height="7"
fill={theme === "dark" ? "#0A0A0A" : c.primary}
/>
<polygon points="37,38 41,38 50,26 46,26" fill={c.slash} />
<circle
cx="52"
cy="47"
r="5"
fill={theme === "dark" ? "#0A0A0A" : c.primary}
/>
</motion.svg>
);
}
if (variant === "wordmark") {
return (
<motion.div
className={`flex items-center gap-3 ${className}`}
whileHover={hoverMotion}
transition={hoverTransition}
>
<svg
width={dimensions.width}
height={dimensions.height}
viewBox="0 0 48 32"
fill="none"
role="img"
aria-label="Evandro wordmark logo"
>
<title>Evandro wordmark logo</title>
<rect x="2" y="2" width="7" height="28" fill={c.primary} />
<rect x="9" y="2" width="20" height="7" fill={c.primary} />
<rect x="9" y="12.5" width="16" height="7" fill={c.primary} />
<rect x="9" y="23" width="20" height="7" fill={c.primary} />
<polygon points="30,22 34,22 42,10 38,10" fill={c.slash} />
<circle cx="44" cy="25" r="4" fill={c.primary} />
</svg>
<div>
<div
className="font-display text-lg font-extrabold tracking-tight"
style={{ color: c.primary }}
>
evandro<span style={{ color: c.slash }}>.</span>dev
<span style={{ color: c.slash }}>.</span>br
</div>
{showTagline && (
<div
className="mt-1 text-[9px] tracking-widest"
style={{
color:
theme === "dark"
? "rgba(255,255,255,.25)"
: "rgba(10,10,10,.4)",
}}
>
DESENVOLVIMENTO DE SOFTWARE
</div>
)}
</div>
</motion.div>
);
}
return (
<motion.svg
width={dimensions.width}
height={dimensions.height}
viewBox="0 0 120 80"
fill="none"
className={className}
role="img"
aria-label="Evandro mark logo"
whileHover={hoverMotion}
transition={hoverTransition}
>
<title>Evandro mark logo</title>
<rect x="10" y="8" width="9" height="64" fill={c.primary} />
<rect x="19" y="8" width="28" height="9" fill={c.primary} />
<rect x="19" y="35.5" width="22" height="9" fill={c.primary} />
<rect x="19" y="63" width="28" height="9" fill={c.primary} />
<polygon points="50,55 57,55 74,25 67,25" fill={c.slash} />
<circle cx="80" cy="63" r="7" fill={c.primary} />
</motion.svg>
);
}