Rocket Launch
nexvyn/rocket-launchFreeComponent
A hand-drawn rocket illustration that ignites its engines and lifts off the pad on demand, with a reset back to rest.
Live preview
live · rendered by the registry
Rendered by nexvyn on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://ui.nexvyn.dev/r/rocket-launch.jsonSource
1'use client'23import {4 forwardRef,5 useEffect,6 useId,7 useImperativeHandle,8 useRef,9 useState,10 type ComponentPropsWithoutRef,11} from 'react'12import { cn } from '@/lib/utils'1314export type RocketLaunchPhase = 'idle' | 'igniting' | 'flying'1516export type RocketLaunchHandle = {17 launch: () => void18 reset: () => void19}2021const IGNITION_DELAY_MS = 14002223export type RocketLaunchIllustrationProps = Readonly<24 Omit<ComponentPropsWithoutRef<'div'>, 'onLaunch' | 'onReset'> & {25 launchLabel?: string26 resetLabel?: string27 onLaunch?: () => void28 onReset?: () => void29 onPhaseChange?: (phase: RocketLaunchPhase) => void30 showControls?: boolean31 }32>3334function EngineFlame({35 path,36 hotPath,37 flameGradId,38 hotGradId,39 turbId,40 speed,41}: Readonly<{42 path: string43 hotPath: string44 flameGradId: string45 hotGradId: string46 turbId: string47 speed: 'a' | 'b' | 'c' | 'd'48}>) {49 return (50 <g filter={`url(#${turbId})`}>51 <path52 className={cn('rocket-flame-body', `rocket-flame-body-${speed}`)}53 fill={`url(#${flameGradId})`}54 d={path}55 />56 <path57 className={cn('rocket-flame-hot', `rocket-flame-hot-${speed}`)}58 fill={`url(#${hotGradId})`}59 d={hotPath}60 />61 </g>62 )63}6465export const RocketLaunchIllustration = forwardRef<66 RocketLaunchHandle,67 RocketLaunchIllustrationProps68>(function RocketLaunchIllustration(69 {70 className,71 launchLabel = 'Launch',72 resetLabel = 'Reset',73 onLaunch,74 onReset,75 onPhaseChange,76 showControls = true,77 ...props78 },79 ref,80) {81 const [phase, setPhaseState] = useState<RocketLaunchPhase>('idle')82 const ignitionTimer = useRef<ReturnType<typeof setTimeout> | null>(null)8384 const uid = useId()85 const flameGradId = `rocket-flame-grad-${uid}`86 const hotGradId = `rocket-hot-grad-${uid}`87 const turbId = `rocket-turb-${uid}`88 const scope = `rocket-launch-${uid}`8990 const setPhase = (next: RocketLaunchPhase) => {91 setPhaseState(next)92 onPhaseChange?.(next)93 }9495 useEffect(() => {96 return () => {97 if (ignitionTimer.current) clearTimeout(ignitionTimer.current)98 }99 }, [])100101 const handleLaunch = () => {102 if (phase !== 'idle') return103 setPhase('igniting')104 ignitionTimer.current = setTimeout(() => {105 setPhase('flying')106 onLaunch?.()107 }, IGNITION_DELAY_MS)108 }109110 const handleReset = () => {111 if (ignitionTimer.current) {112 clearTimeout(ignitionTimer.current)113 ignitionTimer.current = null114// … truncated
Files it writes
More from nexvyn
All 33 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Badgebadge | nexvyn | Components | Free | 2 deps · 2 files | |
| Bars Themebars-theme | nexvyn | Components | Free | 1 dep · 3 files | |
| Bounce Sidebarbounce-sidebar | nexvyn | Components | Free | 1 dep · 2 files | |
| Breadcrumbsbreadcrumbs | nexvyn | Components | Free | 1 dep · 2 files | |
| Checkboxcheckbox | nexvyn | Components | Free | 1 dep · 3 files | |
| Clipboard Fieldclipboard-field | nexvyn | Components | Free | no deps · 2 files | |
| Color Pickercolor-picker | nexvyn | Components | Free | no deps · 16 files | |
| Comboboxcombobox | nexvyn | Components | Free | 1 dep · 2 files |
