Velocity UI
Loading…
Menu

Orbital Ray Badge

Circular orbital beams animated via SVG motion paths; minimal label/subtitle.

Installation

Add this component to your project using the CLI:

terminal
npx vui-registry-cli-v1 add orbital-ray-badge

Source Code

orbital-ray-badge.tsx
'use client'

import React from 'react'
import { motion } from 'framer-motion'
import { cn } from '@/lib/utils'
import { Sparkles, Zap, Cpu, Activity, Shield, Terminal, BarChart, Network } from 'lucide-react'

interface OrbitalRayBadgeProps {
  className?: string
  accentColor?: string
}

export default function OrbitalRayBadge({
  className,
  accentColor = '#10b981',
}: OrbitalRayBadgeProps) {
  return (
    <div
      className={cn(
        'relative h-[420px] w-full max-w-[720px] overflow-hidden rounded-3xl p-6 mx-auto bg-background',
        className,
      )}
    >
      {/* Background Grid */}
      <div className="absolute inset-0 opacity-[0.06] bg-[linear-gradient(to_right,currentColor_1px,transparent_1px),linear-gradient(to_bottom,currentColor_1px,transparent_1px)] text-foreground bg-[size:32px_32px] [mask-image:radial-gradient(ellipse_60%_60%_at_50%_50%,#000_30%,transparent_100%)]" />

      {/* SVG Layer */}
      <svg
        className="absolute inset-0 h-full w-full pointer-events-none z-0"
        viewBox="0 0 200 100"
        preserveAspectRatio="none"
      >
        <defs>
          <filter id="orbital-glow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="0.6" result="blur" />
            <feComposite in="SourceGraphic" in2="blur" operator="over" />
          </filter>

          <radialGradient id="beam-grad" cx="100%" cy="50%" r="100%">
            <stop offset="0%" stopColor="#ffffff" />
            <stop offset="28%" stopColor={accentColor} stopOpacity="0.95" />
            <stop offset="100%" stopColor={accentColor} stopOpacity="0" />
          </radialGradient>
          <linearGradient id="beam-stroke" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor={accentColor} stopOpacity="0" />
            <stop offset="25%" stopColor={accentColor} stopOpacity="0.8" />
            <stop offset="100%" stopColor={accentColor} stopOpacity="0.15" />
          </linearGradient>
          <linearGradient id="beam-stroke-tail" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor={accentColor} stopOpacity="0" />
            <stop offset="25%" stopColor={accentColor} stopOpacity="0.5" />
            <stop offset="100%" stopColor={accentColor} stopOpacity="0.08" />
          </linearGradient>

          {/* Converging Paths to 100,50 (Center) */}
          <path id="p1" d="M 31 12 V 30 Q 31 50 100 50" pathLength="200" />
          <path id="p2" d="M 77 12 V 35 Q 77 50 100 50" pathLength="200" />
          <path id="p3" d="M 124 12 V 35 Q 124 50 100 50" pathLength="200" />
          <path id="p4" d="M 170 12 V 30 Q 170 50 100 50" pathLength="200" />

          <path id="p5" d="M 31 88 V 70 Q 31 50 100 50" pathLength="200" />
          <path id="p6" d="M 77 88 V 65 Q 77 50 100 50" pathLength="200" />
          <path id="p7" d="M 124 88 V 65 Q 124 50 100 50" pathLength="200" />
          <path id="p8" d="M 170 88 V 70 Q 170 50 100 50" pathLength="200" />

          {/* Side Beams - Adjusted to start further out */}
          <path id="p9" d="M 10 50 H 100" pathLength="200" />
          <path id="p10" d="M 190 50 H 100" pathLength="200" />

          {[...Array(10)].map((_, i) => (
            <mask key={`m-${i + 1}`} id={`m${i + 1}`}>
              <use href={`#p${i + 1}`} stroke="white" strokeWidth="2" fill="none" />
            </mask>
          ))}
        </defs>

        <g stroke="hsl(var(--foreground) / 0.06)" fill="none" strokeWidth="0.4">
          {[...Array(10)].map((_, i) => (
            <use key={i} href={`#p${i + 1}`} />
          ))}
        </g>

        {[...Array(10)].map((_, i) => (
          <g key={i} mask={`url(#m${i + 1})`}>
            {/* Head */}
            <use
              href={`#p${i + 1}`}
              stroke="url(#beam-stroke)"
              strokeWidth="0.3"
              strokeLinecap="round"
              fill="none"
              style={{ strokeDasharray: '30 170', strokeDashoffset: 0 }}
            >
              <animate
                attributeName="stroke-dashoffset"
                from="0"
                to="-200"
                dur="3.2s"
                begin={`${(i * 0.35).toFixed(2)}s`}
                repeatCount="indefinite"
              />
            </use>
            {/* Tail */}
            <use
              href={`#p${i + 1}`}
              stroke="url(#beam-stroke-tail)"
              strokeWidth="0.1"
              strokeLinecap="round"
              fill="none"
              style={{ strokeDasharray: '22 178', strokeDashoffset: 0 }}
            >
              <animate
                attributeName="stroke-dashoffset"
                from="0"
                to="-200"
                dur="3.2s"
                begin={`${(i * 0.35 + 0.12).toFixed(2)}s`}
                repeatCount="indefinite"
              />
            </use>
            {/* Bend Glow Pause */}
            <use
              href={`#p${i + 1}`}
              stroke="#10b981"
              strokeWidth="0.5"
              strokeLinecap="round"
              fill="none"
              opacity="0.3"
              style={{ strokeDasharray: '8 192', strokeDashoffset: 0 }}
            >
              <animate
                attributeName="stroke-dashoffset"
                from="0"
                to="-200"
                dur="3.2s"
                begin={`${(i * 0.35 + 0.06).toFixed(2)}s`}
                repeatCount="indefinite"
              />
            </use>
          </g>
        ))}
      </svg>

      {/* TOP ROW */}
      <div className="absolute top-6 left-0 right-0 flex justify-around px-6 z-10">
        {[
          { text: 'TOKENS', icon: Sparkles },
          { text: 'COMPONENTS', icon: Activity },
          { text: 'MOTION', icon: Zap },
          { text: 'REGISTRY', icon: Terminal },
        ].map((b, i) => (
          <BadgeItem key={i} {...b} y={5} />
        ))}
      </div>

      {/* BOTTOM ROW */}
      <div className="absolute bottom-6 left-0 right-0 flex justify-around px-6 z-10">
        {[
          { text: 'THEMES', icon: Shield },
          { text: 'PLAYGROUND', icon: Network },
          { text: 'CLI', icon: Terminal },
          { text: 'EXAMPLES', icon: BarChart },
        ].map((b, i) => (
          <BadgeItem key={i} {...b} y={-5} />
        ))}
      </div>

      {/* SIDES */}
      <div className="absolute left-6 top-1/2 -translate-y-1/2 z-10">
        <BadgeItem text="STUDIO" icon={Cpu} x={5} shadow />
      </div>
      <div className="absolute right-6 top-1/2 -translate-y-1/2 z-10">
        <BadgeItem text="SHOWCASE" icon={Network} x={-5} shadow />
      </div>

      {/* CENTER CARD */}
      <div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-20">
        <div className="relative grid place-items-center w-[110px] h-[110px] rounded-xl border border-white/10 bg-black/90 text-white shadow-[0_0_30px_rgba(0,0,0,0.5)]">
          <div className="flex flex-col items-center gap-1">
            <span className="text-[8px] font-bold tracking-[0.25em] text-emerald-400">
              VELOCITY UI
            </span>
            <div className="h-[1px] w-8 bg-white/20" />
            <span className="text-[6px] tracking-[0.1em] text-white/30 uppercase">Active</span>
          </div>
          <div className="absolute inset-1 rounded-xl border border-dashed border-white/5 pointer-events-none" />
        </div>
      </div>

      <style jsx>{``}</style>
    </div>
  )
}

function BadgeItem({ text, icon: Icon, x = 0, y = 0, shadow = false }: any) {
  return (
    <motion.div
      initial={{ opacity: 0, x, y }}
      animate={{ opacity: 1, x: 0, y: 0 }}
      className={cn(
        'relative flex items-center gap-1.5 rounded px-2.5 py-1 border border-white/10 bg-white/[0.02] backdrop-blur-md',
        shadow ? 'shadow-[0_6px_20px_rgba(0,0,0,0.25)]' : '',
      )}
    >
      <Icon className="size-3 text-muted-foreground" />
      <span className="text-[8px] font-bold tracking-[0.1em] text-muted-foreground uppercase">
        {text}
      </span>
    </motion.div>
  )
}

Props

Component property reference.

NameTypeDefaultDescription
labelstringVELOCITYPrimary label
subtitlestringORBITALSmall uppercase tag
Context Worth Keeping In Orbit

Most components here are inspired by outstanding libraries and creators in the ecosystem. I don’t claim to be the original author — this is my space for learning, rebuilding, and understanding great work at a deeper level.

I’m still a student of the craft, constantly studying the best and translating what I learn through my own perspective. Every piece reflects curiosity, respect for the community, and small creative touches that feel true to me.

I’ve done my best to credit inspirations properly. If anything is missing or inaccurate, I truly appreciate a message so it can be corrected with care.