Files
Creeer-Web/components/primitives/SimboloTresLineas.tsx
T

62 lines
2.2 KiB
TypeScript

'use client';
import { useRef, useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { usePrefersReducedMotion } from '@/lib/motion';
import { BARRAS_SIMBOLO } from '@/lib/simbolo';
// The manual's own description of the ≡ symbol, made literal: "las líneas van
// de muchas/desordenadas (complejidad) a pocas/alineadas (claridad)". Five
// uneven bars resolve, once in view, into the three clean aligned bars of the
// official icon (see app/icon.svg) — decorative, one-shot, never loops.
const FINAL = BARRAS_SIMBOLO;
const BARS = [
{ from: { x: 6, y: 9, width: 22, height: 6, opacity: 0.9 }, to: FINAL[0] },
{ from: { x: 36, y: 15, width: 16, height: 5, opacity: 0.45 }, to: { x: 44, y: 17, width: 8, height: 5, opacity: 0 } },
{ from: { x: 16, y: 25, width: 30, height: 7, opacity: 0.9 }, to: FINAL[1] },
{ from: { x: 8, y: 37, width: 14, height: 5, opacity: 0.45 }, to: { x: 12, y: 39, width: 8, height: 5, opacity: 0 } },
{ from: { x: 20, y: 45, width: 26, height: 6, opacity: 0.9 }, to: FINAL[2] },
];
export function SimboloTresLineas({ className = '' }: { className?: string }) {
const reduced = usePrefersReducedMotion();
const ref = useRef<SVGSVGElement>(null);
const [inView, setInView] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el || reduced) return;
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
setInView(true);
observer.unobserve(el);
}
},
{ threshold: 0.4 },
);
observer.observe(el);
return () => observer.disconnect();
}, [reduced]);
return (
<svg ref={ref} viewBox="0 0 64 64" className={className} aria-hidden="true" focusable="false">
{BARS.map((bar, i) =>
reduced ? (
<rect key={i} {...bar.to} opacity={i === 1 || i === 3 ? 0 : 1} rx={1.5} fill="currentColor" />
) : (
<motion.rect
key={i}
rx={1.5}
fill="currentColor"
initial={bar.from}
animate={inView ? bar.to : bar.from}
transition={{ duration: 0.7, delay: i * 0.08, ease: [0.22, 1, 0.36, 1] }}
/>
),
)}
</svg>
);
}