【发布时间】:2021-05-22 18:38:17
【问题描述】:
我正在关注来自 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,
name,
city,
country,
iata,
icao,
lat,
lng,
alt,
timezone,
dst,
tz,
type,
source,
});
const routeParse = ([
airline,
airlineId,
srcIata,
srcAirportId,
dstIata,
dstAirportId,
codeshare,
stops,
equipment,
]) => ({
airline,
airlineId,
srcIata,
srcAirportId,
dstIata,
dstAirportId,
codeshare,
stops,
equipment,
});
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, ${OPACITY})`,
]}
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 地球仪?
【问题讨论】:
-
如果您从未在
Box中使用过GlobeHome,为什么还要创建它? -
我不是吗?
GlobeHome是创建地球的函数。我从Globe.js导出它并将其导入为Globe,然后进入Box函数。然后我尝试在 App 中渲染Box函数。希望这可以澄清 -
我的错,我没看到。你正在使用它。该错误意味着您在代码中的某个位置尝试使用名为
THREE.Div的东西,但这在库中本身并不存在。也许你,或者react-three-fiber在创建它之前尝试使用THREE.Div? -
也许吧。我会检查并跟进
标签: reactjs three.js 3d react-three-fiber webgl-globe