WarpTunnel
threecn/warp-tunnelFreeComponent
Hyperspace star streaks racing past the camera, from --foreground heads to --primary tails.
Install it
npx shadcn@latest add https://threecn.dev/r/warp-tunnel.jsonSource
1"use client"23import * as React from "react"4import { useFrame } from "@react-three/fiber"5import * as THREE from "three"67import {8 SceneContainer,9 type SceneContainerProps,10} from "@/components/threecn/scene-container"11import {12 useShadcnTheme,13 type ThemeMode,14} from "@/components/hooks/use-shadcn-theme"1516const NEAR_Z = 517const FAR_Z = -451819function randomStreak(spread: number, out: Float32Array, offset: number, z?: number) {20 // Bias stars away from the exact center so the camera has a clear "eye".21 const r = 0.4 + Math.sqrt(Math.random()) * spread22 const a = Math.random() * Math.PI * 223 const x = Math.cos(a) * r24 const y = Math.sin(a) * r * 0.6525 const zz = z ?? FAR_Z + Math.random() * (NEAR_Z - FAR_Z)26 const len = 1 + Math.random() * 1.627 out[offset] = x28 out[offset + 1] = y29 out[offset + 2] = zz30 out[offset + 3] = x31 out[offset + 4] = y32 out[offset + 5] = zz - len33}3435function seedStreaks(count: number, spread: number) {36 const positions = new Float32Array(count * 6)37 for (let i = 0; i < count; i++) randomStreak(spread, positions, i * 6)38 return positions39}4041function Streaks({42 count,43 speed,44 spread,45 theme,46}: {47 count: number48 speed: number49 spread: number50 theme: ThemeMode51}) {52 const { primaryColor, foregroundColor, isDark } = useShadcnTheme(theme)53 const geoRef = React.useRef<THREE.BufferGeometry>(null)5455 const positions = React.useMemo(56 () => seedStreaks(count, spread),57 [count, spread]58 )59 const colors = React.useMemo(() => new Float32Array(count * 6), [count])6061 // Head = bright (foreground tinted with primary), tail = dim primary so62 // additive blending fades the streak out naturally.63 React.useLayoutEffect(() => {64 const geo = geoRef.current65 if (!geo) return66 const colorAttr = geo.getAttribute("color") as THREE.BufferAttribute67 const arr = colorAttr.array as Float32Array68 const head = new THREE.Color()69 .copy(foregroundColor)70 .lerp(primaryColor, 0.4)71 const tail = new THREE.Color()72 .copy(primaryColor)73 .multiplyScalar(isDark ? 0.12 : 0.55)74 for (let i = 0; i * 6 < arr.length; i++) {75 const o = i * 676 arr[o] = head.r77 arr[o + 1] = head.g78 arr[o + 2] = head.b79 arr[o + 3] = tail.r80 arr[o + 4] = tail.g81 arr[o + 5] = tail.b82 }83 colorAttr.needsUpdate = true84 }, [count, primaryColor, foregroundColor, isDark])8586 useFrame((_, delta) => {87 const geo = geoRef.current88 if (!geo) return89// … truncated
What it pulls in
npm packages
Files it writes
More from threecn
All 28 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AuroraRibbonsaurora-ribbons | threecn | Components | Free | 3 deps · 3 files | |
| Boidsboids | threecn | Components | Free | 3 deps · 3 files | |
| Clothcloth | threecn | Components | Free | 3 deps · 3 files | |
| Crystalcrystal | threecn | Components | Free | 3 deps · 3 files | |
| CubeWavecube-wave | threecn | Components | Free | 3 deps · 3 files | |
| CurlFlowcurl-flow | threecn | Components | Free | 3 deps · 3 files | |
| DnaHelixdna-helix | threecn | Components | Free | 3 deps · 3 files | |
| FloatingCard3Dfloating-card-3d | threecn | Components | Free | 3 deps · 3 files |
