2023-10-09 15:49:10 +08:00

156 lines
3.7 KiB
JavaScript

import { Fragment, useState } from "react";
import { Entity, EllipsoidGraphics, useCesium, PolylineGraphics } from "resium";
import { useParams } from "react-router-dom";
import { useInterval, useThrottleFn } from "ahooks";
import { useDispatch } from "react-redux";
const lowCircle = (
<EllipsoidGraphics
radii={new Cesium.Cartesian3(460000.0, 460000.0, 460000.0)}
innerRadii={new Cesium.Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={Cesium.Math.toRadians(89.8)}
maximumCone={Cesium.Math.toRadians(90.2)}
material={new Cesium.Color(0.29, 0.46, 0.77, 1)}
/>
);
const highCircle = (
<EllipsoidGraphics
radii={new Cesium.Cartesian3(460000.0, 460000.0, 460000.0)}
innerRadii={new Cesium.Cartesian3(415000.0, 415000.0, 415000.0)}
minimumCone={Cesium.Math.toRadians(89.8)}
maximumCone={Cesium.Math.toRadians(90.2)}
material={new Cesium.Color(0.99, 0.23, 0.23, 1)}
/>
);
function Circles() {
const { viewer } = useCesium();
const dispatch = useDispatch();
const { run: showInfo } = useThrottleFn(
() => {
dispatch.data.updateImageLayer({ indianOcean: true });
dispatch.data.update({ showSite: true });
},
{
wait: 1000,
}
);
const { run: closeInfo } = useThrottleFn(
() => {
dispatch.data.updateImageLayer({ indianOcean: false });
dispatch.data.update({ showSite: false });
},
{
wait: 1000,
}
);
const Circle = ({ id, lon, lat, isLow, showTime }) => {
const circle = isLow ? lowCircle : highCircle;
const [show, setShow] = useState(false);
useInterval(() => {
const { startTime, currentTime, shouldAnimate } = viewer.clock;
const _time = Math.floor(
currentTime.secondsOfDay - startTime.secondsOfDay
);
if (!shouldAnimate) return;
if (_time === 40) {
showInfo();
} else if (_time === 0) {
closeInfo();
}
if (_time >= showTime) {
setShow(true);
} else {
if (!show) return;
setShow(false);
}
}, 300);
if (!show) return <></>;
return (
<Fragment>
<Entity
id={`${id}-up`}
position={Cesium.Cartesian3.fromDegrees(lon, lat, 1000000)}
>
{circle}
</Entity>
{show && (
<Entity id={`${id}-connection-line`}>
<PolylineGraphics
positions={Cesium.Cartesian3.fromDegreesArrayHeights([
lon,
lat,
1000000,
lon,
lat,
0,
])}
width={2}
material={
new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.WHITE,
dashLength: 4,
})
}
/>
</Entity>
)}
<Entity
id={`${id}-down`}
position={Cesium.Cartesian3.fromDegrees(lon, lat, 0)}
>
{circle}
</Entity>
</Fragment>
);
};
return (
<Fragment>
<Circle
isLow={true}
id={`low-circle-1`}
showTime={10}
lon={-110}
lat={-60}
/>
<Circle
isLow={false}
id={`height-circle-1`}
showTime={20}
lon={-30}
lat={-55}
/>
<Circle
isLow={true}
id={`low-circle-2`}
showTime={30}
lon={30}
lat={-40}
/>
<Circle
isLow={false}
id={`height-circle-2`}
showTime={40}
lon={65}
lat={-35}
/>
<Circle
isLow={true}
id={`low-circle-3`}
showTime={50}
lon={95}
lat={-30}
/>
</Fragment>
);
}
export default Circles;