--- template/app/src/landing-page/components/Hero/Orbit.tsx +++ opensaas-sh/app/src/landing-page/components/Hero/Orbit.tsx @@ -0,0 +1,282 @@ +import logo from "../../../client/static/logo.webp"; +import nodeLogoDark from "../../../client/static/logos/nodejs-dark.webp"; +import nodeLogo from "../../../client/static/logos/nodejs-light.webp"; +import stripeLogoDark from "../../../client/static/logos/stripe-dark.webp"; +import stripeLogo from "../../../client/static/logos/stripe-light.webp"; +import tailwindLogoDark from "../../../client/static/logos/tailwind-dark.webp"; +import tailwindLogo from "../../../client/static/logos/tailwind-light.webp"; +import { cn } from "../../../client/utils"; +import { AstroLogo } from "../../logos/AstroLogo"; +import { OpenAILogo } from "../../logos/OpenAILogo"; +import { PrismaLogo } from "../../logos/PrismaLogo"; +import { ReactLogo } from "../../logos/ReactLogo"; +import { ShadCNLogo } from "../../logos/ShadCNLogo"; + +interface LogoConfig { + id: string; + component: React.ComponentType; + circleIndex: number; + position: number; + size?: number; +} + +function ImageLogo({ + src, + alt, + className, + dark, +}: { + src: string; + alt: string; + className?: string; + dark?: boolean; +}) { + return ( + {alt} + ); +} + +const logoConfigs: LogoConfig[] = [ + { + id: "wasp", + component: () => ( + + ), + circleIndex: 1, + position: 0, + }, + { + id: "openai", + component: OpenAILogo, + circleIndex: 1, + position: 120, + size: 24, + }, + { + id: "astro", + component: AstroLogo, + circleIndex: 1, + position: 270, + size: 24, + }, + { + id: "prisma", + component: PrismaLogo, + circleIndex: 2, + position: 90, + size: 24, + }, + { + id: "shadcn", + component: ShadCNLogo, + circleIndex: 2, + position: 210, + size: 24, + }, + { + id: "tailwind-light", + component: () => ( + + ), + circleIndex: 2, + position: 330, + }, + { + id: "tailwind-dark", + component: () => ( + + ), + circleIndex: 2, + position: 330, + }, + { + id: "stripe-light", + component: () => ( + + ), + circleIndex: 3, + position: 180, + }, + { + id: "stripe-dark", + component: () => ( + + ), + circleIndex: 3, + position: 180, + }, + { + id: "react", + component: ReactLogo, + circleIndex: 3, + position: 300, + size: 32, + }, + { + id: "node-light", + component: () => ( + + ), + circleIndex: 3, + position: 50, + }, + { + id: "node-dark", + component: () => ( + + ), + circleIndex: 3, + position: 50, + }, +]; + +const circles = [ + // Innermost to outermost + { radius: 120, orbitPeriod: 72, ringPeriod: 180 }, + { radius: 180, orbitPeriod: 120, ringPeriod: 240 }, + { radius: 240, orbitPeriod: 180, ringPeriod: 360 }, + { radius: 300, orbitPeriod: 360, ringPeriod: 720 }, +]; + +const ringGradients = [ + `conic-gradient(from 0deg, + hsl(var(--primary) / 0.15), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.15), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.05), + hsl(var(--primary) / 0.15) + )`, + `conic-gradient(from 45deg, + hsl(var(--primary) / 0.12), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.08), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.2), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.12) + )`, + `conic-gradient(from 90deg, + hsl(var(--primary) / 0.1), + hsl(var(--primary) / 0.18), + hsl(var(--primary) / 0.1), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.15), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.1) + )`, + `conic-gradient(from 135deg, + hsl(var(--primary) / 0.08), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.16), + hsl(var(--primary) / 0.06), + hsl(var(--primary) / 0), + hsl(var(--primary) / 0.12), + hsl(var(--primary) / 0.08) + )`, +]; + +export function Orbit() { + return ( +
+ + +
+

+ 100% +

+

Open Source

+
+ + {circles.map((circle, circleIndex) => ( +
+ ))} + + {logoConfigs.map((logoConfig) => { + const circle = circles[logoConfig.circleIndex]; + const logoSize = logoConfig.size || 32; + const LogoComponent = logoConfig.component; + + return ( +
+
+
+ +
+
+
+ ); + })} +
+ ); +}