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 select {
|
||||
.solarsystem-input-row select,
|
||||
.solarsystem-multiselect {
|
||||
min-height: 2.6rem;
|
||||
padding: 0.55rem 0.8rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid rgba(200, 168, 75, 0.14);
|
||||
background: rgba(10, 16, 36, 0.8);
|
||||
@@ -3843,6 +3843,11 @@ body.solarsystem-page main > .container {
|
||||
flex: 1 1 170px;
|
||||
}
|
||||
|
||||
.solarsystem-input-row input[type="date"],
|
||||
.solarsystem-input-row select {
|
||||
padding: 0.55rem 0.8rem;
|
||||
}
|
||||
|
||||
.solarsystem-input-row select {
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
@@ -3882,6 +3887,102 @@ body.solarsystem-page main > .container {
|
||||
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-speed-value {
|
||||
color: var(--gold-pale);
|
||||
|
||||
+242
-98
@@ -194,15 +194,28 @@ $bodyClass = 'solarsystem-page';
|
||||
<div class="solarsystem-sidebar-block">
|
||||
<div class="solarsystem-label">Kleinplanet</div>
|
||||
<div class="solarsystem-input-row">
|
||||
<select id="solarMinorplanetSelect"<?= empty($trackedMinorplanetsForJs) ? ' disabled' : '' ?>>
|
||||
<option value=""><?= empty($trackedMinorplanetsForJs) ? 'Keine Kleinplaneten ausgewaehlt' : 'Kein Kleinplanet' ?></option>
|
||||
<?php foreach ($trackedMinorplanetsForJs as $minorplanet): ?>
|
||||
<option value="<?= (int) $minorplanet['id'] ?>"><?= h(formatMinorplanetDisplayName($minorplanet)) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<details class="solarsystem-multiselect<?= empty($trackedMinorplanetsForJs) ? ' is-disabled' : '' ?>" id="solarMinorplanetSelectWrap"<?= empty($trackedMinorplanetsForJs) ? ' open' : '' ?>>
|
||||
<summary id="solarMinorplanetSelectSummary">
|
||||
<?= empty($trackedMinorplanetsForJs) ? 'Keine Kleinplaneten verfuegbar' : 'Kleinplaneten auswaehlen' ?>
|
||||
</summary>
|
||||
<div class="solarsystem-multiselect-panel" id="solarMinorplanetSelectPanel">
|
||||
<?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 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>
|
||||
|
||||
@@ -212,7 +225,7 @@ $bodyClass = 'solarsystem-page';
|
||||
<li>Maus ziehen: Kamera drehen</li>
|
||||
<li>Mausrad: Zoom</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>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -314,7 +327,9 @@ const btnEcliptic = document.getElementById('solarBtnEcliptic');
|
||||
const speedSlider = document.getElementById('solarSpeedSlider');
|
||||
const speedLabel = document.getElementById('solarSpeedLabel');
|
||||
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) {
|
||||
overlay.textContent = 'Astronomy Engine konnte nicht geladen werden.';
|
||||
@@ -336,9 +351,7 @@ let rotationEqjToEcl;
|
||||
let moonMesh = null;
|
||||
let moonOrbitLine = null;
|
||||
let moonLabelElement = null;
|
||||
let minorPlanetOrbitLine = null;
|
||||
let minorPlanetMesh = null;
|
||||
let minorPlanetLabelElement = null;
|
||||
let minorPlanetObjects = null;
|
||||
const planetDynamicsCache = new Map();
|
||||
|
||||
let showOrbits = true;
|
||||
@@ -347,7 +360,7 @@ let showEcliptic = false;
|
||||
let playing = false;
|
||||
let speedDaysPerSecond = 1;
|
||||
let focusedPlanetKey = null;
|
||||
let selectedMinorPlanetId = null;
|
||||
let selectedMinorPlanetIds = [];
|
||||
let focusedMinorPlanetId = null;
|
||||
let simDate = new Date();
|
||||
let lastAnimationTime = performance.now();
|
||||
@@ -453,6 +466,48 @@ function getMinorPlanetMeta(id) {
|
||||
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) {
|
||||
if (!minorPlanet) {
|
||||
return '--';
|
||||
@@ -658,9 +713,10 @@ function updateMinorPlanetInfoPanel(id) {
|
||||
);
|
||||
const apparentMagnitude = estimateMinorPlanetMagnitude(minorPlanet, position, earthPosition, earthDistanceAu);
|
||||
const periodDays = minorPlanet.meanMotionDegPerDay > 0 ? 360 / minorPlanet.meanMotionDegPerDay : null;
|
||||
const color = getMinorPlanetColor(id);
|
||||
infoPanel.hidden = false;
|
||||
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('solarInfoDistanceKm').textContent = `${(position.r * AU_IN_KM).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.')} km`;
|
||||
document.getElementById('solarInfoEarthDistanceAu').textContent = `${earthDistanceAu.toFixed(4)} AU`;
|
||||
@@ -773,39 +829,86 @@ function updateMoonVisual() {
|
||||
}
|
||||
|
||||
function ensureMinorPlanetObjects() {
|
||||
if (minorPlanetOrbitLine && minorPlanetMesh && minorPlanetLabelElement) {
|
||||
return;
|
||||
if (!minorPlanetObjects) {
|
||||
minorPlanetObjects = new Map();
|
||||
}
|
||||
}
|
||||
|
||||
function createMinorPlanetObjects(id) {
|
||||
ensureMinorPlanetObjects();
|
||||
|
||||
if (minorPlanetObjects.has(id)) {
|
||||
return minorPlanetObjects.get(id);
|
||||
}
|
||||
|
||||
const color = getMinorPlanetColor(id);
|
||||
const lineMaterial = new THREE.LineBasicMaterial({
|
||||
color: 0xff3333,
|
||||
color: new THREE.Color(color.line),
|
||||
transparent: true,
|
||||
opacity: 0.85
|
||||
});
|
||||
minorPlanetOrbitLine = new THREE.Line(new THREE.BufferGeometry(), lineMaterial);
|
||||
minorPlanetOrbitLine.visible = false;
|
||||
scene.add(minorPlanetOrbitLine);
|
||||
const orbitLine = new THREE.Line(new THREE.BufferGeometry(), lineMaterial);
|
||||
orbitLine.visible = false;
|
||||
scene.add(orbitLine);
|
||||
|
||||
minorPlanetMesh = new THREE.Mesh(
|
||||
const mesh = new THREE.Mesh(
|
||||
new THREE.SphereGeometry(0.58, 28, 28),
|
||||
new THREE.MeshStandardMaterial({
|
||||
color: 0xff3030,
|
||||
emissive: new THREE.Color(0xcc0000),
|
||||
color: new THREE.Color(color.body),
|
||||
emissive: new THREE.Color(color.emissive),
|
||||
emissiveIntensity: 0.06,
|
||||
roughness: 0.65,
|
||||
metalness: 0.08,
|
||||
})
|
||||
);
|
||||
minorPlanetMesh.visible = false;
|
||||
minorPlanetMesh.userData.baseScale = 1;
|
||||
minorPlanetMesh.userData.minScaleMultiplier = 1;
|
||||
scene.add(minorPlanetMesh);
|
||||
mesh.visible = false;
|
||||
mesh.userData.baseScale = 1;
|
||||
mesh.userData.minScaleMultiplier = 1;
|
||||
mesh.userData.minorPlanetId = id;
|
||||
scene.add(mesh);
|
||||
|
||||
minorPlanetLabelElement = document.createElement('div');
|
||||
minorPlanetLabelElement.className = 'solarsystem-planet-label';
|
||||
minorPlanetLabelElement.style.color = '#ff2a2a';
|
||||
minorPlanetLabelElement.hidden = true;
|
||||
labelsLayer.appendChild(minorPlanetLabelElement);
|
||||
const labelElement = document.createElement('div');
|
||||
labelElement.className = 'solarsystem-planet-label';
|
||||
labelElement.style.color = color.line;
|
||||
labelElement.hidden = true;
|
||||
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) {
|
||||
@@ -890,13 +993,9 @@ function getMinorPlanetHelioPosition(minorPlanet, date) {
|
||||
}
|
||||
|
||||
function rebuildMinorPlanetOrbit(id) {
|
||||
ensureMinorPlanetObjects();
|
||||
|
||||
const minorPlanet = getMinorPlanetMeta(id);
|
||||
if (!minorPlanet) {
|
||||
minorPlanetOrbitLine.visible = false;
|
||||
minorPlanetMesh.visible = false;
|
||||
minorPlanetLabelElement.hidden = true;
|
||||
const objects = createMinorPlanetObjects(id);
|
||||
if (!minorPlanet || !objects) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -914,42 +1013,57 @@ function rebuildMinorPlanetOrbit(id) {
|
||||
positions.push(display.x, display.y, display.z);
|
||||
}
|
||||
|
||||
minorPlanetOrbitLine.geometry.dispose();
|
||||
minorPlanetOrbitLine.geometry = new THREE.BufferGeometry();
|
||||
minorPlanetOrbitLine.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
|
||||
minorPlanetOrbitLine.visible = showOrbits;
|
||||
objects.orbitLine.geometry.dispose();
|
||||
objects.orbitLine.geometry = new THREE.BufferGeometry();
|
||||
objects.orbitLine.geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
|
||||
objects.orbitLine.visible = showOrbits;
|
||||
}
|
||||
|
||||
function updateMinorPlanetVisual() {
|
||||
ensureMinorPlanetObjects();
|
||||
syncMinorPlanetObjects();
|
||||
|
||||
const minorPlanet = getMinorPlanetMeta(selectedMinorPlanetId);
|
||||
if (!minorPlanet) {
|
||||
minorPlanetOrbitLine.visible = false;
|
||||
minorPlanetMesh.visible = false;
|
||||
minorPlanetLabelElement.hidden = true;
|
||||
if (!minorPlanetObjects || minorPlanetObjects.size === 0) {
|
||||
if (!focusedPlanetKey) {
|
||||
infoPanel.hidden = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const heliocentric = getMinorPlanetHelioPosition(minorPlanet, simDate);
|
||||
if (!heliocentric) {
|
||||
minorPlanetOrbitLine.visible = false;
|
||||
minorPlanetMesh.visible = false;
|
||||
minorPlanetLabelElement.hidden = true;
|
||||
return;
|
||||
}
|
||||
const selectedSet = getSelectedMinorPlanetSet();
|
||||
minorPlanetObjects.forEach((objects, id) => {
|
||||
const minorPlanet = getMinorPlanetMeta(id);
|
||||
const isSelected = selectedSet.has(id);
|
||||
if (!minorPlanet || !isSelected) {
|
||||
objects.orbitLine.visible = false;
|
||||
objects.mesh.visible = false;
|
||||
objects.labelElement.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const display = toDisplayPosition(heliocentric);
|
||||
minorPlanetMesh.visible = true;
|
||||
minorPlanetMesh.position.copy(display);
|
||||
minorPlanetMesh.rotation.y = (simDate.getTime() / 1000) * 0.0002;
|
||||
minorPlanetOrbitLine.visible = showOrbits;
|
||||
const heliocentric = getMinorPlanetHelioPosition(minorPlanet, simDate);
|
||||
if (!heliocentric) {
|
||||
objects.orbitLine.visible = false;
|
||||
objects.mesh.visible = false;
|
||||
objects.labelElement.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (focusedMinorPlanetId === selectedMinorPlanetId) {
|
||||
updateMinorPlanetInfoPanel(selectedMinorPlanetId);
|
||||
const display = toDisplayPosition(heliocentric);
|
||||
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);
|
||||
}
|
||||
|
||||
if (minorPlanetMesh && minorPlanetMesh.visible) {
|
||||
applyMinimumDisplayScale(minorPlanetMesh, 220, 10);
|
||||
if (minorPlanetObjects) {
|
||||
minorPlanetObjects.forEach(({ mesh }) => {
|
||||
if (mesh.visible) {
|
||||
applyMinimumDisplayScale(mesh, 220, 10);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1193,26 +1311,28 @@ function updateLabels() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!minorPlanetLabelElement || !minorPlanetMesh) {
|
||||
if (!minorPlanetObjects) {
|
||||
return;
|
||||
}
|
||||
|
||||
const minorPlanet = getMinorPlanetMeta(selectedMinorPlanetId);
|
||||
minorPlanetLabelElement.hidden = !showLabels || !minorPlanet || !minorPlanetMesh.visible;
|
||||
if (minorPlanetLabelElement.hidden) {
|
||||
return;
|
||||
}
|
||||
minorPlanetObjects.forEach(({ mesh, labelElement }, id) => {
|
||||
const minorPlanet = getMinorPlanetMeta(id);
|
||||
labelElement.hidden = !showLabels || !minorPlanet || !mesh.visible;
|
||||
if (labelElement.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
const projected = minorPlanetMesh.position.clone().project(camera);
|
||||
if (projected.z > 1) {
|
||||
minorPlanetLabelElement.style.opacity = '0';
|
||||
return;
|
||||
}
|
||||
const projected = mesh.position.clone().project(camera);
|
||||
if (projected.z > 1) {
|
||||
labelElement.style.opacity = '0';
|
||||
return;
|
||||
}
|
||||
|
||||
minorPlanetLabelElement.textContent = formatMinorPlanetName(minorPlanet);
|
||||
minorPlanetLabelElement.style.opacity = '1';
|
||||
minorPlanetLabelElement.style.left = `${(projected.x * 0.5 + 0.5) * stageWrap.clientWidth}px`;
|
||||
minorPlanetLabelElement.style.top = `${(-projected.y * 0.5 + 0.5) * stageWrap.clientHeight}px`;
|
||||
labelElement.textContent = formatMinorPlanetName(minorPlanet);
|
||||
labelElement.style.opacity = '1';
|
||||
labelElement.style.left = `${(projected.x * 0.5 + 0.5) * stageWrap.clientWidth}px`;
|
||||
labelElement.style.top = `${(-projected.y * 0.5 + 0.5) * stageWrap.clientHeight}px`;
|
||||
});
|
||||
}
|
||||
|
||||
function pickPlanet(clientX, clientY) {
|
||||
@@ -1230,13 +1350,20 @@ function pickPlanet(clientX, clientY) {
|
||||
});
|
||||
|
||||
const hits = raycaster.intersectObjects(meshes.map((item) => item.mesh), false);
|
||||
if (minorPlanetMesh && minorPlanetMesh.visible) {
|
||||
const minorPlanetHits = raycaster.intersectObject(minorPlanetMesh, false);
|
||||
if (minorPlanetHits.length > 0 && selectedMinorPlanetId) {
|
||||
focusedPlanetKey = null;
|
||||
focusedMinorPlanetId = selectedMinorPlanetId;
|
||||
updateMinorPlanetInfoPanel(selectedMinorPlanetId);
|
||||
return;
|
||||
if (minorPlanetObjects) {
|
||||
const visibleMinorPlanetMeshes = Array.from(minorPlanetObjects.entries())
|
||||
.filter(([, objects]) => objects.mesh.visible)
|
||||
.map(([id, objects]) => ({ id, mesh: objects.mesh }));
|
||||
|
||||
const minorPlanetHits = raycaster.intersectObjects(visibleMinorPlanetMeshes.map((item) => item.mesh), false);
|
||||
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) => {
|
||||
line.visible = showOrbits;
|
||||
});
|
||||
if (minorPlanetOrbitLine) {
|
||||
minorPlanetOrbitLine.visible = showOrbits && !!getMinorPlanetMeta(selectedMinorPlanetId);
|
||||
if (minorPlanetObjects) {
|
||||
minorPlanetObjects.forEach(({ orbitLine }) => {
|
||||
orbitLine.visible = showOrbits;
|
||||
});
|
||||
}
|
||||
if (moonOrbitLine) {
|
||||
moonOrbitLine.visible = showOrbits;
|
||||
@@ -1372,16 +1501,27 @@ function attachUiHandlers() {
|
||||
refreshCurrentDateUi();
|
||||
});
|
||||
|
||||
if (minorPlanetSelect) {
|
||||
minorPlanetSelect.addEventListener('change', () => {
|
||||
selectedMinorPlanetId = minorPlanetSelect.value ? Number(minorPlanetSelect.value) : null;
|
||||
focusedMinorPlanetId = null;
|
||||
rebuildMinorPlanetOrbit(selectedMinorPlanetId);
|
||||
if (!selectedMinorPlanetId && !focusedPlanetKey) {
|
||||
minorPlanetCheckboxes.forEach((checkbox) => {
|
||||
checkbox.addEventListener('change', () => {
|
||||
selectedMinorPlanetIds = minorPlanetCheckboxes
|
||||
.filter((input) => input.checked)
|
||||
.map((input) => Number(input.value));
|
||||
|
||||
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;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function animate() {
|
||||
@@ -1419,9 +1559,12 @@ function animate() {
|
||||
}
|
||||
}
|
||||
|
||||
if (focusedMinorPlanetId && minorPlanetMesh && minorPlanetMesh.visible) {
|
||||
cameraTarget.lerp(minorPlanetMesh.position, 0.06);
|
||||
updateMinorPlanetInfoPanel(focusedMinorPlanetId);
|
||||
if (focusedMinorPlanetId && minorPlanetObjects && minorPlanetObjects.has(focusedMinorPlanetId)) {
|
||||
const focusedMinorPlanetObjects = minorPlanetObjects.get(focusedMinorPlanetId);
|
||||
if (focusedMinorPlanetObjects.mesh.visible) {
|
||||
cameraTarget.lerp(focusedMinorPlanetObjects.mesh.position, 0.06);
|
||||
updateMinorPlanetInfoPanel(focusedMinorPlanetId);
|
||||
}
|
||||
}
|
||||
|
||||
camRadius += (camRadiusTarget - camRadius) * 0.18;
|
||||
@@ -1461,6 +1604,7 @@ async function initSolarSystem() {
|
||||
pointer = new THREE.Vector2();
|
||||
cameraTarget = new THREE.Vector3(0, 0, 0);
|
||||
rotationEqjToEcl = AstronomyEngine.Rotation_EQJ_ECL();
|
||||
updateMinorPlanetSummary();
|
||||
|
||||
const ambientLight = new THREE.AmbientLight(0x334466, 0.8);
|
||||
scene.add(ambientLight);
|
||||
|
||||
Reference in New Issue
Block a user