fix: polish earth legend and info panel interactions

This commit is contained in:
linkong
2026-03-27 16:01:12 +08:00
parent b448a1e560
commit 62f2d9f403
14 changed files with 466 additions and 30 deletions

View File

@@ -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)) {