release: bump version to 0.55.0
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled

This commit is contained in:
linkong
2026-05-13 15:31:29 +08:00
parent 3b4347c87d
commit 39854b9983
23 changed files with 239 additions and 36 deletions

View File

@@ -39,6 +39,15 @@ export const SATELLITE_DISPLAY_STYLES = {
export const DEFAULT_SATELLITE_DISPLAY_STYLE =
SATELLITE_DISPLAY_STYLES.GROUND_FOOTPRINT;
export const SURFACE_HOVER_INFO_MODES = {
COUNTRY: "country",
POSITION: "position",
FULL: "full",
};
export const DEFAULT_SURFACE_HOVER_INFO_MODE =
SURFACE_HOVER_INFO_MODES.FULL;
export const CRUISE_CONFIG = {
dwellMs: 7_000,
focusDurationMs: 1_400,
@@ -331,7 +340,11 @@ export const SATELLITE_CONFIG = {
hydrateFullAfterInitialLoad: false,
trailLength: 10,
trailLineWidth: 3,
displayAltitudeOffset: 8,
fallbackAltitudeOffset: 8,
altitudeCompressionKm: 1200,
maxDisplayAltitudeKm: 40000,
minRealAltitudeOffset: 4,
maxRealAltitudeOffset: 55,
frontFacingDotThreshold: 0.015,
overlayRenderOrder: 12,
dotBaseSize: 2.8,

View File

@@ -4,11 +4,13 @@ import * as THREE from "three";
import {
CONFIG,
CRUISE_MODULES,
DEFAULT_SURFACE_HOVER_INFO_MODE,
DEFAULT_SATELLITE_DISPLAY_STYLE,
DEFAULT_CRUISE_MODULES,
EARTH_CONFIG,
ROTATION_MODE,
SATELLITE_DISPLAY_STYLES,
SURFACE_HOVER_INFO_MODES,
} from "./constants.js";
import {
setEarthStatValue,
@@ -51,7 +53,9 @@ import {
getSatelliteCount,
getSatelliteDisplayStyle,
getSatelliteIdleBreathingEnabled,
getSatelliteRealAltitudeEnabled,
setSatelliteIdleBreathingEnabled as applySatelliteIdleBreathingEnabled,
setSatelliteRealAltitudeEnabled as applySatelliteRealAltitudeEnabled,
setSatelliteDisplayStyle as applySatelliteDisplayStyle,
} from "./satellites.js";
import {
@@ -141,7 +145,7 @@ const SETTINGS_SHEET_MAX_SCALE_X = 0.22;
const SETTINGS_SHEET_MAX_SCALE_Y = 0.18;
const EARTH_SETTINGS_STORAGE_KEY = "planet.earth.settings.v2";
const LEGACY_EARTH_SETTINGS_STORAGE_KEY = "planet.earth.settings.v1";
const EARTH_SETTINGS_VERSION = 10;
const EARTH_SETTINGS_VERSION = 11;
const GRID_LINES_DEFAULT_VERSION = 3;
const SATELLITE_DISPLAY_DEFAULT_VERSION = 4;
const MEDIA_PANEL_DEFAULT_VERSION = 5;
@@ -150,6 +154,7 @@ const MOTION_PROVIDER_DEFAULT_VERSION = 7;
const MOTION_DEBUG_SKELETON_ONLY_DEFAULT_VERSION = 8;
const MEDIA_PANEL_ACTIVE_TAB_DEFAULT_VERSION = 9;
const VISUAL_PREFERENCES_DEFAULT_VERSION = 10;
const SURFACE_HOVER_INFO_DEFAULT_VERSION = 11;
const DEFAULT_EARTH_ZOOM_STEP = 0.01;
const ZOOM_STATUS_UPDATE_INTERVAL_MS = 90;
const TARGET_SWITCH_ZOOM_IN_PHASE = 0.28;
@@ -177,6 +182,9 @@ const ALLOWED_CRUISE_MODULES = new Set(Object.values(CRUISE_MODULES));
const ALLOWED_SATELLITE_DISPLAY_STYLES = new Set(
Object.values(SATELLITE_DISPLAY_STYLES),
);
const ALLOWED_SURFACE_HOVER_INFO_MODES = new Set(
Object.values(SURFACE_HOVER_INFO_MODES),
);
const CRUISE_MODULE_LABELS = {
[CRUISE_MODULES.BGP]: "BGP",
[CRUISE_MODULES.NEWS]: "新闻",
@@ -190,6 +198,12 @@ function normalizeMediaPanelActiveTab(tab) {
return tab === "news" ? "news" : "live";
}
function normalizeSurfaceHoverInfoMode(mode) {
return ALLOWED_SURFACE_HOVER_INFO_MODES.has(mode)
? mode
: DEFAULT_SURFACE_HOVER_INFO_MODE;
}
function detectLayoutMode() {
const width = window.innerWidth;
const height = window.innerHeight;
@@ -794,7 +808,9 @@ function getCurrentSharedSettingsSnapshot() {
motionDebugSkeletonOnly,
mediaPanelActiveTab: normalizeMediaPanelActiveTab(getActiveTVTab()),
satelliteIdleBreathingEnabled: getSatelliteIdleBreathingEnabled(),
satelliteRealAltitudeEnabled: getSatelliteRealAltitudeEnabled(),
interactableCompactDotsEnabled: getInteractableCompactDotsEnabled(),
surfaceHoverInfoMode: getSurfaceHoverInfoMode(),
};
}
@@ -848,8 +864,13 @@ function cloneEarthSettings(settings) {
mediaPanelActiveTab: normalizeMediaPanelActiveTab(settings.shared.mediaPanelActiveTab),
satelliteIdleBreathingEnabled:
settings.shared.satelliteIdleBreathingEnabled !== false,
satelliteRealAltitudeEnabled:
settings.shared.satelliteRealAltitudeEnabled !== false,
interactableCompactDotsEnabled:
settings.shared.interactableCompactDotsEnabled !== false,
surfaceHoverInfoMode: normalizeSurfaceHoverInfoMode(
settings.shared.surfaceHoverInfoMode,
),
layerVisibility: { ...(settings.shared.layerVisibility || {}) },
},
views: {
@@ -975,11 +996,19 @@ function normalizeEarthSettings(rawSettings, defaults) {
typeof sharedSettings?.satelliteIdleBreathingEnabled === "boolean"
? sharedSettings.satelliteIdleBreathingEnabled
: defaults.shared.satelliteIdleBreathingEnabled;
const nextSatelliteRealAltitudeEnabled =
typeof sharedSettings?.satelliteRealAltitudeEnabled === "boolean"
? sharedSettings.satelliteRealAltitudeEnabled
: defaults.shared.satelliteRealAltitudeEnabled;
const nextInteractableCompactDotsEnabled =
(rawSettings?.version || 0) >= VISUAL_PREFERENCES_DEFAULT_VERSION &&
typeof sharedSettings?.interactableCompactDotsEnabled === "boolean"
? sharedSettings.interactableCompactDotsEnabled
: defaults.shared.interactableCompactDotsEnabled;
const nextSurfaceHoverInfoMode =
(rawSettings?.version || 0) >= SURFACE_HOVER_INFO_DEFAULT_VERSION
? normalizeSurfaceHoverInfoMode(sharedSettings?.surfaceHoverInfoMode)
: defaults.shared.surfaceHoverInfoMode;
const nextTrailsEnabled = typeof sharedSettings?.trailsEnabled === "boolean"
? sharedSettings.trailsEnabled
: typeof inputLayerVisibility.trails === "boolean"
@@ -1006,7 +1035,9 @@ function normalizeEarthSettings(rawSettings, defaults) {
motionDebugSkeletonOnly: nextMotionDebugSkeletonOnly,
mediaPanelActiveTab: nextMediaPanelActiveTab,
satelliteIdleBreathingEnabled: nextSatelliteIdleBreathingEnabled,
satelliteRealAltitudeEnabled: nextSatelliteRealAltitudeEnabled,
interactableCompactDotsEnabled: nextInteractableCompactDotsEnabled,
surfaceHoverInfoMode: nextSurfaceHoverInfoMode,
},
views: {
desktop: {
@@ -1195,6 +1226,15 @@ function syncSatelliteIdleBreathingToggle() {
});
}
function syncSatelliteRealAltitudeToggle() {
const enabled = getSatelliteRealAltitudeEnabled();
document.querySelectorAll("[data-satellite-real-altitude-toggle]").forEach((input) => {
if (input instanceof HTMLInputElement) {
input.checked = enabled;
}
});
}
function syncInteractableCompactDotsToggle() {
const enabled = getInteractableCompactDotsEnabled();
document.querySelectorAll("[data-interactable-compact-dots-toggle]").forEach((input) => {
@@ -1294,6 +1334,27 @@ export function setSatelliteIdleBreathingEnabled(
return enabled;
}
export function setSatelliteRealAltitudeEnabled(
nextEnabled,
{ persist = true, suppressStatus = false } = {},
) {
const enabled = applySatelliteRealAltitudeEnabled(nextEnabled);
ensureMutableEarthSettingsState();
earthSettingsState.shared.satelliteRealAltitudeEnabled = enabled;
syncSatelliteRealAltitudeToggle();
if (persist) {
persistEarthSettings();
}
if (!suppressStatus) {
showStatusMessage(
enabled ? "卫星真实高度已开启" : "卫星已切换为旧版同层高度",
"info",
);
}
return enabled;
}
export function setInteractableCompactDotsEnabled(
nextEnabled,
{ persist = true, suppressStatus = false } = {},
@@ -1387,6 +1448,10 @@ async function applyEarthSettings(settings, { applyLayers = true } = {}) {
persist: false,
suppressStatus: true,
});
setSatelliteRealAltitudeEnabled(settings.shared.satelliteRealAltitudeEnabled, {
persist: false,
suppressStatus: true,
});
setInteractableCompactDotsEnabled(settings.shared.interactableCompactDotsEnabled, {
persist: false,
suppressStatus: true,
@@ -2714,6 +2779,13 @@ function setupSettingsControls() {
});
});
document.querySelectorAll("[data-satellite-real-altitude-toggle]").forEach((toggle) => {
if (!(toggle instanceof HTMLInputElement)) return;
bindListener(toggle, "change", () => {
setSatelliteRealAltitudeEnabled(toggle.checked);
});
});
document.querySelectorAll("[data-trails-toggle]").forEach((toggle) => {
if (!(toggle instanceof HTMLInputElement)) return;
bindListener(toggle, "change", () => {
@@ -2767,6 +2839,9 @@ function setupSettingsControls() {
syncRotationModeButtons();
syncCruiseModuleControls();
syncSatelliteDisplayStyleControls();
syncSatelliteIdleBreathingToggle();
syncSatelliteRealAltitudeToggle();
syncInteractableCompactDotsToggle();
syncDayNightToggle(dayNightEnabled);
syncMotionDebugToggle(motionDebugEnabled);
syncMotionProviderControls(motionProvider);

View File

@@ -43,6 +43,7 @@ let satelliteCapacity = 0;
let satelliteSatrecCache = new Map();
let satelliteDisplayStyle = DEFAULT_SATELLITE_DISPLAY_STYLE;
let satelliteIdleBreathingEnabled = true;
let satelliteRealAltitudeEnabled = true;
const GROUND_FOOTPRINT_RENDER_ORDER = 3;
@@ -338,6 +339,28 @@ export function setSatelliteIdleBreathingEnabled(enabled) {
return satelliteIdleBreathingEnabled;
}
export function getSatelliteRealAltitudeEnabled() {
return satelliteRealAltitudeEnabled;
}
export function setSatelliteRealAltitudeEnabled(enabled) {
const nextEnabled = Boolean(enabled);
if (nextEnabled === satelliteRealAltitudeEnabled) {
return satelliteRealAltitudeEnabled;
}
satelliteRealAltitudeEnabled = nextEnabled;
clearSatelliteTrails();
updateSatellitePositions(0, true, { resetTrails: true });
if (
lockedSatelliteIndex !== null &&
satellitePositions?.[lockedSatelliteIndex]?.current
) {
showHoverRing(satellitePositions[lockedSatelliteIndex].current, true);
}
return satelliteRealAltitudeEnabled;
}
export function updateSatelliteIdleBreathingVisual(isIdle = true) {
if (!satellitePoints || !satelliteBackdropPoints) return;
@@ -940,8 +963,13 @@ function computeSatellitePosition(satellite, time) {
}
const r = Math.sqrt(x * x + y * y + z * z);
const displayRadius =
CONFIG.earthRadius + SATELLITE_CONFIG.displayAltitudeOffset;
if (!Number.isFinite(r) || r <= 0) {
return null;
}
const displayRadius = satelliteRealAltitudeEnabled
? CONFIG.earthRadius + getCompressedRealAltitudeOffset(r)
: CONFIG.earthRadius + SATELLITE_CONFIG.fallbackAltitudeOffset;
const scale = displayRadius / r;
return new THREE.Vector3(x * scale, y * scale, z * scale);
@@ -950,6 +978,23 @@ function computeSatellitePosition(satellite, time) {
}
}
function getCompressedRealAltitudeOffset(radiusKm) {
const altitudeKm = Math.max(0, radiusKm - EARTH_RADIUS_KM);
const clampedAltitudeKm = Math.min(
altitudeKm,
SATELLITE_CONFIG.maxDisplayAltitudeKm,
);
const compressionKm = Math.max(1, SATELLITE_CONFIG.altitudeCompressionKm);
const normalizedAltitude = Math.log1p(clampedAltitudeKm / compressionKm) /
Math.log1p(SATELLITE_CONFIG.maxDisplayAltitudeKm / compressionKm);
return THREE.MathUtils.lerp(
SATELLITE_CONFIG.minRealAltitudeOffset,
SATELLITE_CONFIG.maxRealAltitudeOffset,
THREE.MathUtils.clamp(normalizedAltitude, 0, 1),
);
}
function buildSatrecFromProperties(props, fallbackTime) {
if (props.tle_line1 && props.tle_line2) {
// Prefer source-provided TLE lines so the client does not need to rebuild them.
@@ -1088,7 +1133,7 @@ function buildTleLinesFromElements(props, fallbackTime) {
}
function generateFallbackPosition(satellite, index, total, time = new Date()) {
const radius = CONFIG.earthRadius + SATELLITE_CONFIG.displayAltitudeOffset;
const radius = CONFIG.earthRadius + SATELLITE_CONFIG.fallbackAltitudeOffset;
const noradId = satellite.properties?.norad_cat_id || index;
const inclination = satellite.properties?.inclination || 53;
@@ -2557,7 +2602,7 @@ function calculatePredictedOrbit(
if (points.length < samples * 0.5) {
points.length = 0;
const radius =
CONFIG.earthRadius + SATELLITE_CONFIG.displayAltitudeOffset;
CONFIG.earthRadius + SATELLITE_CONFIG.fallbackAltitudeOffset;
const inclination = satellite.properties?.inclination || 53;
const raan = satellite.properties?.raan || 0;