Sonnensystem kann jetzt mehr Kleinplaneten
This commit is contained in:
+103
-2
@@ -3831,9 +3831,9 @@ body.solarsystem-page main > .container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.solarsystem-input-row input[type="date"],
|
.solarsystem-input-row input[type="date"],
|
||||||
.solarsystem-input-row select {
|
.solarsystem-input-row select,
|
||||||
|
.solarsystem-multiselect {
|
||||||
min-height: 2.6rem;
|
min-height: 2.6rem;
|
||||||
padding: 0.55rem 0.8rem;
|
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 1px solid rgba(200, 168, 75, 0.14);
|
border: 1px solid rgba(200, 168, 75, 0.14);
|
||||||
background: rgba(10, 16, 36, 0.8);
|
background: rgba(10, 16, 36, 0.8);
|
||||||
@@ -3843,6 +3843,11 @@ body.solarsystem-page main > .container {
|
|||||||
flex: 1 1 170px;
|
flex: 1 1 170px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.solarsystem-input-row input[type="date"],
|
||||||
|
.solarsystem-input-row select {
|
||||||
|
padding: 0.55rem 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
.solarsystem-input-row select {
|
.solarsystem-input-row select {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
@@ -3882,6 +3887,102 @@ body.solarsystem-page main > .container {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect {
|
||||||
|
position: relative;
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02), 0 10px 24px rgba(0, 0, 0, 0.22);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect:hover {
|
||||||
|
border-color: rgba(201, 168, 76, 0.28);
|
||||||
|
background-color: rgba(14, 22, 44, 0.92);
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(201, 168, 76, 0.05), 0 14px 28px rgba(0, 0, 0, 0.26);
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect[open] {
|
||||||
|
border-color: rgba(201, 168, 76, 0.4);
|
||||||
|
box-shadow: 0 0 0 3px rgba(201, 168, 76, 0.12), 0 14px 28px rgba(0, 0, 0, 0.28);
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect summary {
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
min-height: 2.6rem;
|
||||||
|
padding: 0.55rem 2.9rem 0.55rem 0.8rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect summary::-webkit-details-marker {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect summary::before,
|
||||||
|
.solarsystem-multiselect summary::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
right: 1rem;
|
||||||
|
top: 50%;
|
||||||
|
width: 0.5rem;
|
||||||
|
height: 0.5rem;
|
||||||
|
border-right: 2px solid rgba(240, 217, 144, 0.92);
|
||||||
|
border-bottom: 2px solid rgba(240, 217, 144, 0.92);
|
||||||
|
transform-origin: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect summary::before {
|
||||||
|
transform: translateY(-60%) rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect[open] summary::before {
|
||||||
|
transform: translateY(-20%) rotate(225deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect summary::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect-panel {
|
||||||
|
display: grid;
|
||||||
|
gap: 0.3rem;
|
||||||
|
max-height: 15rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 0.45rem 0.45rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.55rem;
|
||||||
|
padding: 0.45rem 0.5rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect-option:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect-option input {
|
||||||
|
margin: 0;
|
||||||
|
accent-color: #f0d990;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect-option span {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect.is-disabled {
|
||||||
|
opacity: 0.7;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarsystem-multiselect.is-disabled summary {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
.solarsystem-current-date,
|
.solarsystem-current-date,
|
||||||
.solarsystem-speed-value {
|
.solarsystem-speed-value {
|
||||||
color: var(--gold-pale);
|
color: var(--gold-pale);
|
||||||
|
|||||||
+242
-98
@@ -194,15 +194,28 @@ $bodyClass = 'solarsystem-page';
|
|||||||
<div class="solarsystem-sidebar-block">
|
<div class="solarsystem-sidebar-block">
|
||||||
<div class="solarsystem-label">Kleinplanet</div>
|
<div class="solarsystem-label">Kleinplanet</div>
|
||||||
<div class="solarsystem-input-row">
|
<div class="solarsystem-input-row">
|
||||||
<select id="solarMinorplanetSelect"<?= empty($trackedMinorplanetsForJs) ? ' disabled' : '' ?>>
|
<details class="solarsystem-multiselect<?= empty($trackedMinorplanetsForJs) ? ' is-disabled' : '' ?>" id="solarMinorplanetSelectWrap"<?= empty($trackedMinorplanetsForJs) ? ' open' : '' ?>>
|
||||||
<option value=""><?= empty($trackedMinorplanetsForJs) ? 'Keine Kleinplaneten ausgewaehlt' : 'Kein Kleinplanet' ?></option>
|
<summary id="solarMinorplanetSelectSummary">
|
||||||
<?php foreach ($trackedMinorplanetsForJs as $minorplanet): ?>
|
<?= empty($trackedMinorplanetsForJs) ? 'Keine Kleinplaneten verfuegbar' : 'Kleinplaneten auswaehlen' ?>
|
||||||
<option value="<?= (int) $minorplanet['id'] ?>"><?= h(formatMinorplanetDisplayName($minorplanet)) ?></option>
|
</summary>
|
||||||
<?php endforeach; ?>
|
<div class="solarsystem-multiselect-panel" id="solarMinorplanetSelectPanel">
|
||||||
</select>
|
<?php if (!empty($trackedMinorplanetsForJs)): ?>
|
||||||
|
<?php foreach ($trackedMinorplanetsForJs as $minorplanet): ?>
|
||||||
|
<label class="solarsystem-multiselect-option">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="solar-minorplanet-checkbox"
|
||||||
|
value="<?= (int) $minorplanet['id'] ?>"
|
||||||
|
>
|
||||||
|
<span><?= h(formatMinorplanetDisplayName($minorplanet)) ?></span>
|
||||||
|
</label>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
</div>
|
</div>
|
||||||
<div class="solarsystem-current-date solarsystem-minorplanet-hint" id="solarMinorplanetHint">
|
<div class="solarsystem-current-date solarsystem-minorplanet-hint" id="solarMinorplanetHint">
|
||||||
<?= empty($trackedMinorplanetsForJs) ? 'Fuege in den Favoriten Kleinplaneten hinzu, um hier ihren Orbit anzuzeigen.' : 'Der Orbit des gewaehlten Kleinplaneten wird eingeblendet.' ?>
|
<?= empty($trackedMinorplanetsForJs) ? 'Fuege in den Favoriten Kleinplaneten hinzu, um hier ihre Orbits anzuzeigen.' : 'Mehrere Kleinplaneten koennen gleichzeitig per Haken eingeblendet werden.' ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -212,7 +225,7 @@ $bodyClass = 'solarsystem-page';
|
|||||||
<li>Maus ziehen: Kamera drehen</li>
|
<li>Maus ziehen: Kamera drehen</li>
|
||||||
<li>Mausrad: Zoom</li>
|
<li>Mausrad: Zoom</li>
|
||||||
<li>Klick auf Planet: Fokus setzen</li>
|
<li>Klick auf Planet: Fokus setzen</li>
|
||||||
<li>Dropdown: gewaehlten Kleinplaneten-Orbit zeigen</li>
|
<li>Dropdown: mehrere Kleinplaneten per Haken anzeigen</li>
|
||||||
<li>Erneuter Klick ins Leere: Fokus loesen</li>
|
<li>Erneuter Klick ins Leere: Fokus loesen</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -314,7 +327,9 @@ const btnEcliptic = document.getElementById('solarBtnEcliptic');
|
|||||||
const speedSlider = document.getElementById('solarSpeedSlider');
|
const speedSlider = document.getElementById('solarSpeedSlider');
|
||||||
const speedLabel = document.getElementById('solarSpeedLabel');
|
const speedLabel = document.getElementById('solarSpeedLabel');
|
||||||
const infoPanel = document.getElementById('solarInfoPanel');
|
const infoPanel = document.getElementById('solarInfoPanel');
|
||||||
const minorPlanetSelect = document.getElementById('solarMinorplanetSelect');
|
const minorPlanetSelectWrap = document.getElementById('solarMinorplanetSelectWrap');
|
||||||
|
const minorPlanetSelectSummary = document.getElementById('solarMinorplanetSelectSummary');
|
||||||
|
const minorPlanetCheckboxes = Array.from(document.querySelectorAll('.solar-minorplanet-checkbox'));
|
||||||
|
|
||||||
if (!AstronomyEngine) {
|
if (!AstronomyEngine) {
|
||||||
overlay.textContent = 'Astronomy Engine konnte nicht geladen werden.';
|
overlay.textContent = 'Astronomy Engine konnte nicht geladen werden.';
|
||||||
@@ -336,9 +351,7 @@ let rotationEqjToEcl;
|
|||||||
let moonMesh = null;
|
let moonMesh = null;
|
||||||
let moonOrbitLine = null;
|
let moonOrbitLine = null;
|
||||||
let moonLabelElement = null;
|
let moonLabelElement = null;
|
||||||
let minorPlanetOrbitLine = null;
|
let minorPlanetObjects = null;
|
||||||
let minorPlanetMesh = null;
|
|
||||||
let minorPlanetLabelElement = null;
|
|
||||||
const planetDynamicsCache = new Map();
|
const planetDynamicsCache = new Map();
|
||||||
|
|
||||||
let showOrbits = true;
|
let showOrbits = true;
|
||||||
@@ -347,7 +360,7 @@ let showEcliptic = false;
|
|||||||
let playing = false;
|
let playing = false;
|
||||||
let speedDaysPerSecond = 1;
|
let speedDaysPerSecond = 1;
|
||||||
let focusedPlanetKey = null;
|
let focusedPlanetKey = null;
|
||||||
let selectedMinorPlanetId = null;
|
let selectedMinorPlanetIds = [];
|
||||||
let focusedMinorPlanetId = null;
|
let focusedMinorPlanetId = null;
|
||||||
let simDate = new Date();
|
let simDate = new Date();
|
||||||
let lastAnimationTime = performance.now();
|
let lastAnimationTime = performance.now();
|
||||||
@@ -453,6 +466,48 @@ function getMinorPlanetMeta(id) {
|
|||||||
return USER_MINOR_PLANETS.find((minorPlanet) => minorPlanet.id === Number(id)) || null;
|
return USER_MINOR_PLANETS.find((minorPlanet) => minorPlanet.id === Number(id)) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSelectedMinorPlanetSet() {
|
||||||
|
return new Set(selectedMinorPlanetIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MINOR_PLANET_COLOR_PALETTE = [
|
||||||
|
{ line: '#ff6b6b', body: '#ff5a5a', emissive: '#d63b3b' },
|
||||||
|
{ line: '#ff5252', body: '#ff4747', emissive: '#c62828' },
|
||||||
|
{ line: '#ff7a5c', body: '#ff6b4a', emissive: '#d9482c' },
|
||||||
|
{ line: '#ff4d6d', body: '#ff3f5f', emissive: '#c81f45' },
|
||||||
|
{ line: '#ff8a65', body: '#ff7043', emissive: '#d4512c' },
|
||||||
|
{ line: '#f0625d', body: '#eb554f', emissive: '#bf3c36' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function getMinorPlanetColor(id) {
|
||||||
|
const safeId = Math.abs(Number(id) || 0);
|
||||||
|
return MINOR_PLANET_COLOR_PALETTE[safeId % MINOR_PLANET_COLOR_PALETTE.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateMinorPlanetSummary() {
|
||||||
|
if (!minorPlanetSelectSummary) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minorPlanetCheckboxes.length === 0) {
|
||||||
|
minorPlanetSelectSummary.textContent = 'Keine Kleinplaneten verfuegbar';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedMinorPlanetIds.length === 0) {
|
||||||
|
minorPlanetSelectSummary.textContent = 'Kleinplaneten auswaehlen';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedNames = selectedMinorPlanetIds
|
||||||
|
.map((id) => formatMinorPlanetName(getMinorPlanetMeta(id)))
|
||||||
|
.filter((name) => name && name !== '--');
|
||||||
|
|
||||||
|
minorPlanetSelectSummary.textContent = selectedNames.length <= 2
|
||||||
|
? selectedNames.join(', ')
|
||||||
|
: `${selectedNames.length} Kleinplaneten ausgewaehlt`;
|
||||||
|
}
|
||||||
|
|
||||||
function formatMinorPlanetName(minorPlanet) {
|
function formatMinorPlanetName(minorPlanet) {
|
||||||
if (!minorPlanet) {
|
if (!minorPlanet) {
|
||||||
return '--';
|
return '--';
|
||||||
@@ -658,9 +713,10 @@ function updateMinorPlanetInfoPanel(id) {
|
|||||||
);
|
);
|
||||||
const apparentMagnitude = estimateMinorPlanetMagnitude(minorPlanet, position, earthPosition, earthDistanceAu);
|
const apparentMagnitude = estimateMinorPlanetMagnitude(minorPlanet, position, earthPosition, earthDistanceAu);
|
||||||
const periodDays = minorPlanet.meanMotionDegPerDay > 0 ? 360 / minorPlanet.meanMotionDegPerDay : null;
|
const periodDays = minorPlanet.meanMotionDegPerDay > 0 ? 360 / minorPlanet.meanMotionDegPerDay : null;
|
||||||
|
const color = getMinorPlanetColor(id);
|
||||||
infoPanel.hidden = false;
|
infoPanel.hidden = false;
|
||||||
document.getElementById('solarInfoName').textContent = formatMinorPlanetName(minorPlanet);
|
document.getElementById('solarInfoName').textContent = formatMinorPlanetName(minorPlanet);
|
||||||
document.getElementById('solarInfoName').style.color = '#ff2a2a';
|
document.getElementById('solarInfoName').style.color = color.line;
|
||||||
document.getElementById('solarInfoDistanceAu').textContent = `${position.r.toFixed(4)} AU`;
|
document.getElementById('solarInfoDistanceAu').textContent = `${position.r.toFixed(4)} AU`;
|
||||||
document.getElementById('solarInfoDistanceKm').textContent = `${(position.r * AU_IN_KM).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} km`;
|
document.getElementById('solarInfoDistanceKm').textContent = `${(position.r * AU_IN_KM).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} km`;
|
||||||
document.getElementById('solarInfoEarthDistanceAu').textContent = `${earthDistanceAu.toFixed(4)} AU`;
|
document.getElementById('solarInfoEarthDistanceAu').textContent = `${earthDistanceAu.toFixed(4)} AU`;
|
||||||
@@ -773,39 +829,86 @@ function updateMoonVisual() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ensureMinorPlanetObjects() {
|
function ensureMinorPlanetObjects() {
|
||||||
if (minorPlanetOrbitLine && minorPlanetMesh && minorPlanetLabelElement) {
|
if (!minorPlanetObjects) {
|
||||||
return;
|
minorPlanetObjects = new Map();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMinorPlanetObjects(id) {
|
||||||
|
ensureMinorPlanetObjects();
|
||||||
|
|
||||||
|
if (minorPlanetObjects.has(id)) {
|
||||||
|
return minorPlanetObjects.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const color = getMinorPlanetColor(id);
|
||||||
const lineMaterial = new THREE.LineBasicMaterial({
|
const lineMaterial = new THREE.LineBasicMaterial({
|
||||||
color: 0xff3333,
|
color: new THREE.Color(color.line),
|
||||||
transparent: true,
|
transparent: true,
|
||||||
opacity: 0.85
|
opacity: 0.85
|
||||||
});
|
});
|
||||||
minorPlanetOrbitLine = new THREE.Line(new THREE.BufferGeometry(), lineMaterial);
|
const orbitLine = new THREE.Line(new THREE.BufferGeometry(), lineMaterial);
|
||||||
minorPlanetOrbitLine.visible = false;
|
orbitLine.visible = false;
|
||||||
scene.add(minorPlanetOrbitLine);
|
scene.add(orbitLine);
|
||||||
|
|
||||||
minorPlanetMesh = new THREE.Mesh(
|
const mesh = new THREE.Mesh(
|
||||||
new THREE.SphereGeometry(0.58, 28, 28),
|
new THREE.SphereGeometry(0.58, 28, 28),
|
||||||
new THREE.MeshStandardMaterial({
|
new THREE.MeshStandardMaterial({
|
||||||
color: 0xff3030,
|
color: new THREE.Color(color.body),
|
||||||
emissive: new THREE.Color(0xcc0000),
|
emissive: new THREE.Color(color.emissive),
|
||||||
emissiveIntensity: 0.06,
|
emissiveIntensity: 0.06,
|
||||||
roughness: 0.65,
|
roughness: 0.65,
|
||||||
metalness: 0.08,
|
metalness: 0.08,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
minorPlanetMesh.visible = false;
|
mesh.visible = false;
|
||||||
minorPlanetMesh.userData.baseScale = 1;
|
mesh.userData.baseScale = 1;
|
||||||
minorPlanetMesh.userData.minScaleMultiplier = 1;
|
mesh.userData.minScaleMultiplier = 1;
|
||||||
scene.add(minorPlanetMesh);
|
mesh.userData.minorPlanetId = id;
|
||||||
|
scene.add(mesh);
|
||||||
|
|
||||||
minorPlanetLabelElement = document.createElement('div');
|
const labelElement = document.createElement('div');
|
||||||
minorPlanetLabelElement.className = 'solarsystem-planet-label';
|
labelElement.className = 'solarsystem-planet-label';
|
||||||
minorPlanetLabelElement.style.color = '#ff2a2a';
|
labelElement.style.color = color.line;
|
||||||
minorPlanetLabelElement.hidden = true;
|
labelElement.hidden = true;
|
||||||
labelsLayer.appendChild(minorPlanetLabelElement);
|
labelsLayer.appendChild(labelElement);
|
||||||
|
|
||||||
|
const objects = { orbitLine, mesh, labelElement };
|
||||||
|
minorPlanetObjects.set(id, objects);
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeMinorPlanetObjects(id) {
|
||||||
|
if (!minorPlanetObjects || !minorPlanetObjects.has(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { orbitLine, mesh, labelElement } = minorPlanetObjects.get(id);
|
||||||
|
orbitLine.geometry.dispose();
|
||||||
|
orbitLine.material.dispose();
|
||||||
|
scene.remove(orbitLine);
|
||||||
|
|
||||||
|
mesh.geometry.dispose();
|
||||||
|
mesh.material.dispose();
|
||||||
|
scene.remove(mesh);
|
||||||
|
|
||||||
|
labelElement.remove();
|
||||||
|
minorPlanetObjects.delete(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncMinorPlanetObjects() {
|
||||||
|
ensureMinorPlanetObjects();
|
||||||
|
|
||||||
|
const selectedSet = getSelectedMinorPlanetSet();
|
||||||
|
selectedMinorPlanetIds.forEach((id) => {
|
||||||
|
createMinorPlanetObjects(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.from(minorPlanetObjects.keys()).forEach((id) => {
|
||||||
|
if (!selectedSet.has(id)) {
|
||||||
|
removeMinorPlanetObjects(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeRadians(value) {
|
function normalizeRadians(value) {
|
||||||
@@ -890,13 +993,9 @@ function getMinorPlanetHelioPosition(minorPlanet, date) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function rebuildMinorPlanetOrbit(id) {
|
function rebuildMinorPlanetOrbit(id) {
|
||||||
ensureMinorPlanetObjects();
|
|
||||||
|
|
||||||
const minorPlanet = getMinorPlanetMeta(id);
|
const minorPlanet = getMinorPlanetMeta(id);
|
||||||
if (!minorPlanet) {
|
const objects = createMinorPlanetObjects(id);
|
||||||
minorPlanetOrbitLine.visible = false;
|
if (!minorPlanet || !objects) {
|
||||||
minorPlanetMesh.visible = false;
|
|
||||||
minorPlanetLabelElement.hidden = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -914,42 +1013,57 @@ function rebuildMinorPlanetOrbit(id) {
|
|||||||
positions.push(display.x, display.y, display.z);
|
positions.push(display.x, display.y, display.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
minorPlanetOrbitLine.geometry.dispose();
|
objects.orbitLine.geometry.dispose();
|
||||||
minorPlanetOrbitLine.geometry = new THREE.BufferGeometry();
|
objects.orbitLine.geometry = new THREE.BufferGeometry();
|
||||||
minorPlanetOrbitLine.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
|
objects.orbitLine.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
|
||||||
minorPlanetOrbitLine.visible = showOrbits;
|
objects.orbitLine.visible = showOrbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMinorPlanetVisual() {
|
function updateMinorPlanetVisual() {
|
||||||
ensureMinorPlanetObjects();
|
syncMinorPlanetObjects();
|
||||||
|
|
||||||
const minorPlanet = getMinorPlanetMeta(selectedMinorPlanetId);
|
if (!minorPlanetObjects || minorPlanetObjects.size === 0) {
|
||||||
if (!minorPlanet) {
|
|
||||||
minorPlanetOrbitLine.visible = false;
|
|
||||||
minorPlanetMesh.visible = false;
|
|
||||||
minorPlanetLabelElement.hidden = true;
|
|
||||||
if (!focusedPlanetKey) {
|
if (!focusedPlanetKey) {
|
||||||
infoPanel.hidden = true;
|
infoPanel.hidden = true;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const heliocentric = getMinorPlanetHelioPosition(minorPlanet, simDate);
|
const selectedSet = getSelectedMinorPlanetSet();
|
||||||
if (!heliocentric) {
|
minorPlanetObjects.forEach((objects, id) => {
|
||||||
minorPlanetOrbitLine.visible = false;
|
const minorPlanet = getMinorPlanetMeta(id);
|
||||||
minorPlanetMesh.visible = false;
|
const isSelected = selectedSet.has(id);
|
||||||
minorPlanetLabelElement.hidden = true;
|
if (!minorPlanet || !isSelected) {
|
||||||
return;
|
objects.orbitLine.visible = false;
|
||||||
}
|
objects.mesh.visible = false;
|
||||||
|
objects.labelElement.hidden = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const display = toDisplayPosition(heliocentric);
|
const heliocentric = getMinorPlanetHelioPosition(minorPlanet, simDate);
|
||||||
minorPlanetMesh.visible = true;
|
if (!heliocentric) {
|
||||||
minorPlanetMesh.position.copy(display);
|
objects.orbitLine.visible = false;
|
||||||
minorPlanetMesh.rotation.y = (simDate.getTime() / 1000) * 0.0002;
|
objects.mesh.visible = false;
|
||||||
minorPlanetOrbitLine.visible = showOrbits;
|
objects.labelElement.hidden = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (focusedMinorPlanetId === selectedMinorPlanetId) {
|
const display = toDisplayPosition(heliocentric);
|
||||||
updateMinorPlanetInfoPanel(selectedMinorPlanetId);
|
objects.mesh.visible = true;
|
||||||
|
objects.mesh.position.copy(display);
|
||||||
|
objects.mesh.rotation.y = (simDate.getTime() / 1000) * 0.0002;
|
||||||
|
objects.orbitLine.visible = showOrbits;
|
||||||
|
|
||||||
|
if (focusedMinorPlanetId === id) {
|
||||||
|
updateMinorPlanetInfoPanel(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (focusedMinorPlanetId !== null && !selectedSet.has(focusedMinorPlanetId)) {
|
||||||
|
focusedMinorPlanetId = null;
|
||||||
|
if (!focusedPlanetKey) {
|
||||||
|
infoPanel.hidden = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1150,8 +1264,12 @@ function updateBodyDisplayScales() {
|
|||||||
applyMinimumDisplayScale(moonMesh, 220, 10);
|
applyMinimumDisplayScale(moonMesh, 220, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minorPlanetMesh && minorPlanetMesh.visible) {
|
if (minorPlanetObjects) {
|
||||||
applyMinimumDisplayScale(minorPlanetMesh, 220, 10);
|
minorPlanetObjects.forEach(({ mesh }) => {
|
||||||
|
if (mesh.visible) {
|
||||||
|
applyMinimumDisplayScale(mesh, 220, 10);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1193,26 +1311,28 @@ function updateLabels() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!minorPlanetLabelElement || !minorPlanetMesh) {
|
if (!minorPlanetObjects) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const minorPlanet = getMinorPlanetMeta(selectedMinorPlanetId);
|
minorPlanetObjects.forEach(({ mesh, labelElement }, id) => {
|
||||||
minorPlanetLabelElement.hidden = !showLabels || !minorPlanet || !minorPlanetMesh.visible;
|
const minorPlanet = getMinorPlanetMeta(id);
|
||||||
if (minorPlanetLabelElement.hidden) {
|
labelElement.hidden = !showLabels || !minorPlanet || !mesh.visible;
|
||||||
return;
|
if (labelElement.hidden) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const projected = minorPlanetMesh.position.clone().project(camera);
|
const projected = mesh.position.clone().project(camera);
|
||||||
if (projected.z > 1) {
|
if (projected.z > 1) {
|
||||||
minorPlanetLabelElement.style.opacity = '0';
|
labelElement.style.opacity = '0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
minorPlanetLabelElement.textContent = formatMinorPlanetName(minorPlanet);
|
labelElement.textContent = formatMinorPlanetName(minorPlanet);
|
||||||
minorPlanetLabelElement.style.opacity = '1';
|
labelElement.style.opacity = '1';
|
||||||
minorPlanetLabelElement.style.left = `${(projected.x * 0.5 + 0.5) * stageWrap.clientWidth}px`;
|
labelElement.style.left = `${(projected.x * 0.5 + 0.5) * stageWrap.clientWidth}px`;
|
||||||
minorPlanetLabelElement.style.top = `${(-projected.y * 0.5 + 0.5) * stageWrap.clientHeight}px`;
|
labelElement.style.top = `${(-projected.y * 0.5 + 0.5) * stageWrap.clientHeight}px`;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickPlanet(clientX, clientY) {
|
function pickPlanet(clientX, clientY) {
|
||||||
@@ -1230,13 +1350,20 @@ function pickPlanet(clientX, clientY) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const hits = raycaster.intersectObjects(meshes.map((item) => item.mesh), false);
|
const hits = raycaster.intersectObjects(meshes.map((item) => item.mesh), false);
|
||||||
if (minorPlanetMesh && minorPlanetMesh.visible) {
|
if (minorPlanetObjects) {
|
||||||
const minorPlanetHits = raycaster.intersectObject(minorPlanetMesh, false);
|
const visibleMinorPlanetMeshes = Array.from(minorPlanetObjects.entries())
|
||||||
if (minorPlanetHits.length > 0 && selectedMinorPlanetId) {
|
.filter(([, objects]) => objects.mesh.visible)
|
||||||
focusedPlanetKey = null;
|
.map(([id, objects]) => ({ id, mesh: objects.mesh }));
|
||||||
focusedMinorPlanetId = selectedMinorPlanetId;
|
|
||||||
updateMinorPlanetInfoPanel(selectedMinorPlanetId);
|
const minorPlanetHits = raycaster.intersectObjects(visibleMinorPlanetMeshes.map((item) => item.mesh), false);
|
||||||
return;
|
if (minorPlanetHits.length > 0) {
|
||||||
|
const hitItem = visibleMinorPlanetMeshes.find((item) => item.mesh === minorPlanetHits[0].object);
|
||||||
|
if (hitItem) {
|
||||||
|
focusedPlanetKey = null;
|
||||||
|
focusedMinorPlanetId = hitItem.id;
|
||||||
|
updateMinorPlanetInfoPanel(hitItem.id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1336,8 +1463,10 @@ function attachUiHandlers() {
|
|||||||
orbitLines.forEach((line) => {
|
orbitLines.forEach((line) => {
|
||||||
line.visible = showOrbits;
|
line.visible = showOrbits;
|
||||||
});
|
});
|
||||||
if (minorPlanetOrbitLine) {
|
if (minorPlanetObjects) {
|
||||||
minorPlanetOrbitLine.visible = showOrbits && !!getMinorPlanetMeta(selectedMinorPlanetId);
|
minorPlanetObjects.forEach(({ orbitLine }) => {
|
||||||
|
orbitLine.visible = showOrbits;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (moonOrbitLine) {
|
if (moonOrbitLine) {
|
||||||
moonOrbitLine.visible = showOrbits;
|
moonOrbitLine.visible = showOrbits;
|
||||||
@@ -1372,16 +1501,27 @@ function attachUiHandlers() {
|
|||||||
refreshCurrentDateUi();
|
refreshCurrentDateUi();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (minorPlanetSelect) {
|
minorPlanetCheckboxes.forEach((checkbox) => {
|
||||||
minorPlanetSelect.addEventListener('change', () => {
|
checkbox.addEventListener('change', () => {
|
||||||
selectedMinorPlanetId = minorPlanetSelect.value ? Number(minorPlanetSelect.value) : null;
|
selectedMinorPlanetIds = minorPlanetCheckboxes
|
||||||
focusedMinorPlanetId = null;
|
.filter((input) => input.checked)
|
||||||
rebuildMinorPlanetOrbit(selectedMinorPlanetId);
|
.map((input) => Number(input.value));
|
||||||
if (!selectedMinorPlanetId && !focusedPlanetKey) {
|
|
||||||
|
if (focusedMinorPlanetId !== null && !selectedMinorPlanetIds.includes(focusedMinorPlanetId)) {
|
||||||
|
focusedMinorPlanetId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncMinorPlanetObjects();
|
||||||
|
selectedMinorPlanetIds.forEach((id) => {
|
||||||
|
rebuildMinorPlanetOrbit(id);
|
||||||
|
});
|
||||||
|
updateMinorPlanetSummary();
|
||||||
|
|
||||||
|
if (selectedMinorPlanetIds.length === 0 && !focusedPlanetKey && focusedMinorPlanetId === null) {
|
||||||
infoPanel.hidden = true;
|
infoPanel.hidden = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function animate() {
|
function animate() {
|
||||||
@@ -1419,9 +1559,12 @@ function animate() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focusedMinorPlanetId && minorPlanetMesh && minorPlanetMesh.visible) {
|
if (focusedMinorPlanetId && minorPlanetObjects && minorPlanetObjects.has(focusedMinorPlanetId)) {
|
||||||
cameraTarget.lerp(minorPlanetMesh.position, 0.06);
|
const focusedMinorPlanetObjects = minorPlanetObjects.get(focusedMinorPlanetId);
|
||||||
updateMinorPlanetInfoPanel(focusedMinorPlanetId);
|
if (focusedMinorPlanetObjects.mesh.visible) {
|
||||||
|
cameraTarget.lerp(focusedMinorPlanetObjects.mesh.position, 0.06);
|
||||||
|
updateMinorPlanetInfoPanel(focusedMinorPlanetId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
camRadius += (camRadiusTarget - camRadius) * 0.18;
|
camRadius += (camRadiusTarget - camRadius) * 0.18;
|
||||||
@@ -1461,6 +1604,7 @@ async function initSolarSystem() {
|
|||||||
pointer = new THREE.Vector2();
|
pointer = new THREE.Vector2();
|
||||||
cameraTarget = new THREE.Vector3(0, 0, 0);
|
cameraTarget = new THREE.Vector3(0, 0, 0);
|
||||||
rotationEqjToEcl = AstronomyEngine.Rotation_EQJ_ECL();
|
rotationEqjToEcl = AstronomyEngine.Rotation_EQJ_ECL();
|
||||||
|
updateMinorPlanetSummary();
|
||||||
|
|
||||||
const ambientLight = new THREE.AmbientLight(0x334466, 0.8);
|
const ambientLight = new THREE.AmbientLight(0x334466, 0.8);
|
||||||
scene.add(ambientLight);
|
scene.add(ambientLight);
|
||||||
|
|||||||
Reference in New Issue
Block a user