## Changelog ### New Features - Modularized 3D earth HTML page from single 1918-line file into ES Modules - Split CSS into separate module files (base, info-panel, coordinates-display, legend, earth-stats) - Split JS into separate modules (constants, utils, ui, earth, cables, controls, main) ### 3D Earth Rendering - Use Three.js r128 (via esm.sh CDN) for color consistency with original - Earth with 8K satellite texture and proper material settings - Cloud layer with transparency and additive blending - Starfield background (8000 stars) - Latitude/longitude grid lines that rotate with Earth ### Cable System - Load cable data from geo.json with great circle path calculation - Support for MultiLineString and LineString geometry types - Cable color from geo.json properties.color field - Landing points loading from landing-point-geo.geojson ### User Interactions - Mouse hover: highlight cable and show details - Mouse click: lock cable with pulsing glow effect - Click cable to pause rotation, click elsewhere to resume - Click rotation toggle button to resume rotation and clear highlight - Reset view with smooth animation (800ms cubic ease-out) - Mouse wheel zoom support - Drag to rotate Earth ### UI/UX Improvements - Tooltip shows latitude, longitude, and altitude - Prevent tooltip text selection during drag - Hide tooltip during drag operation - Blue border tooltip styling matching original - Cursor changes to grabbing during drag - Front-facing cable detection (only detect cables facing camera) ### Bug Fixes - Grid lines now rotate with Earth (added as Earth child) - Reset view button now works correctly - Fixed camera reference in reset view - Fixed autoRotate state management when clearing locked cable ### Original HTML - Copied original 3dearthmult.html to public folder for reference
56 lines
1.6 KiB
JavaScript
56 lines
1.6 KiB
JavaScript
// utils.js - Utility functions for coordinate conversion
|
|
|
|
import * as THREE from 'three';
|
|
|
|
import { CONFIG } from './constants.js';
|
|
|
|
// Convert latitude/longitude to 3D vector
|
|
export function latLonToVector3(lat, lon, radius = CONFIG.earthRadius) {
|
|
const phi = (90 - lat) * (Math.PI / 180);
|
|
const theta = (lon + 180) * (Math.PI / 180);
|
|
|
|
const x = -(radius * Math.sin(phi) * Math.cos(theta));
|
|
const z = radius * Math.sin(phi) * Math.sin(theta);
|
|
const y = radius * Math.cos(phi);
|
|
|
|
return new THREE.Vector3(x, y, z);
|
|
}
|
|
|
|
// Convert 3D vector to latitude/longitude
|
|
export function vector3ToLatLon(vector) {
|
|
const radius = Math.sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
|
|
const lat = 90 - (Math.acos(vector.y / radius) * 180 / Math.PI);
|
|
const lon = (Math.atan2(vector.z, -vector.x) * 180 / Math.PI) - 180;
|
|
|
|
return {
|
|
lat: parseFloat(lat.toFixed(4)),
|
|
lon: parseFloat(lon.toFixed(4)),
|
|
alt: radius - CONFIG.earthRadius
|
|
};
|
|
}
|
|
|
|
// Convert screen coordinates to Earth surface 3D coordinates
|
|
export function screenToEarthCoords(x, y, camera, earth) {
|
|
const raycaster = new THREE.Raycaster();
|
|
const mouse = new THREE.Vector2(
|
|
(x / window.innerWidth) * 2 - 1,
|
|
-(y / window.innerHeight) * 2 + 1
|
|
);
|
|
|
|
raycaster.setFromCamera(mouse, camera);
|
|
const intersects = raycaster.intersectObject(earth);
|
|
|
|
if (intersects.length > 0) {
|
|
return intersects[0].point;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// Calculate simplified distance between two points
|
|
export function calculateDistance(lat1, lon1, lat2, lon2) {
|
|
const dx = lon2 - lon1;
|
|
const dy = lat2 - lat1;
|
|
return Math.sqrt(dx * dx + dy * dy);
|
|
}
|