IsoCity
threecn/iso-cityFreeComponent
A procedural isometric skyline rotating under fog, with a few towers pulsing in --primary.
Install it
npx shadcn@latest add https://threecn.dev/r/iso-city.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"1516type Building = { x: number; z: number; h: number; shade: number }1718function seedCity(size: number, density: number) {19 const base: Building[] = []20 const glow: Building[] = []21 const half = (size - 1) / 222 for (let gx = 0; gx < size; gx++) {23 for (let gz = 0; gz < size; gz++) {24 if (Math.random() > density) continue25 const falloff =26 1 - Math.hypot(gx - half, gz - half) / Math.max(half * 1.45, 1)27 const h =28 0.25 + Math.pow(Math.random(), 1.8) * 2.6 * Math.max(0.2, falloff)29 const building: Building = {30 x: (gx - half) * 0.72,31 z: (gz - half) * 0.72,32 h,33 shade: Math.random(),34 }35 // A few towers glow with --primary, like lit offices at night.36 ;(Math.random() < 0.13 ? glow : base).push(building)37 }38 }39 return { base, glow }40}4142function placeInstances(43 mesh: THREE.InstancedMesh | null,44 items: Building[],45 colorFor: (b: Building, target: THREE.Color) => THREE.Color46) {47 if (!mesh) return48 const dummy = new THREE.Object3D()49 const color = new THREE.Color()50 items.forEach((b, i) => {51 dummy.position.set(b.x, b.h / 2, b.z)52 dummy.scale.set(1, b.h, 1)53 dummy.updateMatrix()54 mesh.setMatrixAt(i, dummy.matrix)55 mesh.setColorAt(i, colorFor(b, color))56 })57 mesh.instanceMatrix.needsUpdate = true58 if (mesh.instanceColor) mesh.instanceColor.needsUpdate = true59}6061function City({62 size,63 density,64 speed,65 theme,66}: {67 size: number68 density: number69 speed: number70 theme: ThemeMode71}) {72 const { primaryColor, mutedColor, borderColor } = useShadcnTheme(theme)73 const groupRef = React.useRef<THREE.Group>(null)74 const baseRef = React.useRef<THREE.InstancedMesh>(null)75 const glowRef = React.useRef<THREE.InstancedMesh>(null)76 const glowMatRef = React.useRef<THREE.MeshStandardMaterial>(null)7778 const { base, glow } = React.useMemo(79 () => seedCity(size, density),80 [size, density]81 )8283 React.useLayoutEffect(() => {84 placeInstances(baseRef.current, base, (b, c) =>85 c.copy(borderColor).lerp(mutedColor, 0.25 + b.shade * 0.5)86 )87 placeInstances(glowRef.current, glow, (_, c) => c.copy(primaryColor))88// … 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 |
