- Replaced HomeBlink with HomeAurora component for improved visual experience - Added PodCapabilities horizontal slider with interactive navigation controls - Created PodsFeatures section showcasing use cases with hover animations - Updated PodsHow layout with bullet points and new PodsFlow animation component
193 lines
5.1 KiB
TypeScript
193 lines
5.1 KiB
TypeScript
"use client";
|
|
|
|
import { motion } from "framer-motion";
|
|
import clsx from "clsx";
|
|
|
|
type Props = {
|
|
className?: string;
|
|
accent?: string;
|
|
gridStroke?: string;
|
|
};
|
|
|
|
const W = 760;
|
|
const H = 420;
|
|
|
|
export default function PodsFlow({
|
|
className,
|
|
accent = "#00b8db",
|
|
gridStroke = "#2b2a2a",
|
|
}: Props) {
|
|
const pods = [
|
|
{ x: 100, y: 180, label: "Pod 1" },
|
|
{ x: 260, y: 180, label: "Pod 2" },
|
|
{ x: 420, y: 180, label: "Pod 3" },
|
|
{ x: 580, y: 180, label: "Pod 4" },
|
|
];
|
|
|
|
// Pulse path
|
|
const path = `
|
|
M ${pods[0].x + 80} ${pods[0].y + 40}
|
|
L ${pods[1].x - 10} ${pods[1].y + 40}
|
|
L ${pods[1].x + 80} ${pods[1].y + 40}
|
|
L ${pods[2].x - 10} ${pods[2].y + 40}
|
|
L ${pods[2].x + 80} ${pods[2].y + 40}
|
|
L ${pods[3].x - 10} ${pods[3].y + 40}
|
|
`;
|
|
|
|
// Arrow segments
|
|
const arrows = [
|
|
{
|
|
d: `M ${pods[0].x + 80} ${pods[0].y + 40} L ${pods[1].x - 6} ${pods[1].y + 40}`,
|
|
end: { x: pods[1].x - 6, y: pods[1].y + 40 },
|
|
},
|
|
{
|
|
d: `M ${pods[1].x + 80} ${pods[1].y + 40} L ${pods[2].x - 6} ${pods[2].y + 40}`,
|
|
end: { x: pods[2].x - 6, y: pods[2].y + 40 },
|
|
},
|
|
{
|
|
d: `M ${pods[2].x + 80} ${pods[2].y + 40} L ${pods[3].x - 6} ${pods[3].y + 40}`,
|
|
end: { x: pods[3].x - 6, y: pods[3].y + 40 },
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div
|
|
className={clsx("relative overflow-hidden", className)}
|
|
aria-hidden="true"
|
|
role="img"
|
|
aria-label="Pod-to-Pod signal transfer animation"
|
|
style={{ background: "transparent" }}
|
|
>
|
|
<svg viewBox={`0 0 ${W} ${H}`} className="w-full h-full">
|
|
{/* GRID BG */}
|
|
<defs>
|
|
<pattern id="pods-grid" width="28" height="28" patternUnits="userSpaceOnUse">
|
|
<path d="M 28 0 L 0 0 0 28" fill="none" stroke={gridStroke} strokeWidth="1" opacity="0.6" />
|
|
</pattern>
|
|
|
|
<filter id="pods-glow">
|
|
<feGaussianBlur stdDeviation="4" result="blur" />
|
|
<feMerge>
|
|
<feMergeNode in="blur" />
|
|
<feMergeNode in="SourceGraphic" />
|
|
</feMerge>
|
|
</filter>
|
|
</defs>
|
|
|
|
<rect width={W} height={H} fill="url(#pods-grid)" />
|
|
|
|
{/* POD BOXES */}
|
|
{pods.map((p, i) => (
|
|
<motion.rect
|
|
key={i}
|
|
x={p.x}
|
|
y={p.y}
|
|
width={80}
|
|
height={80}
|
|
rx={14}
|
|
fill="#0d0d0d"
|
|
stroke="#1a1a1a"
|
|
strokeWidth={2}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 0.9 }}
|
|
transition={{ duration: 0.5 + i * 0.15 }}
|
|
/>
|
|
))}
|
|
|
|
{/* POD LABELS */}
|
|
{pods.map((p, i) => (
|
|
<motion.text
|
|
key={i}
|
|
x={p.x + 40}
|
|
y={p.y + 50}
|
|
textAnchor="middle"
|
|
fontSize="14"
|
|
fontFamily="Inter, sans-serif"
|
|
fill="#9ca3af"
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 0.9 }}
|
|
transition={{ delay: 0.1 + i * 0.1, duration: 0.6 }}
|
|
>
|
|
{p.label}
|
|
</motion.text>
|
|
))}
|
|
|
|
{/* GREY LINES */}
|
|
{arrows.map((a, i) => (
|
|
<motion.path
|
|
key={`grey-${i}`}
|
|
d={a.d}
|
|
stroke="#333"
|
|
strokeWidth={4}
|
|
strokeLinecap="round"
|
|
fill="none"
|
|
initial={{ pathLength: 0, opacity: 0 }}
|
|
animate={{ pathLength: 1, opacity: 0.8 }}
|
|
transition={{ delay: 0.2 * i, duration: 0.7 }}
|
|
/>
|
|
))}
|
|
|
|
{/* CYAN LINES */}
|
|
{arrows.map((a, i) => (
|
|
<motion.path
|
|
key={`cyan-${i}`}
|
|
d={a.d}
|
|
stroke={accent}
|
|
strokeWidth={2}
|
|
strokeLinecap="round"
|
|
strokeDasharray="10"
|
|
fill="none"
|
|
initial={{ pathLength: 0, opacity: 0 }}
|
|
animate={{ pathLength: 1, opacity: 1 }}
|
|
transition={{ delay: 0.25 * i, duration: 0.7 }}
|
|
/>
|
|
))}
|
|
|
|
{/* NEW: CYAN ENDPOINT PULSES */}
|
|
{arrows.map((a, i) => (
|
|
<motion.circle
|
|
key={`endpoint-${i}`}
|
|
cx={a.end.x}
|
|
cy={a.end.y}
|
|
r={10}
|
|
fill={accent}
|
|
opacity={0.12}
|
|
filter="url(#pods-glow)"
|
|
initial={{ scale: 0.8, opacity: 0 }}
|
|
animate={{
|
|
scale: [1, 1.2, 1],
|
|
opacity: [0.05, 0.25, 0.05],
|
|
}}
|
|
transition={{
|
|
duration: 1.5,
|
|
delay: i * 0.2,
|
|
repeat: Infinity,
|
|
repeatType: "mirror",
|
|
}}
|
|
/>
|
|
))}
|
|
|
|
{/* MAIN MOVING CYAN PULSE */}
|
|
<motion.circle
|
|
r={8}
|
|
fill={accent}
|
|
filter="url(#pods-glow)"
|
|
style={{
|
|
offsetPath: `path('${path.replace(/\s+/g, " ")}')`,
|
|
}}
|
|
initial={{ offsetDistance: "0%", opacity: 0.4 }}
|
|
animate={{
|
|
offsetDistance: ["0%", "100%"],
|
|
opacity: [0.4, 1, 0.4],
|
|
}}
|
|
transition={{
|
|
duration: 2.6,
|
|
repeat: Infinity,
|
|
ease: "linear",
|
|
}}
|
|
/>
|
|
</svg>
|
|
</div>
|
|
);
|
|
}
|