diff --git a/frontend/public/earth/js/constants.js b/frontend/public/earth/js/constants.js index 912783ba..a1c68a0a 100644 --- a/frontend/public/earth/js/constants.js +++ b/frontend/public/earth/js/constants.js @@ -38,7 +38,15 @@ export const CABLE_COLORS = { 'default': 0xffff44 }; -// Grid configuration +export const CABLE_CONFIG = { + lockedOpacityMin: 0.6, + lockedOpacityMax: 1.0, + otherOpacity: 0.5, + otherBrightness: 0.6, + pulseSpeed: 0.003, + pulseCoefficient: 0.4 +}; + export const GRID_CONFIG = { latitudeStep: 10, longitudeStep: 30, diff --git a/frontend/public/earth/js/main.js b/frontend/public/earth/js/main.js index 5cc88f0a..843702ec 100644 --- a/frontend/public/earth/js/main.js +++ b/frontend/public/earth/js/main.js @@ -1,7 +1,7 @@ import * as THREE from 'three'; import { createNoise3D } from 'simplex-noise'; -import { CONFIG } from './constants.js'; +import { CONFIG, CABLE_CONFIG } from './constants.js'; import { latLonToVector3, vector3ToLatLon, screenToEarthCoords } from './utils.js'; import { showStatusMessage, @@ -32,21 +32,48 @@ let dragStartTime = 0; let isLongDrag = false; function clearLockedObject() { - if (lockedObjectType === 'cable' && lockedObject) { - const prevCableId = lockedObject.userData.cableId; - const prevSameCables = getCablesById(prevCableId); - prevSameCables.forEach(c => { - if (c.userData.originalColor !== undefined) { - c.material.color.setHex(c.userData.originalColor); - } - }); - } + hoveredCable = null; lockedObject = null; lockedObjectType = null; lockedSatellite = null; cableLockedData = null; } +function isSameCable(cable1, cable2) { + return cable1 && cable2 && cable1.userData.cableId === cable2.userData.cableId; +} + +function applyCableVisualState() { + const allCables = getCableLines(); + const pulse = (Math.sin(Date.now() * CABLE_CONFIG.pulseSpeed) + 1) * 0.5; + const isLocked = lockedObjectType === 'cable' && lockedObject; + + allCables.forEach(c => { + const cableIsLocked = isSameCable(c, lockedObject); + const cableIsHovered = isSameCable(c, hoveredCable); + + if (cableIsLocked) { + c.material.opacity = CABLE_CONFIG.lockedOpacityMin + pulse * CABLE_CONFIG.pulseCoefficient; + c.material.color.setRGB(1, 1, 1); + } else if (cableIsHovered) { + c.material.opacity = 1; + c.material.color.setRGB(1, 1, 1); + } else if (isLocked) { + c.material.opacity = CABLE_CONFIG.otherOpacity; + const origColor = c.userData.originalColor; + const brightness = CABLE_CONFIG.otherBrightness; + c.material.color.setRGB( + ((origColor >> 16) & 255) / 255 * brightness, + ((origColor >> 8) & 255) / 255 * brightness, + (origColor & 255) / 255 * brightness + ); + } else { + c.material.opacity = 1; + c.material.color.setHex(c.userData.originalColor); + } + }); +} + window.addEventListener('error', (e) => { console.error('全局错误:', e.error); showStatusMessage('加载错误: ' + e.error?.message, 'error'); @@ -204,14 +231,7 @@ function onMouseMove(event, camera) { const frontCables = getFrontFacingCables(allCableLines, camera); const intersects = raycaster.intersectObjects(frontCables); - if (hoveredCable && (lockedObjectType !== 'cable' || hoveredCable !== lockedObject)) { - const prevCableId = hoveredCable.userData.cableId; - const prevSameCables = getCablesById(prevCableId); - prevSameCables.forEach(c => { - if (c.userData.originalColor !== undefined) { - c.material.color.setHex(c.userData.originalColor); - } - }); + if (hoveredCable && (lockedObjectType !== 'cable' || !isSameCable(hoveredCable, lockedObject))) { hoveredCable = null; } @@ -231,16 +251,7 @@ function onMouseMove(event, camera) { if (hasHoveredCable) { const cable = intersects[0].object; - const cableId = cable.userData.cableId; - const sameCables = getCablesById(cableId); - - if (lockedObjectType !== 'cable' || cable !== lockedObject) { - sameCables.forEach(c => { - c.material.color.setHex(0xffffff); - c.material.opacity = 1; - }); - hoveredCable = cable; - } + hoveredCable = cable; showInfoCard('cable', { name: cable.userData.name, @@ -421,16 +432,7 @@ function animate() { earth.rotation.y += CONFIG.rotationSpeed; } - if (lockedObjectType === 'cable') { - const pulse = (Math.sin(Date.now() * 0.003) + 1) * 0.5; - const glowIntensity = 0.7 + pulse * 0.3; - const cableId = lockedObject.userData.cableId; - const sameCables = getCablesById(cableId); - sameCables.forEach(c => { - c.material.opacity = 0.6 + pulse * 0.4; - c.material.color.setRGB(glowIntensity, glowIntensity, glowIntensity); - }); - } + applyCableVisualState(); updateSatellitePositions(16);