Globe
magicui/globeFreeComponent
An autorotating, interactive, and highly performant globe made using WebGL.
Live preview
live · rendered by the registry
Rendered by magicui on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://magicui.design/r/globe.jsonSource
1"use client"23import { useEffect, useRef } from "react"4import createGlobe, { type COBEOptions } from "cobe"5import { useMotionValue, useSpring } from "motion/react"67import { cn } from "@/lib/utils"89const MOVEMENT_DAMPING = 14001011const GLOBE_CONFIG: COBEOptions = {12 width: 800,13 height: 800,14 onRender: () => {},15 devicePixelRatio: 2,16 phi: 0,17 theta: 0.3,18 dark: 0,19 diffuse: 0.4,20 mapSamples: 16000,21 mapBrightness: 1.2,22 baseColor: [1, 1, 1],23 markerColor: [251 / 255, 100 / 255, 21 / 255],24 glowColor: [1, 1, 1],25 markers: [26 { location: [14.5995, 120.9842], size: 0.03 },27 { location: [19.076, 72.8777], size: 0.1 },28 { location: [23.8103, 90.4125], size: 0.05 },29 { location: [30.0444, 31.2357], size: 0.07 },30 { location: [39.9042, 116.4074], size: 0.08 },31 { location: [-23.5505, -46.6333], size: 0.1 },32 { location: [19.4326, -99.1332], size: 0.1 },33 { location: [40.7128, -74.006], size: 0.1 },34 { location: [34.6937, 135.5022], size: 0.05 },35 { location: [41.0082, 28.9784], size: 0.06 },36 ],37}3839export function Globe({40 className,41 config = GLOBE_CONFIG,42}: {43 className?: string44 config?: COBEOptions45}) {46 const canvasRef = useRef<HTMLCanvasElement>(null)47 const phiRef = useRef(0)48 const widthRef = useRef(0)49 const pointerInteracting = useRef<number | null>(null)50 const pointerInteractionMovement = useRef(0)5152 const r = useMotionValue(0)53 const rs = useSpring(r, {54 mass: 1,55 damping: 30,56 stiffness: 100,57 })5859 const updatePointerInteraction = (value: number | null) => {60 pointerInteracting.current = value61 if (canvasRef.current) {62 canvasRef.current.style.cursor = value !== null ? "grabbing" : "grab"63 }64 }6566 const updateMovement = (clientX: number) => {67 if (pointerInteracting.current !== null) {68 const delta = clientX - pointerInteracting.current69 pointerInteractionMovement.current = delta70 r.set(r.get() + delta / MOVEMENT_DAMPING)71 }72 }7374 useEffect(() => {75 const onResize = () => {76 if (canvasRef.current) {77 widthRef.current = canvasRef.current.offsetWidth78 }79 }8081 window.addEventListener("resize", onResize)82 onResize()8384 const globe = createGlobe(canvasRef.current!, {85 ...config,86 width: widthRef.current * 2,87 height: widthRef.current * 2,88 onRender: (state) => {89 if (!pointerInteracting.current) phiRef.current += 0.00590 state.phi = phiRef.current + rs.get()91// … truncated
What it pulls in
npm packages
Files it writes
More from magicui
All 247 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Androidandroid | magicui | Components | Free | no deps | |
| Animated Beamanimated-beam | magicui | Components | Free | 1 dep | |
| Animated Circular Progress Baranimated-circular-progress-bar | magicui | Components | Free | no deps | |
| Animated Gradient Textanimated-gradient-text | magicui | Components | Free | no deps | |
| Animated Grid Patternanimated-grid-pattern | magicui | Components | Free | 1 dep | |
| Animated Listanimated-list | magicui | Components | Free | 1 dep | |
| Animated Shiny Textanimated-shiny-text | magicui | Components | Free | no deps | |
| Theme Toggleranimated-theme-toggler | magicui | Components | Free | 1 dep |
