1+ import { Canvas , useFrame , useThree } from "@react-three/fiber" ;
2+ import { useEffect , useMemo , useRef } from "react" ;
3+ import * as THREE from "three" ;
4+ import { LineMaterial } from "three/examples/jsm/Addons.js" ;
5+ import { LineSegments2 } from "three/examples/jsm/lines/LineSegments2.js" ;
6+
7+ export default function Globe ( ) {
8+ return (
9+ < Canvas camera = { { fov : 50 , near : 1 , far : 100 } } >
10+ < Scene />
11+ </ Canvas >
12+ ) ;
13+ }
14+
15+ function Scene ( ) {
16+ const { camera } = useThree ( ) ;
17+ const meshReference = useRef < THREE . Mesh > ( null ) ;
18+ const geometryReference = useRef < THREE . BufferGeometry > ( null ) ;
19+ const wireframeReference = useRef < LineSegments2 > ( null ) ;
20+ const material = new LineMaterial ( { color : 0x88_91_F3 , linewidth : 3 } ) ;
21+ const sphereGeometry = useSphereMesh ( ) ;
22+
23+ useEffect ( ( ) => {
24+ geometryReference . current = new THREE . BufferGeometry ( ) . copy ( new THREE . EdgesGeometry ( ) ) ;
25+
26+ if ( meshReference . current ) {
27+ meshReference . current . geometry = geometryReference . current ;
28+ meshReference . current . material = material ;
29+ }
30+
31+ camera . position . set ( 0 , 13 , 4 ) ;
32+ camera . lookAt ( 0 , 8.5 , 0 ) ;
33+ } , [ ] ) ;
34+
35+ useFrame ( ( ) => {
36+ if ( wireframeReference . current ) {
37+ wireframeReference . current . rotation . y += 0.0025 ;
38+ }
39+ } ) ;
40+
41+ return (
42+ < >
43+ < mesh >
44+ < sphereGeometry args = { [ 9.95 , 32 , 32 ] } />
45+ < meshBasicMaterial color = "black" />
46+ </ mesh >
47+ < lineSegments geometry = { sphereGeometry } ref = { wireframeReference } >
48+ < lineBasicMaterial color = "slateblue" />
49+ </ lineSegments >
50+ </ >
51+ ) ;
52+ }
53+
54+ function useSphereMesh ( ) {
55+ return useMemo ( ( ) => {
56+ const geometry = new THREE . SphereGeometry ( 10 , 32 , 32 ) ;
57+
58+ const p = ( geometry as unknown ) . parameters ;
59+ if ( ! p ) return ;
60+
61+ const segmentsX = p . widthSegments ;
62+ const segmentsY = p . heightSegments - 2 ;
63+ const mainShift = segmentsX + 1 ;
64+ const indices : number [ ] = [ ] ;
65+
66+ for ( let index = 0 ; index < segmentsY + 1 ; index ++ ) {
67+ let index11 = 0 ;
68+ let index12 = 0 ;
69+ for ( let index_ = 0 ; index_ < segmentsX ; index_ ++ ) {
70+ index11 = ( segmentsX + 1 ) * index + index_ ;
71+ index12 = index11 + 1 ;
72+ const index21 = index11 ;
73+ const index22 = index11 + ( segmentsX + 1 ) ;
74+ indices . push ( index11 + mainShift , index12 + mainShift ) ;
75+ if ( index22 < ( segmentsX + 1 ) * ( segmentsY + 1 ) - 1 ) {
76+ indices . push ( index21 + mainShift , index22 + mainShift ) ;
77+ }
78+ }
79+ if ( index12 + segmentsX + 1 <= ( segmentsX + 1 ) * ( segmentsY + 1 ) - 1 ) {
80+ indices . push ( index12 + mainShift , index12 + segmentsX + 1 + mainShift ) ;
81+ }
82+ }
83+
84+ const lastIndex = indices . at ( - 1 ) + 2 ;
85+
86+ for ( let index = 0 ; index < segmentsX ; index ++ ) {
87+ indices . push ( index , index + mainShift , index , index + mainShift + 1 ) ;
88+
89+ const index_ = lastIndex + index ;
90+ const backShift = mainShift + 1 ;
91+ indices . push ( index_ , index_ - backShift , index_ , index_ - backShift + 1 ) ;
92+ }
93+
94+ geometry . setIndex ( indices ) ;
95+
96+ return geometry ;
97+ } , [ ] ) ;
98+ }
0 commit comments