release: bump version to 0.40.1
This commit is contained in:
@@ -10,6 +10,16 @@ This project follows the repository versioning rule:
|
|||||||
|
|
||||||
## [0.39.0] — 2026-04-24
|
## [0.39.0] — 2026-04-24
|
||||||
|
|
||||||
|
## [0.40.1] — 2026-04-24
|
||||||
|
|
||||||
|
### 🔧 Improvements
|
||||||
|
- 卫星选中标记(lockedring / lockeddot / 光晕)颜色统一跟随图例轨道倾角分类配色
|
||||||
|
- 修复 Starlink footprint 在特定视角下遮蔽卫星点的渲染顺序问题(Group renderOrder 影响子 Mesh 排序)
|
||||||
|
- footprint 材质改为 `depthTest: false` + 相机朝向 limbFade,替代 polygonOffset 深度竞争方案
|
||||||
|
- 修复选中海缆时误触发附近卫星高亮(该行为属于 BGP 事件点逻辑,不应用于海缆)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## [0.40.0] — 2026-04-24
|
## [0.40.0] — 2026-04-24
|
||||||
|
|
||||||
### ✨ Highlights
|
### ✨ Highlights
|
||||||
|
|||||||
@@ -16,12 +16,13 @@
|
|||||||
## Current Version
|
## Current Version
|
||||||
|
|
||||||
- `main` 当前主线历史推导到:`0.16.5`
|
- `main` 当前主线历史推导到:`0.16.5`
|
||||||
- `dev` 当前开发分支历史推导到:`0.40.0`
|
- `dev` 当前开发分支历史推导到:`0.40.1`
|
||||||
|
|
||||||
## Timeline
|
## Timeline
|
||||||
|
|
||||||
| Version | Type | Branch | Commit | Summary |
|
| Version | Type | Branch | Commit | Summary |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `0.40.1` | improvement | `dev` | `pending` | 卫星选中标记配色跟随图例,修复 footprint 遮蔽卫星渲染问题,修复选中海缆误触发卫星高亮 |
|
||||||
| `0.40.0` | feature | `dev` | `pending` | Earth 卫星 footprint 按星座能力分层,Iridium 独立 coverage ring 落地,卫星详情卡补齐覆盖能力与当前显示说明 |
|
| `0.40.0` | feature | `dev` | `pending` | Earth 卫星 footprint 按星座能力分层,Iridium 独立 coverage ring 落地,卫星详情卡补齐覆盖能力与当前显示说明 |
|
||||||
| `0.39.0` | feature | `dev` | `pending` | 后端统一结构化日志地基落地,系统日志页重构为紧凑日志工作台,并修复 Earth 移动端态势抽屉与新闻详情同步问题 |
|
| `0.39.0` | feature | `dev` | `pending` | 后端统一结构化日志地基落地,系统日志页重构为紧凑日志工作台,并修复 Earth 移动端态势抽屉与新闻详情同步问题 |
|
||||||
| `0.38.0` | feature | `dev` | `pending` | Earth 新闻接入通用巡航与专用卡片链路,系统日志页升级为结构化时间/级别过滤与真正字符串检索 |
|
| `0.38.0` | feature | `dev` | `pending` | Earth 新闻接入通用巡航与专用卡片链路,系统日志页升级为结构化时间/级别过滤与真正字符串检索 |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "planet-frontend",
|
"name": "planet-frontend",
|
||||||
"version": "0.40.0",
|
"version": "0.40.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"packageManager": "bun@1",
|
"packageManager": "bun@1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ import {
|
|||||||
setSatelliteCamera,
|
setSatelliteCamera,
|
||||||
setSatelliteSunDirection,
|
setSatelliteSunDirection,
|
||||||
setLockedSatelliteIndex,
|
setLockedSatelliteIndex,
|
||||||
|
setHoveredSatelliteIndex,
|
||||||
resetSatelliteState,
|
resetSatelliteState,
|
||||||
clearSatelliteData,
|
clearSatelliteData,
|
||||||
} from "./satellites.js";
|
} from "./satellites.js";
|
||||||
@@ -482,6 +483,7 @@ function clearTransientHoverState() {
|
|||||||
}
|
}
|
||||||
hoveredSatellite = null;
|
hoveredSatellite = null;
|
||||||
hoveredSatelliteIndex = null;
|
hoveredSatelliteIndex = null;
|
||||||
|
setHoveredSatelliteIndex(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyBGPHoverState(marker) {
|
function applyBGPHoverState(marker) {
|
||||||
@@ -933,6 +935,9 @@ async function focusSearchSatellite(index) {
|
|||||||
const satPositions = getSatellitePositions();
|
const satPositions = getSatellitePositions();
|
||||||
if (satPositions?.[index]) {
|
if (satPositions?.[index]) {
|
||||||
setSatelliteRingState(index, "locked", satPositions[index].current);
|
setSatelliteRingState(index, "locked", satPositions[index].current);
|
||||||
|
if (hoveredSatelliteIndex === index) {
|
||||||
|
setHoveredSatelliteIndex(index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showSatelliteInfo(sat.properties, getSearchCardCoords());
|
showSatelliteInfo(sat.properties, getSearchCardCoords());
|
||||||
showStatusMessage(`已定位卫星:${sat.properties.name || sat.properties.norad_cat_id || "未知卫星"}`, "info");
|
showStatusMessage(`已定位卫星:${sat.properties.name || sat.properties.norad_cat_id || "未知卫星"}`, "info");
|
||||||
@@ -2663,6 +2668,7 @@ function onMouseMove(event) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
setHoveredSatelliteIndex(hoveredSatelliteIndex);
|
||||||
showTooltip(event.clientX + TOOLTIP_CURSOR_OFFSET, event.clientY + TOOLTIP_CURSOR_OFFSET, getSatelliteBriefHtml(hoveredSat.properties));
|
showTooltip(event.clientX + TOOLTIP_CURSOR_OFFSET, event.clientY + TOOLTIP_CURSOR_OFFSET, getSatelliteBriefHtml(hoveredSat.properties));
|
||||||
objectTooltipShown = true;
|
objectTooltipShown = true;
|
||||||
} else if (lockedObjectType === "bgp" && lockedObject) {
|
} else if (lockedObjectType === "bgp" && lockedObject) {
|
||||||
@@ -2962,19 +2968,6 @@ function onClick(event) {
|
|||||||
lockedObject = clickedCable;
|
lockedObject = clickedCable;
|
||||||
lockedObjectType = "cable";
|
lockedObjectType = "cable";
|
||||||
setAutoRotate(false);
|
setAutoRotate(false);
|
||||||
{
|
|
||||||
const cableLandingRegions = getLandingPoints()
|
|
||||||
.filter((lp) => lp.userData.cableNames?.includes(clickedCable.userData.name))
|
|
||||||
.map((lp) => {
|
|
||||||
const { lat, lon } = vector3ToLatLon(lp.position);
|
|
||||||
return { latitude: lat, longitude: lon };
|
|
||||||
});
|
|
||||||
const relatedSatelliteIndices = getRelatedSatelliteIndicesForRegions(
|
|
||||||
cableLandingRegions,
|
|
||||||
{ limit: 6, maxAngleDeg: 20 },
|
|
||||||
);
|
|
||||||
highlightRelatedSatellites(relatedSatelliteIndices, RELATED_SATELLITE_HIGHLIGHT_COLOR);
|
|
||||||
}
|
|
||||||
handleCableClick(clickedCable);
|
handleCableClick(clickedCable);
|
||||||
showCableInfo(clickedCable, { x: event.clientX, y: event.clientY });
|
showCableInfo(clickedCable, { x: event.clientX, y: event.clientY });
|
||||||
return;
|
return;
|
||||||
@@ -3029,6 +3022,9 @@ function onClick(event) {
|
|||||||
"locked",
|
"locked",
|
||||||
satPositions[selectedIndex].current,
|
satPositions[selectedIndex].current,
|
||||||
);
|
);
|
||||||
|
if (hoveredSatelliteIndex === selectedIndex) {
|
||||||
|
setHoveredSatelliteIndex(selectedIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showSatelliteInfo(sat.properties, { x: event.clientX, y: event.clientY });
|
showSatelliteInfo(sat.properties, { x: event.clientX, y: event.clientY });
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ const LOCKED_HALO_BASE_OPACITY = 0.54;
|
|||||||
const LOCKED_HALO_OFFSET = 0.0014;
|
const LOCKED_HALO_OFFSET = 0.0014;
|
||||||
const LOCKED_HALO_CORE_PIXEL_RADIUS = 8;
|
const LOCKED_HALO_CORE_PIXEL_RADIUS = 8;
|
||||||
const LOCKED_HALO_PIXEL_RADIUS = 24;
|
const LOCKED_HALO_PIXEL_RADIUS = 24;
|
||||||
|
const FILLED_TEXTURE_RADIUS_RATIO = 0.28;
|
||||||
|
const LOCKED_RING_IDLE_SCALE = 0.68;
|
||||||
|
const LOCKED_RING_IDLE_OPACITY = 0.92;
|
||||||
const EARTH_RADIUS_KM = 6378.137;
|
const EARTH_RADIUS_KM = 6378.137;
|
||||||
const GROUND_FOOTPRINT_MIN_ELEVATION_DEG = 25;
|
const GROUND_FOOTPRINT_MIN_ELEVATION_DEG = 25;
|
||||||
const GROUND_FOOTPRINT_RADIUS_OFFSET = 0.72;
|
const GROUND_FOOTPRINT_RADIUS_OFFSET = 0.72;
|
||||||
@@ -345,6 +348,25 @@ function createRingTexture(innerRadius, outerRadius, color = "#ffffff") {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createFilledCircleTexture(color = "#ffcc00") {
|
||||||
|
const size = DOT_TEXTURE_SIZE * 2;
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
canvas.width = size;
|
||||||
|
canvas.height = size;
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
const center = size / 2;
|
||||||
|
const radius = size * FILLED_TEXTURE_RADIUS_RATIO;
|
||||||
|
|
||||||
|
ctx.fillStyle = color;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(center, center, radius, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
const texture = new THREE.CanvasTexture(canvas);
|
||||||
|
texture.needsUpdate = true;
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
export function createSatellites(scene, earthObj) {
|
export function createSatellites(scene, earthObj) {
|
||||||
initSatelliteScene(scene, earthObj);
|
initSatelliteScene(scene, earthObj);
|
||||||
const dotTexture = createDotTexture();
|
const dotTexture = createDotTexture();
|
||||||
@@ -1156,14 +1178,14 @@ export function isSatelliteFrontFacing(index, camera = cameraRef) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createLockedHaloMaterial() {
|
function createLockedHaloMaterial(color = "#ffbf47") {
|
||||||
return new THREE.ShaderMaterial({
|
return new THREE.ShaderMaterial({
|
||||||
transparent: true,
|
transparent: true,
|
||||||
depthTest: false,
|
depthTest: false,
|
||||||
depthWrite: false,
|
depthWrite: false,
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uColor: { value: new THREE.Color(0xffbf47) },
|
uColor: { value: new THREE.Color(color) },
|
||||||
uOpacity: { value: LOCKED_HALO_BASE_OPACITY },
|
uOpacity: { value: LOCKED_HALO_BASE_OPACITY },
|
||||||
},
|
},
|
||||||
vertexShader: `
|
vertexShader: `
|
||||||
@@ -1196,10 +1218,8 @@ function createGroundFootprintMaterial() {
|
|||||||
return new THREE.ShaderMaterial({
|
return new THREE.ShaderMaterial({
|
||||||
transparent: true,
|
transparent: true,
|
||||||
side: THREE.DoubleSide,
|
side: THREE.DoubleSide,
|
||||||
|
depthTest: false,
|
||||||
depthWrite: false,
|
depthWrite: false,
|
||||||
polygonOffset: true,
|
|
||||||
polygonOffsetFactor: -2,
|
|
||||||
polygonOffsetUnits: -2,
|
|
||||||
uniforms: {
|
uniforms: {
|
||||||
uColor: { value: new THREE.Color(0xffffff) },
|
uColor: { value: new THREE.Color(0xffffff) },
|
||||||
uOpacity: { value: 0.46 },
|
uOpacity: { value: 0.46 },
|
||||||
@@ -1288,6 +1308,12 @@ function createGroundFootprintMaterial() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3 worldNormal = normalize(vWorldPosition);
|
vec3 worldNormal = normalize(vWorldPosition);
|
||||||
|
vec3 toCam = normalize(cameraPosition - vWorldPosition);
|
||||||
|
float facing = dot(worldNormal, toCam);
|
||||||
|
float limbFade = smoothstep(-0.08, 0.12, facing);
|
||||||
|
if (limbFade <= 0.0) discard;
|
||||||
|
alpha *= limbFade;
|
||||||
|
|
||||||
vec3 sunDir = normalize(uSunDirectionWorld);
|
vec3 sunDir = normalize(uSunDirectionWorld);
|
||||||
float sunFacing = dot(worldNormal, sunDir);
|
float sunFacing = dot(worldNormal, sunDir);
|
||||||
float daylight = clamp(sunFacing * 0.5 + 0.5, 0.0, 1.0);
|
float daylight = clamp(sunFacing * 0.5 + 0.5, 0.0, 1.0);
|
||||||
@@ -1720,13 +1746,13 @@ function updateGroundFootprintTransform(position) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSelfGlowStyle(position) {
|
function showSelfGlowStyle(position, color = "#ffd25a") {
|
||||||
const dotGeometry = new THREE.CircleGeometry(
|
const dotGeometry = new THREE.CircleGeometry(
|
||||||
LOCKED_HALO_CORE_RADIUS,
|
LOCKED_HALO_CORE_RADIUS,
|
||||||
LOCKED_HALO_CORE_SEGMENTS,
|
LOCKED_HALO_CORE_SEGMENTS,
|
||||||
);
|
);
|
||||||
const dotMaterial = new THREE.MeshBasicMaterial({
|
const dotMaterial = new THREE.MeshBasicMaterial({
|
||||||
color: 0xffd25a,
|
color: new THREE.Color(color),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
opacity: 0.96,
|
opacity: 0.96,
|
||||||
depthTest: false,
|
depthTest: false,
|
||||||
@@ -1740,7 +1766,7 @@ function showSelfGlowStyle(position) {
|
|||||||
|
|
||||||
lockedHaloMesh = new THREE.Mesh(
|
lockedHaloMesh = new THREE.Mesh(
|
||||||
new THREE.CircleGeometry(LOCKED_HALO_RADIUS, 64),
|
new THREE.CircleGeometry(LOCKED_HALO_RADIUS, 64),
|
||||||
createLockedHaloMaterial(),
|
createLockedHaloMaterial(color),
|
||||||
);
|
);
|
||||||
lockedHaloMesh.renderOrder = SATELLITE_CONFIG.overlayRenderOrder + 1;
|
lockedHaloMesh.renderOrder = SATELLITE_CONFIG.overlayRenderOrder + 1;
|
||||||
sceneRef?.add(lockedHaloMesh);
|
sceneRef?.add(lockedHaloMesh);
|
||||||
@@ -1750,7 +1776,7 @@ function showSelfGlowStyle(position) {
|
|||||||
function showGroundFootprintStyle(position) {
|
function showGroundFootprintStyle(position) {
|
||||||
if (!earthObjRef) return;
|
if (!earthObjRef) return;
|
||||||
lockedGroundFootprintMesh = new THREE.Group();
|
lockedGroundFootprintMesh = new THREE.Group();
|
||||||
lockedGroundFootprintMesh.renderOrder = SATELLITE_CONFIG.overlayRenderOrder - 1;
|
lockedGroundFootprintMesh.renderOrder = 0;
|
||||||
const fill = new THREE.Mesh(
|
const fill = new THREE.Mesh(
|
||||||
new THREE.BufferGeometry(),
|
new THREE.BufferGeometry(),
|
||||||
createGroundFootprintMaterial(),
|
createGroundFootprintMaterial(),
|
||||||
@@ -1766,7 +1792,7 @@ function showIridiumReservedStyle(position) {
|
|||||||
lockedIridiumFootprintMesh = createIridiumFootprintAdapter({
|
lockedIridiumFootprintMesh = createIridiumFootprintAdapter({
|
||||||
earthObj: earthObjRef,
|
earthObj: earthObjRef,
|
||||||
earthRadiusWorld: CONFIG.earthRadius,
|
earthRadiusWorld: CONFIG.earthRadius,
|
||||||
renderOrder: SATELLITE_CONFIG.overlayRenderOrder - 1,
|
renderOrder: 0,
|
||||||
});
|
});
|
||||||
updateIridiumReservedStyle(position);
|
updateIridiumReservedStyle(position);
|
||||||
}
|
}
|
||||||
@@ -1782,14 +1808,17 @@ function updateIridiumReservedStyle(position) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function createRingSprite(position, isLocked = false) {
|
function createRingSprite(position, isLocked = false, color = "#ffcc00") {
|
||||||
if (!earthObjRef) return null;
|
if (!earthObjRef) return null;
|
||||||
|
|
||||||
const ringTexture = createRingTexture(
|
const ringTexture = createRingTexture(
|
||||||
8,
|
8,
|
||||||
12,
|
12,
|
||||||
isLocked ? "#ffcc00" : "#ffffff",
|
isLocked ? color : "#ffffff",
|
||||||
);
|
);
|
||||||
|
const filledTexture = isLocked
|
||||||
|
? createFilledCircleTexture(color)
|
||||||
|
: null;
|
||||||
const spriteMaterial = new THREE.SpriteMaterial({
|
const spriteMaterial = new THREE.SpriteMaterial({
|
||||||
map: ringTexture,
|
map: ringTexture,
|
||||||
transparent: true,
|
transparent: true,
|
||||||
@@ -1799,6 +1828,8 @@ function createRingSprite(position, isLocked = false) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const sprite = new THREE.Sprite(spriteMaterial);
|
const sprite = new THREE.Sprite(spriteMaterial);
|
||||||
|
sprite.userData.ringTexture = ringTexture;
|
||||||
|
sprite.userData.filledTexture = filledTexture;
|
||||||
sprite.position.copy(position);
|
sprite.position.copy(position);
|
||||||
sprite.scale.set(SATELLITE_CONFIG.ringSize, SATELLITE_CONFIG.ringSize, 1);
|
sprite.scale.set(SATELLITE_CONFIG.ringSize, SATELLITE_CONFIG.ringSize, 1);
|
||||||
sprite.renderOrder = SATELLITE_CONFIG.overlayRenderOrder;
|
sprite.renderOrder = SATELLITE_CONFIG.overlayRenderOrder;
|
||||||
@@ -1806,6 +1837,26 @@ function createRingSprite(position, isLocked = false) {
|
|||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isLockedSatelliteHovered() {
|
||||||
|
return (
|
||||||
|
lockedSatelliteIndex !== null &&
|
||||||
|
hoveredSatelliteIndex !== null &&
|
||||||
|
hoveredSatelliteIndex === lockedSatelliteIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLockedMarkerVisual(isHovered) {
|
||||||
|
if (!lockedRingSprite?.material) return;
|
||||||
|
|
||||||
|
const nextTexture = isHovered
|
||||||
|
? lockedRingSprite.userData.ringTexture
|
||||||
|
: lockedRingSprite.userData.filledTexture || lockedRingSprite.userData.ringTexture;
|
||||||
|
if (lockedRingSprite.material.map !== nextTexture) {
|
||||||
|
lockedRingSprite.material.map = nextTexture;
|
||||||
|
lockedRingSprite.material.needsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function createRelatedSatelliteSprite(position, color = "#7dd3fc") {
|
function createRelatedSatelliteSprite(position, color = "#7dd3fc") {
|
||||||
if (!earthObjRef) return null;
|
if (!earthObjRef) return null;
|
||||||
|
|
||||||
@@ -1830,11 +1881,12 @@ export function showHoverRing(position, isLocked = false) {
|
|||||||
if (!earthObjRef || !position) return null;
|
if (!earthObjRef || !position) return null;
|
||||||
|
|
||||||
if (isLocked) {
|
if (isLocked) {
|
||||||
|
const lockedProps = getLockedSatelliteProperties() || {};
|
||||||
|
const legendColor = getSatelliteLegendRule(lockedProps).color;
|
||||||
hideLockedRing();
|
hideLockedRing();
|
||||||
lockedRingSprite = createRingSprite(position, true);
|
lockedRingSprite = createRingSprite(position, true, legendColor);
|
||||||
const presentationMode = getSatellitePresentationMode(
|
updateLockedMarkerVisual(isLockedSatelliteHovered());
|
||||||
getLockedSatelliteProperties() || {},
|
const presentationMode = getSatellitePresentationMode(lockedProps);
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
presentationMode ===
|
presentationMode ===
|
||||||
SATELLITE_PRESENTATION_MODES.STARLINK_GROUND_FOOTPRINT
|
SATELLITE_PRESENTATION_MODES.STARLINK_GROUND_FOOTPRINT
|
||||||
@@ -1845,7 +1897,7 @@ export function showHoverRing(position, isLocked = false) {
|
|||||||
) {
|
) {
|
||||||
showIridiumReservedStyle(position);
|
showIridiumReservedStyle(position);
|
||||||
} else {
|
} else {
|
||||||
showSelfGlowStyle(position);
|
showSelfGlowStyle(position, legendColor);
|
||||||
}
|
}
|
||||||
return lockedRingSprite;
|
return lockedRingSprite;
|
||||||
}
|
}
|
||||||
@@ -1864,7 +1916,15 @@ export function hideHoverRings() {
|
|||||||
|
|
||||||
export function hideLockedRing() {
|
export function hideLockedRing() {
|
||||||
if (lockedRingSprite) {
|
if (lockedRingSprite) {
|
||||||
|
const ringTexture = lockedRingSprite.userData?.ringTexture;
|
||||||
|
const filledTexture = lockedRingSprite.userData?.filledTexture;
|
||||||
disposeObject3D(lockedRingSprite);
|
disposeObject3D(lockedRingSprite);
|
||||||
|
if (ringTexture && ringTexture !== lockedRingSprite.material?.map) {
|
||||||
|
ringTexture.dispose();
|
||||||
|
}
|
||||||
|
if (filledTexture && filledTexture !== lockedRingSprite.material?.map) {
|
||||||
|
filledTexture.dispose();
|
||||||
|
}
|
||||||
lockedRingSprite = null;
|
lockedRingSprite = null;
|
||||||
}
|
}
|
||||||
clearLockedSatelliteStyleVisuals();
|
clearLockedSatelliteStyleVisuals();
|
||||||
@@ -1885,21 +1945,28 @@ export function updateLockedRingPosition(position) {
|
|||||||
showHoverRing(position, true);
|
showHoverRing(position, true);
|
||||||
}
|
}
|
||||||
if (lockedRingSprite) {
|
if (lockedRingSprite) {
|
||||||
|
const isHovered = isLockedSatelliteHovered();
|
||||||
|
updateLockedMarkerVisual(isHovered);
|
||||||
lockedRingSprite.position.copy(position);
|
lockedRingSprite.position.copy(position);
|
||||||
const ringPulse = getBreathingPulse(breathingPhase);
|
const ringPulse = getBreathingPulse(breathingPhase);
|
||||||
const breathScale =
|
const breathScale =
|
||||||
1 +
|
1 +
|
||||||
(ringPulse * 2 - 1) * SATELLITE_CONFIG.breathingScaleAmplitude;
|
(ringPulse * 2 - 1) * SATELLITE_CONFIG.breathingScaleAmplitude;
|
||||||
|
const markerSize = isHovered
|
||||||
|
? SATELLITE_CONFIG.ringSize
|
||||||
|
: SATELLITE_CONFIG.ringSize * LOCKED_RING_IDLE_SCALE;
|
||||||
lockedRingSprite.scale.set(
|
lockedRingSprite.scale.set(
|
||||||
SATELLITE_CONFIG.ringSize * breathScale,
|
markerSize * breathScale,
|
||||||
SATELLITE_CONFIG.ringSize * breathScale,
|
markerSize * breathScale,
|
||||||
1,
|
1,
|
||||||
);
|
);
|
||||||
lockedRingSprite.material.opacity =
|
lockedRingSprite.material.opacity =
|
||||||
SATELLITE_CONFIG.breathingOpacityMin +
|
isHovered
|
||||||
ringPulse *
|
? SATELLITE_CONFIG.breathingOpacityMin +
|
||||||
(SATELLITE_CONFIG.breathingOpacityMax -
|
ringPulse *
|
||||||
SATELLITE_CONFIG.breathingOpacityMin);
|
(SATELLITE_CONFIG.breathingOpacityMax -
|
||||||
|
SATELLITE_CONFIG.breathingOpacityMin)
|
||||||
|
: LOCKED_RING_IDLE_OPACITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lockedDotSprite) {
|
if (lockedDotSprite) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "planet"
|
name = "planet"
|
||||||
version = "0.40.0"
|
version = "0.40.1"
|
||||||
description = "智能星球计划 - 态势感知系统"
|
description = "智能星球计划 - 态势感知系统"
|
||||||
requires-python = ">=3.14"
|
requires-python = ">=3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
|||||||
Reference in New Issue
Block a user