问题描述
我正在关注 Globe.gl 中的此 example 以实现以下 output。我想使用 react-three-fiber 旋转这个地球仪,即使用 example 中的方法。
这是我的Globe.js
:
import React from "react";
import * as d3 from "d3-dsv";
import indexBy from "index-array-by";
import Globe from "react-globe.gl";
import earth from "../../public/images/earth-dark.png";
import background from "../../public/images/globeBackground.png";
function GlobeHome() {
const { useState,useEffect,useRef } = React;
const globeEl = useRef();
const [airports,setAirports] = useState([]);
const [routes,setRoutes] = useState([]);
const COUNTRY = "United States";
const OPACITY = 0.125;
const airportParse = ([
airportId,name,city,country,iata,icao,lat,lng,alt,timezone,dst,tz,type,source,]) => ({
airportId,});
const routeParse = ([
airline,airlineId,srcIata,srcAirportId,dstIata,dstAirportId,codeshare,stops,equipment,]) => ({
airline,});
useEffect(() => {
Promise.all([
fetch(
"https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat"
)
.then((res) => res.text())
.then((d) => d3.csvParseRows(d,airportParse)),fetch(
"https://raw.githubusercontent.com/jpatokal/openflights/master/data/routes.dat"
)
.then((res) => res.text())
.then((d) => d3.csvParseRows(d,routeParse)),]).then(([airports,routes]) => {
const byIata = indexBy(airports,"iata",false);
const filteredRoutes = routes
.filter(
(d) =>
byIata.hasOwnProperty(d.srcIata) && byIata.hasOwnProperty(d.dstIata)
)
.filter((d) => d.stops === "0")
.map((d) =>
Object.assign(d,{
srcAirport: byIata[d.srcIata],dstAirport: byIata[d.dstIata],})
)
.filter(
(d) =>
d.srcAirport.country === COUNTRY && d.dstAirport.country !== COUNTRY
);
setAirports(airports);
setRoutes(filteredRoutes);
});
},[]);
useEffect(() => {
globeEl.current.pointOfView({ lat: 42,lng: -71,altitude: 2 });
},[]);
return (
<Globe
ref={globeEl}
width={1000}
height={1000}
showGlobe={true}
globeImageUrl={earth}
backgroundImageUrl={background}
arcsData={routes}
arcStartLat={(d) => +d.srcAirport.lat}
arcStartLng={(d) => +d.srcAirport.lng}
arcEndLat={(d) => +d.dstAirport.lat}
arcEndLng={(d) => +d.dstAirport.lng}
arcDashLength={0.25}
arcDashGap={1}
arcDashInitialGap={() => Math.random()}
arcDashAnimateTime={4000}
arcColor={(d) => [
`rgba(48,64,77,${OPACITY})`,`rgba(191,204,214,]}
arcsTransitionDuration={0}
pointsData={airports}
pointColor={() => "white"}
pointAltitude={0}
poinTradius={0.03}
pointsMerge={true}
/>
);
}
export default GlobeHome;
然后我将其导入到 Boxes.js
中:
import React,{ useRef,useState } from "react";
import { Canvas,useFrame } from "react-three-fiber";
import Globe from './Globe'
function Box(props) {
// This reference will give us direct access to the mesh
const mesh = useRef();
// Set up state for the hovered and active state
const [hovered,setHover] = useState(false);
const [active,setActive] = useState(false);
// Rotate mesh every frame,this is outside of React without overhead
useFrame(() => {
mesh.current.rotation.x = mesh.current.rotation.y += 0.01;
});
return (
<mesh
{...props}
ref={mesh}
>
<Globe />
</mesh>
);
}
export default function App() {
return (
<Canvas>
<ambientLight intensity={0.5} />
<spotLight position={[10,10,10]} angle={0.15} penumbra={1} />
<pointLight position={[-10,-10,-10]} />
<Box />
</Canvas>
);
}
Uncaught "Div" is not part of the THREE namespace! Did you forget to extend it?
关于调试的想法?有没有更好的方法来旋转这个 Globe.gl 地球仪?
解决方法
我也遇到了这个问题。问题是您将 Globe 组件作为 Box 组件的属性传递,该组件是一个网格。然后 Box 组件位于 Canvas 组件中。该库要求您将 Globe 组件作为标准 React 组件放置在 Canvas 组件之外。我能够通过将 App 组件更改为仅返回