A rotating dotted globe with a faint wire core, an orbit ring, and orbiting satellites.
three @react-three/fiber @react-three/drei<Globe /> inside your own <Canvas>.import { useMemo, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import type { Group } from 'three';
// Even point distribution on a sphere (Fibonacci lattice).
function fibonacciSphere(n: number, radius: number) {
const arr = new Float32Array(n * 3);
const phi = Math.PI * (3 - Math.sqrt(5));
for (let i = 0; i < n; i++) {
const y = 1 - (i / (n - 1)) * 2;
const r = Math.sqrt(1 - y * y);
const theta = phi * i;
arr[i * 3] = Math.cos(theta) * r * radius;
arr[i * 3 + 1] = y * radius;
arr[i * 3 + 2] = Math.sin(theta) * r * radius;
}
return arr;
}
const SATELLITES = [0, (2 * Math.PI) / 3, (4 * Math.PI) / 3];
export default function Globe({ color = '#22e0ff', scale = 1 }: { color?: string; scale?: number }) {
const core = useRef<Group>(null);
const sats = useRef<Group>(null);
const points = useMemo(() => fibonacciSphere(2800, 1), []);
useFrame((state, dt) => {
if (core.current) core.current.rotation.y += dt * 0.15;
if (sats.current) sats.current.rotation.y = state.clock.elapsedTime * 0.7;
});
return (
<group scale={scale}>
{/* dotted surface + faint wire core rotate together */}
<group ref={core}>
<points>
<bufferGeometry>
<bufferAttribute attach="attributes-position" args={[points, 3]} />
</bufferGeometry>
<pointsMaterial color={color} size={0.022} sizeAttenuation transparent opacity={0.9} toneMapped={false} />
</points>
<mesh>
<sphereGeometry args={[0.97, 28, 28]} />
<meshBasicMaterial color={color} wireframe transparent opacity={0.05} toneMapped={false} />
</mesh>
</group>
{/* static orbit ring */}
<mesh rotation={[Math.PI / 2.3, 0, 0.35]}>
<torusGeometry args={[1.4, 0.006, 16, 140]} />
<meshBasicMaterial color="#ff2fd0" toneMapped={false} />
</mesh>
{/* satellites orbiting along the ring plane */}
<group ref={sats} rotation={[Math.PI / 2.3, 0, 0.35]}>
{SATELLITES.map((a, i) => (
<mesh key={i} position={[Math.cos(a) * 1.4, 0, Math.sin(a) * 1.4]}>
<sphereGeometry args={[0.035, 16, 16]} />
<meshBasicMaterial color="#ffffff" toneMapped={false} />
</mesh>
))}
</group>
</group>
);
}