Merge pull request 'dev' (#2) from dev into main
Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
@@ -43,7 +43,7 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 6px;
|
||||||
background: rgba(10, 10, 30, 0.9);
|
background: rgba(10, 10, 30, 0.9);
|
||||||
padding: 8px 4px;
|
padding: 8px 4px;
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
@@ -93,7 +93,9 @@ body {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#zoom-toolbar .zoom-btn:hover {
|
#zoom-toolbar .zoom-btn:hover {
|
||||||
@@ -306,6 +308,9 @@ input[type="range"]::-webkit-slider-thumb {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar-btn:hover {
|
.toolbar-btn:hover {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
<div id="right-toolbar-group">
|
<div id="right-toolbar-group">
|
||||||
<div id="zoom-toolbar">
|
<div id="zoom-toolbar">
|
||||||
<button id="reset-view" class="zoom-btn">🎯</button>
|
<button id="reset-view" class="zoom-btn">🎯</button>
|
||||||
<input type="range" id="zoom-slider" min="0.5" max="5" step="0.01" value="1">
|
|
||||||
<button id="zoom-in" class="zoom-btn">+</button>
|
<button id="zoom-in" class="zoom-btn">+</button>
|
||||||
<span id="zoom-value" class="zoom-percent">100%</span>
|
<span id="zoom-value" class="zoom-percent">100%</span>
|
||||||
<button id="zoom-out" class="zoom-btn">−</button>
|
<button id="zoom-out" class="zoom-btn">−</button>
|
||||||
@@ -48,8 +47,9 @@
|
|||||||
<div id="control-toolbar">
|
<div id="control-toolbar">
|
||||||
<div class="toolbar-items">
|
<div class="toolbar-items">
|
||||||
<button id="rotate-toggle" class="toolbar-btn" title="自动旋转">🔄<span class="tooltip">自动旋转</span></button>
|
<button id="rotate-toggle" class="toolbar-btn" title="自动旋转">🔄<span class="tooltip">自动旋转</span></button>
|
||||||
|
<button id="toggle-cables" class="toolbar-btn active" title="显示/隐藏线缆">🌐<span class="tooltip">隐藏线缆</span></button>
|
||||||
<button id="toggle-terrain" class="toolbar-btn" title="显示/隐藏地形">⛰️<span class="tooltip">显示/隐藏地形</span></button>
|
<button id="toggle-terrain" class="toolbar-btn" title="显示/隐藏地形">⛰️<span class="tooltip">显示/隐藏地形</span></button>
|
||||||
<button id="toggle-satellites" class="toolbar-btn" title="显示/隐藏卫星">🛰️<span class="tooltip">显示/隐藏卫星</span></button>
|
<button id="toggle-satellites" class="toolbar-btn" title="显示/隐藏卫星">🛰️<span class="tooltip">显示卫星</span></button>
|
||||||
<button id="toggle-trails" class="toolbar-btn" title="显示/隐藏轨迹">✨<span class="tooltip">显示/隐藏轨迹</span></button>
|
<button id="toggle-trails" class="toolbar-btn" title="显示/隐藏轨迹">✨<span class="tooltip">显示/隐藏轨迹</span></button>
|
||||||
<button id="reload-data" class="toolbar-btn" title="重新加载数据">🔃<span class="tooltip">重新加载数据</span></button>
|
<button id="reload-data" class="toolbar-btn" title="重新加载数据">🔃<span class="tooltip">重新加载数据</span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export let cableLines = [];
|
|||||||
export let landingPoints = [];
|
export let landingPoints = [];
|
||||||
export let lockedCable = null;
|
export let lockedCable = null;
|
||||||
let cableIdMap = new Map();
|
let cableIdMap = new Map();
|
||||||
|
let cablesVisible = true;
|
||||||
|
|
||||||
function getCableColor(properties) {
|
function getCableColor(properties) {
|
||||||
if (properties.color) {
|
if (properties.color) {
|
||||||
@@ -406,3 +407,17 @@ export function resetLandingPointVisualState() {
|
|||||||
lp.scale.setScalar(1.0);
|
lp.scale.setScalar(1.0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function toggleCables(show) {
|
||||||
|
cablesVisible = show;
|
||||||
|
cableLines.forEach(cable => {
|
||||||
|
cable.visible = cablesVisible;
|
||||||
|
});
|
||||||
|
landingPoints.forEach(lp => {
|
||||||
|
lp.visible = cablesVisible;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShowCables() {
|
||||||
|
return cablesVisible;
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ export const CABLE_COLORS = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CABLE_CONFIG = {
|
export const CABLE_CONFIG = {
|
||||||
lockedOpacityMin: 0.6,
|
lockedOpacityMin: 0.2,
|
||||||
lockedOpacityMax: 1.0,
|
lockedOpacityMax: 1.0,
|
||||||
otherOpacity: 0.5,
|
otherOpacity: 0.5,
|
||||||
otherBrightness: 0.6,
|
otherBrightness: 0.6,
|
||||||
pulseSpeed: 0.003,
|
pulseSpeed: 0.008,
|
||||||
pulseCoefficient: 0.4
|
pulseCoefficient: 0.4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
119
frontend/public/earth/js/controls.js
vendored
119
frontend/public/earth/js/controls.js
vendored
@@ -3,8 +3,9 @@
|
|||||||
import { CONFIG, EARTH_CONFIG } from './constants.js';
|
import { CONFIG, EARTH_CONFIG } from './constants.js';
|
||||||
import { updateZoomDisplay, showStatusMessage } from './ui.js';
|
import { updateZoomDisplay, showStatusMessage } from './ui.js';
|
||||||
import { toggleTerrain } from './earth.js';
|
import { toggleTerrain } from './earth.js';
|
||||||
import { reloadData } from './main.js';
|
import { reloadData, clearLockedObject } from './main.js';
|
||||||
import { toggleSatellites, toggleTrails, getShowSatellites, getSatelliteCount } from './satellites.js';
|
import { toggleSatellites, toggleTrails, getShowSatellites, getSatelliteCount } from './satellites.js';
|
||||||
|
import { toggleCables, getShowCables } from './cables.js';
|
||||||
|
|
||||||
export let autoRotate = true;
|
export let autoRotate = true;
|
||||||
export let zoomLevel = 1.0;
|
export let zoomLevel = 1.0;
|
||||||
@@ -23,33 +24,18 @@ export function setupControls(camera, renderer, scene, earth) {
|
|||||||
|
|
||||||
function setupZoomControls(camera) {
|
function setupZoomControls(camera) {
|
||||||
let zoomInterval = null;
|
let zoomInterval = null;
|
||||||
let lastDirection = 0;
|
let holdTimeout = null;
|
||||||
let isSnapped = false;
|
let startTime = 0;
|
||||||
|
const HOLD_THRESHOLD = 150;
|
||||||
|
const LONG_PRESS_TICK = 50;
|
||||||
|
const CLICK_STEP = 10;
|
||||||
|
|
||||||
const MIN_PERCENT = CONFIG.minZoom * 100;
|
const MIN_PERCENT = CONFIG.minZoom * 100;
|
||||||
const MAX_PERCENT = CONFIG.maxZoom * 100;
|
const MAX_PERCENT = CONFIG.maxZoom * 100;
|
||||||
|
|
||||||
function adjustZoom(direction) {
|
function doZoomStep(direction) {
|
||||||
const currentPercent = Math.round(zoomLevel * 100);
|
let currentPercent = Math.round(zoomLevel * 100);
|
||||||
let newPercent;
|
let newPercent = direction > 0 ? currentPercent + CLICK_STEP : currentPercent - CLICK_STEP;
|
||||||
|
|
||||||
if (direction > 0) {
|
|
||||||
if (!isSnapped || currentPercent % 10 !== 0) {
|
|
||||||
newPercent = Math.ceil(currentPercent / 10) * 10;
|
|
||||||
if (newPercent <= currentPercent) newPercent = currentPercent + 10;
|
|
||||||
isSnapped = true;
|
|
||||||
} else {
|
|
||||||
newPercent = currentPercent + 10;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!isSnapped || currentPercent % 10 !== 0) {
|
|
||||||
newPercent = Math.floor(currentPercent / 10) * 10;
|
|
||||||
if (newPercent >= currentPercent) newPercent = currentPercent - 10;
|
|
||||||
isSnapped = true;
|
|
||||||
} else {
|
|
||||||
newPercent = currentPercent - 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newPercent > MAX_PERCENT) newPercent = MAX_PERCENT;
|
if (newPercent > MAX_PERCENT) newPercent = MAX_PERCENT;
|
||||||
if (newPercent < MIN_PERCENT) newPercent = MIN_PERCENT;
|
if (newPercent < MIN_PERCENT) newPercent = MIN_PERCENT;
|
||||||
@@ -58,13 +44,22 @@ function setupZoomControls(camera) {
|
|||||||
applyZoom(camera);
|
applyZoom(camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
function startZoom(direction) {
|
function doContinuousZoom(direction) {
|
||||||
isSnapped = false;
|
let currentPercent = Math.round(zoomLevel * 100);
|
||||||
lastDirection = direction;
|
let newPercent = direction > 0 ? currentPercent + 1 : currentPercent - 1;
|
||||||
adjustZoom(direction);
|
|
||||||
|
if (newPercent > MAX_PERCENT) newPercent = MAX_PERCENT;
|
||||||
|
if (newPercent < MIN_PERCENT) newPercent = MIN_PERCENT;
|
||||||
|
|
||||||
|
zoomLevel = newPercent / 100;
|
||||||
|
applyZoom(camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startContinuousZoom(direction) {
|
||||||
|
doContinuousZoom(direction);
|
||||||
zoomInterval = setInterval(() => {
|
zoomInterval = setInterval(() => {
|
||||||
adjustZoom(direction);
|
doContinuousZoom(direction);
|
||||||
}, 150);
|
}, LONG_PRESS_TICK);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopZoom() {
|
function stopZoom() {
|
||||||
@@ -72,29 +67,49 @@ function setupZoomControls(camera) {
|
|||||||
clearInterval(zoomInterval);
|
clearInterval(zoomInterval);
|
||||||
zoomInterval = null;
|
zoomInterval = null;
|
||||||
}
|
}
|
||||||
|
if (holdTimeout) {
|
||||||
|
clearTimeout(holdTimeout);
|
||||||
|
holdTimeout = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('zoom-in').addEventListener('mousedown', () => startZoom(1));
|
function handleMouseDown(direction) {
|
||||||
document.getElementById('zoom-in').addEventListener('mouseup', stopZoom);
|
startTime = Date.now();
|
||||||
document.getElementById('zoom-in').addEventListener('mouseleave', stopZoom);
|
stopZoom();
|
||||||
document.getElementById('zoom-in').addEventListener('touchstart', (e) => { e.preventDefault(); startZoom(1); });
|
holdTimeout = setTimeout(() => {
|
||||||
document.getElementById('zoom-in').addEventListener('touchend', stopZoom);
|
startContinuousZoom(direction);
|
||||||
|
}, HOLD_THRESHOLD);
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('zoom-out').addEventListener('mousedown', () => startZoom(-1));
|
function handleMouseUp(direction) {
|
||||||
document.getElementById('zoom-out').addEventListener('mouseup', stopZoom);
|
const heldTime = Date.now() - startTime;
|
||||||
|
stopZoom();
|
||||||
|
if (heldTime < HOLD_THRESHOLD) {
|
||||||
|
doZoomStep(direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('zoom-in').addEventListener('mousedown', () => handleMouseDown(1));
|
||||||
|
document.getElementById('zoom-in').addEventListener('mouseup', () => handleMouseUp(1));
|
||||||
|
document.getElementById('zoom-in').addEventListener('mouseleave', stopZoom);
|
||||||
|
document.getElementById('zoom-in').addEventListener('touchstart', (e) => { e.preventDefault(); handleMouseDown(1); });
|
||||||
|
document.getElementById('zoom-in').addEventListener('touchend', () => handleMouseUp(1));
|
||||||
|
|
||||||
|
document.getElementById('zoom-out').addEventListener('mousedown', () => handleMouseDown(-1));
|
||||||
|
document.getElementById('zoom-out').addEventListener('mouseup', () => handleMouseUp(-1));
|
||||||
document.getElementById('zoom-out').addEventListener('mouseleave', stopZoom);
|
document.getElementById('zoom-out').addEventListener('mouseleave', stopZoom);
|
||||||
document.getElementById('zoom-out').addEventListener('touchstart', (e) => { e.preventDefault(); startZoom(-1); });
|
document.getElementById('zoom-out').addEventListener('touchstart', (e) => { e.preventDefault(); handleMouseDown(-1); });
|
||||||
document.getElementById('zoom-out').addEventListener('touchend', stopZoom);
|
document.getElementById('zoom-out').addEventListener('touchend', () => handleMouseUp(-1));
|
||||||
|
|
||||||
document.getElementById('zoom-value').addEventListener('click', function() {
|
document.getElementById('zoom-value').addEventListener('click', function() {
|
||||||
const startZoom = zoomLevel;
|
const startZoomVal = zoomLevel;
|
||||||
const targetZoom = 1.0;
|
const targetZoom = 1.0;
|
||||||
const startDistance = CONFIG.defaultCameraZ / startZoom;
|
const startDistance = CONFIG.defaultCameraZ / startZoomVal;
|
||||||
const targetDistance = CONFIG.defaultCameraZ / targetZoom;
|
const targetDistance = CONFIG.defaultCameraZ / targetZoom;
|
||||||
|
|
||||||
animateValue(0, 1, 600, (progress) => {
|
animateValue(0, 1, 600, (progress) => {
|
||||||
const ease = 1 - Math.pow(1 - progress, 3);
|
const ease = 1 - Math.pow(1 - progress, 3);
|
||||||
zoomLevel = startZoom + (targetZoom - startZoom) * ease;
|
zoomLevel = startZoomVal + (targetZoom - startZoomVal) * ease;
|
||||||
camera.position.z = CONFIG.defaultCameraZ / zoomLevel;
|
camera.position.z = CONFIG.defaultCameraZ / zoomLevel;
|
||||||
const distance = startDistance + (targetDistance - startDistance) * ease;
|
const distance = startDistance + (targetDistance - startDistance) * ease;
|
||||||
updateZoomDisplay(zoomLevel, distance.toFixed(0));
|
updateZoomDisplay(zoomLevel, distance.toFixed(0));
|
||||||
@@ -103,12 +118,6 @@ function setupZoomControls(camera) {
|
|||||||
showStatusMessage('缩放已重置到100%', 'info');
|
showStatusMessage('缩放已重置到100%', 'info');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const slider = document.getElementById('zoom-slider');
|
|
||||||
slider?.addEventListener('input', (e) => {
|
|
||||||
zoomLevel = parseFloat(e.target.value);
|
|
||||||
applyZoom(camera);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupWheelZoom(camera, renderer) {
|
function setupWheelZoom(camera, renderer) {
|
||||||
@@ -219,6 +228,9 @@ function setupTerrainControls() {
|
|||||||
|
|
||||||
document.getElementById('toggle-satellites').addEventListener('click', function() {
|
document.getElementById('toggle-satellites').addEventListener('click', function() {
|
||||||
const showSats = !getShowSatellites();
|
const showSats = !getShowSatellites();
|
||||||
|
if (!showSats) {
|
||||||
|
clearLockedObject();
|
||||||
|
}
|
||||||
toggleSatellites(showSats);
|
toggleSatellites(showSats);
|
||||||
this.classList.toggle('active', showSats);
|
this.classList.toggle('active', showSats);
|
||||||
this.querySelector('.tooltip').textContent = showSats ? '隐藏卫星' : '显示卫星';
|
this.querySelector('.tooltip').textContent = showSats ? '隐藏卫星' : '显示卫星';
|
||||||
@@ -235,6 +247,17 @@ function setupTerrainControls() {
|
|||||||
showStatusMessage(showTrails ? '轨迹已显示' : '轨迹已隐藏', 'info');
|
showStatusMessage(showTrails ? '轨迹已显示' : '轨迹已隐藏', 'info');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('toggle-cables').addEventListener('click', function() {
|
||||||
|
const showCables = !getShowCables();
|
||||||
|
if (!showCables) {
|
||||||
|
clearLockedObject();
|
||||||
|
}
|
||||||
|
toggleCables(showCables);
|
||||||
|
this.classList.toggle('active', showCables);
|
||||||
|
this.querySelector('.tooltip').textContent = showCables ? '隐藏线缆' : '显示线缆';
|
||||||
|
showStatusMessage(showCables ? '线缆已显示' : '线缆已隐藏', 'info');
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('reload-data').addEventListener('click', async () => {
|
document.getElementById('reload-data').addEventListener('click', async () => {
|
||||||
await reloadData();
|
await reloadData();
|
||||||
showStatusMessage('数据已重新加载', 'success');
|
showStatusMessage('数据已重新加载', 'success');
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
hideTooltip
|
hideTooltip
|
||||||
} from './ui.js';
|
} from './ui.js';
|
||||||
import { createEarth, createClouds, createTerrain, createStars, createGridLines, toggleTerrain, getEarth } from './earth.js';
|
import { createEarth, createClouds, createTerrain, createStars, createGridLines, toggleTerrain, getEarth } from './earth.js';
|
||||||
import { loadGeoJSONFromPath, loadLandingPoints, handleCableClick, clearCableSelection, getCableLines, getCablesById, lockedCable as cableLocked, getCableState, setCableState, clearAllCableStates, applyLandingPointVisualState, resetLandingPointVisualState, getAllLandingPoints } from './cables.js';
|
import { loadGeoJSONFromPath, loadLandingPoints, handleCableClick, clearCableSelection, getCableLines, getCablesById, lockedCable as cableLocked, getCableState, setCableState, clearAllCableStates, applyLandingPointVisualState, resetLandingPointVisualState, getAllLandingPoints, getShowCables } from './cables.js';
|
||||||
import { createSatellites, loadSatellites, updateSatellitePositions, toggleSatellites, toggleTrails, getShowSatellites, selectSatellite, getSatelliteData, getSatellitePoints, setSatelliteRingState, updateLockedRingPosition, updateHoverRingPosition, getSatellitePositions } from './satellites.js';
|
import { createSatellites, loadSatellites, updateSatellitePositions, toggleSatellites, toggleTrails, getShowSatellites, selectSatellite, getSatelliteData, getSatellitePoints, setSatelliteRingState, updateLockedRingPosition, updateHoverRingPosition, getSatellitePositions } from './satellites.js';
|
||||||
import { setupControls, getAutoRotate, getShowTerrain, zoomLevel, setAutoRotate, toggleAutoRotate, resetView } from './controls.js';
|
import { setupControls, getAutoRotate, getShowTerrain, zoomLevel, setAutoRotate, toggleAutoRotate, resetView } from './controls.js';
|
||||||
import { initInfoCard, showInfoCard, hideInfoCard, getCurrentType, setInfoCardNoBorder } from './info-card.js';
|
import { initInfoCard, showInfoCard, hideInfoCard, getCurrentType, setInfoCardNoBorder } from './info-card.js';
|
||||||
@@ -33,7 +33,7 @@ let lockedObjectType = null;
|
|||||||
let dragStartTime = 0;
|
let dragStartTime = 0;
|
||||||
let isLongDrag = false;
|
let isLongDrag = false;
|
||||||
|
|
||||||
function clearLockedObject() {
|
export function clearLockedObject() {
|
||||||
hoveredCable = null;
|
hoveredCable = null;
|
||||||
hoveredSatellite = null;
|
hoveredSatellite = null;
|
||||||
hoveredSatelliteIndex = null;
|
hoveredSatelliteIndex = null;
|
||||||
@@ -92,7 +92,7 @@ function applyCableVisualState() {
|
|||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case CABLE_STATE.LOCKED:
|
case CABLE_STATE.LOCKED:
|
||||||
c.material.opacity = 0.3 + pulse * 0.7;
|
c.material.opacity = CABLE_CONFIG.lockedOpacityMin + pulse * (CABLE_CONFIG.lockedOpacityMax - CABLE_CONFIG.lockedOpacityMin);
|
||||||
c.material.color.setRGB(1, 1, 1);
|
c.material.color.setRGB(1, 1, 1);
|
||||||
break;
|
break;
|
||||||
case CABLE_STATE.HOVERED:
|
case CABLE_STATE.HOVERED:
|
||||||
@@ -191,16 +191,27 @@ async function loadData(showWhiteSphere = false) {
|
|||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
console.log('开始加载电缆数据...');
|
console.log('开始加载数据...');
|
||||||
|
await Promise.all([
|
||||||
|
(async () => {
|
||||||
await loadGeoJSONFromPath(scene, getEarth());
|
await loadGeoJSONFromPath(scene, getEarth());
|
||||||
console.log('电缆数据加载完成');
|
console.log('电缆数据加载完成');
|
||||||
await loadLandingPoints(scene, getEarth());
|
await loadLandingPoints(scene, getEarth());
|
||||||
console.log('登陆点数据加载完成');
|
console.log('登陆点数据加载完成');
|
||||||
|
})(),
|
||||||
|
(async () => {
|
||||||
const satCount = await loadSatellites();
|
const satCount = await loadSatellites();
|
||||||
console.log(`卫星数据加载完成: ${satCount} 颗`);
|
console.log(`卫星数据加载完成: ${satCount} 颗`);
|
||||||
updateSatellitePositions();
|
updateSatellitePositions();
|
||||||
console.log('卫星位置已更新');
|
console.log('卫星位置已更新');
|
||||||
|
toggleSatellites(true);
|
||||||
|
const satBtn = document.getElementById('toggle-satellites');
|
||||||
|
if (satBtn) {
|
||||||
|
satBtn.classList.add('active');
|
||||||
|
satBtn.querySelector('.tooltip').textContent = '隐藏卫星';
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载数据失败:', error);
|
console.error('加载数据失败:', error);
|
||||||
showStatusMessage('加载数据失败: ' + error.message, 'error');
|
showStatusMessage('加载数据失败: ' + error.message, 'error');
|
||||||
@@ -306,7 +317,7 @@ function onMouseMove(event, camera) {
|
|||||||
hoveredSatelliteIndex = null;
|
hoveredSatelliteIndex = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasHoveredCable) {
|
if (hasHoveredCable && getShowCables()) {
|
||||||
const cable = intersects[0].object;
|
const cable = intersects[0].object;
|
||||||
if (!isSameCable(cable, lockedObject)) {
|
if (!isSameCable(cable, lockedObject)) {
|
||||||
hoveredCable = cable;
|
hoveredCable = cable;
|
||||||
@@ -402,7 +413,7 @@ function onClick(event, camera, renderer) {
|
|||||||
const intersects = raycaster.intersectObjects(frontCables);
|
const intersects = raycaster.intersectObjects(frontCables);
|
||||||
const satIntersects = getShowSatellites() ? raycaster.intersectObject(getSatellitePoints()) : [];
|
const satIntersects = getShowSatellites() ? raycaster.intersectObject(getSatellitePoints()) : [];
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0 && getShowCables()) {
|
||||||
clearLockedObject();
|
clearLockedObject();
|
||||||
|
|
||||||
const clickedCable = intersects[0].object;
|
const clickedCable = intersects[0].object;
|
||||||
|
|||||||
@@ -291,9 +291,9 @@ export function updateSatellitePositions(deltaTime = 0) {
|
|||||||
trailColors[trailIdx + 1] = g * alpha;
|
trailColors[trailIdx + 1] = g * alpha;
|
||||||
trailColors[trailIdx + 2] = b * alpha;
|
trailColors[trailIdx + 2] = b * alpha;
|
||||||
} else {
|
} else {
|
||||||
trailPositions[trailIdx] = 0;
|
trailPositions[trailIdx] = pos.x;
|
||||||
trailPositions[trailIdx + 1] = 0;
|
trailPositions[trailIdx + 1] = pos.y;
|
||||||
trailPositions[trailIdx + 2] = 0;
|
trailPositions[trailIdx + 2] = pos.z;
|
||||||
trailColors[trailIdx] = 0;
|
trailColors[trailIdx] = 0;
|
||||||
trailColors[trailIdx + 1] = 0;
|
trailColors[trailIdx + 1] = 0;
|
||||||
trailColors[trailIdx + 2] = 0;
|
trailColors[trailIdx + 2] = 0;
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ export function updateZoomDisplay(zoomLevel, distance) {
|
|||||||
const percent = Math.round(zoomLevel * 100);
|
const percent = Math.round(zoomLevel * 100);
|
||||||
document.getElementById('zoom-value').textContent = percent + '%';
|
document.getElementById('zoom-value').textContent = percent + '%';
|
||||||
document.getElementById('zoom-level').textContent = '缩放: ' + percent + '%';
|
document.getElementById('zoom-level').textContent = '缩放: ' + percent + '%';
|
||||||
document.getElementById('zoom-slider').value = zoomLevel;
|
const slider = document.getElementById('zoom-slider');
|
||||||
|
if (slider) slider.value = zoomLevel;
|
||||||
document.getElementById('camera-distance').textContent = distance + ' km';
|
document.getElementById('camera-distance').textContent = distance + ' km';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,12 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html, body, #root {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ function Earth() {
|
|||||||
<iframe
|
<iframe
|
||||||
src="/earth/index.html"
|
src="/earth/index.html"
|
||||||
style={{
|
style={{
|
||||||
width: '100vw',
|
width: '100%',
|
||||||
height: '100vh',
|
height: '100%',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
|
display: 'block',
|
||||||
}}
|
}}
|
||||||
title="3D Earth"
|
title="3D Earth"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user