fix: polish earth legend and info panel interactions
This commit is contained in:
@@ -22,6 +22,7 @@ let lockedSatelliteIndex = null;
|
||||
let hoveredSatelliteIndex = null;
|
||||
let positionUpdateAccumulator = 0;
|
||||
let satelliteCapacity = 0;
|
||||
let selectedSatelliteLegendKey = null;
|
||||
|
||||
const TRAIL_LENGTH = SATELLITE_CONFIG.trailLength;
|
||||
const DOT_TEXTURE_SIZE = 32;
|
||||
@@ -33,10 +34,95 @@ const scratchToSatellite = new THREE.Vector3();
|
||||
|
||||
export let breathingPhase = 0;
|
||||
|
||||
const SATELLITE_LEGEND_RULES = [
|
||||
{
|
||||
key: "starlink",
|
||||
label: "Starlink",
|
||||
color: "#00e6ff",
|
||||
match: (props) => (props?.name || "").includes("STARLINK"),
|
||||
},
|
||||
{
|
||||
key: "geo",
|
||||
label: "GEO / 倾角 20-30",
|
||||
color: "#ffcc00",
|
||||
match: (props) => {
|
||||
const inclination = props?.inclination || 53;
|
||||
return inclination > 20 && inclination < 30;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "iridium",
|
||||
label: "Iridium",
|
||||
color: "#ff8000",
|
||||
match: (props) => (props?.name || "").includes("IRIDIUM"),
|
||||
},
|
||||
{
|
||||
key: "mid-inclination",
|
||||
label: "倾角 50-70",
|
||||
color: "#00ff4d",
|
||||
match: (props) => {
|
||||
const inclination = props?.inclination || 53;
|
||||
return inclination > 50 && inclination < 70;
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "other",
|
||||
label: "其他卫星",
|
||||
color: "#ffffff",
|
||||
match: () => true,
|
||||
},
|
||||
];
|
||||
|
||||
export function updateBreathingPhase(deltaTime = 16) {
|
||||
breathingPhase += SATELLITE_CONFIG.breathingSpeed * (deltaTime / 16);
|
||||
}
|
||||
|
||||
export function getSatelliteLegendItems() {
|
||||
const presentKeys = new Set();
|
||||
|
||||
satelliteData.forEach((satellite) => {
|
||||
const props = satellite?.properties || {};
|
||||
const rule = SATELLITE_LEGEND_RULES.find((item) => item.match(props));
|
||||
if (rule) {
|
||||
presentKeys.add(rule.key);
|
||||
}
|
||||
});
|
||||
|
||||
if (presentKeys.size === 0) {
|
||||
return SATELLITE_LEGEND_RULES.map(({ label, color }) => ({ label, color }));
|
||||
}
|
||||
|
||||
const items = SATELLITE_LEGEND_RULES
|
||||
.filter((item) => presentKeys.has(item.key))
|
||||
.map(({ key, label, color }) => ({ key, label, color }));
|
||||
|
||||
if (!selectedSatelliteLegendKey) {
|
||||
return items.map(({ label, color }) => ({ label, color }));
|
||||
}
|
||||
|
||||
const selectedIndex = items.findIndex(
|
||||
(item) => item.key === selectedSatelliteLegendKey,
|
||||
);
|
||||
|
||||
if (selectedIndex > 0) {
|
||||
const [selectedItem] = items.splice(selectedIndex, 1);
|
||||
items.unshift(selectedItem);
|
||||
}
|
||||
|
||||
return items.map(({ label, color }) => ({ label, color }));
|
||||
}
|
||||
|
||||
export function setSelectedSatelliteLegend(props) {
|
||||
const rule = SATELLITE_LEGEND_RULES.find((item) =>
|
||||
item.match(props || {}),
|
||||
);
|
||||
selectedSatelliteLegendKey = rule?.key || null;
|
||||
}
|
||||
|
||||
export function clearSelectedSatelliteLegend() {
|
||||
selectedSatelliteLegendKey = null;
|
||||
}
|
||||
|
||||
function disposeMaterial(material) {
|
||||
if (!material) return;
|
||||
if (Array.isArray(material)) {
|
||||
|
||||
Reference in New Issue
Block a user