Erweitere Sonnenfinsternis-Steuerung und Zeitanzeige

This commit is contained in:
2026-08-19 10:44:15 +02:00
parent 2bf6c504b5
commit bee9bd1ef4
2 changed files with 122 additions and 21 deletions
+4
View File
@@ -4930,6 +4930,10 @@ body.solarsystem-page:not(.jupitersystem-page) .solarsystem-stage-wrap {
pointer-events: none;
}
.eclipse-stage-time-solar {
bottom: calc(5.4rem - 5px);
}
/* View toggle */
.eclipse-view-toggle {
position: absolute;
+118 -21
View File
@@ -57,6 +57,40 @@ $userAlt = isset($currentLocation['elevation']) ? (float)$currentLocation['eleva
</div>
</div>
<div class="solarsystem-sidebar-block">
<div class="solarsystem-label">Steuerung</div>
<div class="eclipse-sidebar-controls">
<div class="eclipse-sidebar-buttons">
<button class="btn btn-sm btn-secondary" id="eclipseBtnRewind" title="Zum Anfang">⏮</button>
<button class="btn btn-sm btn-primary" id="eclipseBtnPlay" title="Play/Pause">▶ Play</button>
<button class="btn btn-sm btn-secondary" id="eclipseBtnEnd" title="Zum Ende">⏭</button>
</div>
<div class="eclipse-time-display" id="eclipseTimeDisplay">– – : – – UTC</div>
<label class="eclipse-speed-label eclipse-speed-label-sidebar">
<span class="solarsystem-label">Geschw.</span>
<select id="eclipseSpeedSel" class="eclipse-speed-sel">
<option value="1">×1</option>
<option value="3">×3</option>
<option value="10" selected>×10</option>
<option value="30">×30</option>
<option value="60">×60</option>
</select>
</label>
</div>
</div>
<div class="solarsystem-sidebar-block">
<div class="solarsystem-label">Zeitformat</div>
<label class="form-checkbox" for="eclipseUseLocalTime">
<input type="checkbox" id="eclipseUseLocalTime">
<span>Lokale Zeit statt UTC anzeigen</span>
</label>
<label class="form-checkbox" for="eclipseShowStageTime">
<input type="checkbox" id="eclipseShowStageTime">
<span>Uhrzeit mittig in der Grafik anzeigen</span>
</label>
</div>
<div class="solarsystem-sidebar-block">
<div class="solarsystem-label">Schatten-Skalierung</div>
<label class="solarsystem-label eclipse-control-label" for="umbraScaleRange">
@@ -70,7 +104,7 @@ $userAlt = isset($currentLocation['elevation']) ? (float)$currentLocation['eleva
</div>
<div class="solarsystem-sidebar-block is-hidden" id="eclipseDataBlock">
<div class="solarsystem-label">Kontaktzeiten (UTC)</div>
<div class="solarsystem-label">Kontaktzeiten (<span id="eclipseTimeZoneLabel">UTC</span>)</div>
<table class="data-table" id="eclipseContactTable"></table>
</div>
@@ -100,31 +134,31 @@ $userAlt = isset($currentLocation['elevation']) ? (float)$currentLocation['eleva
<div id="eclipseLocalHint" class="eclipse-local-hint"></div>
<div id="eclipseScaleNote" class="eclipse-scale-note">
Distanzen stark komprimiert<br>Größenverhältnisse für die Anschauung angepasst
</div>
<div class="solarsystem-info-panel eclipse-info-panel" id="eclipseInfoPanel">
<button type="button" class="eclipse-info-toggle" id="eclipseInfoToggle" aria-expanded="true" aria-controls="eclipseInfoBody" title="Ein-/Ausklappen">
<span class="eclipse-info-toggle-icon">▾</span>
<span class="sr-only">Infokasten ein- oder ausklappen</span>
</button>
<div class="eclipse-info-body" id="eclipseInfoBody">
<div class="eclipse-info-empty">Wähle eine Finsternis aus der Liste</div>
<div class="eclipse-info-scale-note">Distanzen stark komprimiert, Größenverhältnisse für die Anschauung angepasst</div>
</div>
</div>
<div class="eclipse-stage-time eclipse-stage-time-solar is-hidden" id="eclipseStageTime">– – : – – UTC</div>
<div class="eclipse-timeline" id="eclipseTimeline">
<div class="eclipse-timeline-bar" id="eclipseTimelineBar">
<div class="eclipse-tl-cursor" id="eclipseTimelineCursor"></div>
</div>
<div class="eclipse-timeline-controls">
<button class="btn btn-sm btn-secondary" id="eclipseBtnRewind" title="Zum Anfang">⏮</button>
<button class="btn btn-sm btn-primary" id="eclipseBtnPlay" title="Play/Pause">▶ Play</button>
<button class="btn btn-sm btn-secondary" id="eclipseBtnEnd" title="Zum Ende">⏭</button>
<span class="eclipse-time-display" id="eclipseTimeDisplay">– – : – – UTC</span>
<div class="eclipse-timeline-controls is-hidden" aria-hidden="true">
<button class="btn btn-sm btn-secondary" id="eclipseBtnRewindLegacy" title="Zum Anfang">⏮</button>
<button class="btn btn-sm btn-primary" id="eclipseBtnPlayLegacy" title="Play/Pause">▶ Play</button>
<button class="btn btn-sm btn-secondary" id="eclipseBtnEndLegacy" title="Zum Ende">⏭</button>
<span class="eclipse-time-display" id="eclipseTimeDisplayLegacy">– – : – – UTC</span>
<label class="eclipse-speed-label">
<span class="solarsystem-label">Geschw.</span>
<select id="eclipseSpeedSel" class="eclipse-speed-sel">
<select id="eclipseSpeedSelLegacy" class="eclipse-speed-sel">
<option value="1">×1</option>
<option value="3">×3</option>
<option value="10" selected>×10</option>
@@ -183,6 +217,10 @@ const infoToggleBtn = document.getElementById('eclipseInfoToggle');
const timelineBar = document.getElementById('eclipseTimelineBar');
const tlCursor = document.getElementById('eclipseTimelineCursor');
const tlDisplay = document.getElementById('eclipseTimeDisplay');
const useLocalTimeEl = document.getElementById('eclipseUseLocalTime');
const showStageTimeEl = document.getElementById('eclipseShowStageTime');
const timeZoneLabelEl = document.getElementById('eclipseTimeZoneLabel');
const stageTimeEl = document.getElementById('eclipseStageTime');
const eclipseListEl = document.getElementById('eclipseList');
const dataBlock = document.getElementById('eclipseDataBlock');
const contactTable = document.getElementById('eclipseContactTable');
@@ -207,6 +245,9 @@ let simTime = 0;
let playing = false;
let playSpeed = 10;
let lastRAF = 0;
let infoPanelCollapsed = false;
let useLocalTime = false;
let showStageTime = false;
let simPartialHalf = 95;
let simCentralHalf = 0;
let simTrackB = 0;
@@ -1396,7 +1437,7 @@ function updateSim() {
const peakDate = eventPeakDate();
const cur = new Date(peakDate.getTime() + simTime * 60000);
tlDisplay.textContent = cur.toISOString().slice(11, 16) + ' UTC';
tlDisplay.textContent = formatTime(cur, { withSeconds: false });
updateInfoPhase(cov);
@@ -1428,15 +1469,49 @@ function renderLoop(now) {
if (viewMode === 'space') renderer.render(scene, camera);
}
function fmtUTC(date) {
return date.toISOString().slice(11, 19) + ' UTC';
function timeZoneSuffix() {
return useLocalTime ? 'Uhr' : 'UTC';
}
function formatDate(date, options) {
const settings = useLocalTime ? {} : { timeZone: 'UTC' };
return date.toLocaleDateString('de-DE', { ...options, ...settings });
}
function formatTime(date, { withSeconds = true } = {}) {
const settings = {
hour: '2-digit',
minute: '2-digit',
...(withSeconds ? { second: '2-digit' } : {}),
hour12: false,
...(useLocalTime ? {} : { timeZone: 'UTC' }),
};
return `${date.toLocaleTimeString('de-DE', settings)} ${timeZoneSuffix()}`;
}
function refreshTimeDisplays() {
timeZoneLabelEl.textContent = timeZoneSuffix();
if (!currentEclipse) {
tlDisplay.textContent = `– – : – – ${timeZoneSuffix()}`;
return;
}
renderInfo();
renderContactTable();
updateSim();
}
function setInfoPanelCollapsed(collapsed) {
infoPanelCollapsed = collapsed;
infoPanel.classList.toggle('is-collapsed', collapsed);
infoToggleBtn.setAttribute('aria-expanded', String(!collapsed));
infoToggleBtn.title = collapsed ? 'Infokasten aufklappen' : 'Infokasten zuklappen';
}
function renderInfo() {
const ec = currentEclipse;
const d = ec.peak.date;
const ds = d.toLocaleDateString('de-DE', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
const ts = fmtUTC(d);
const ds = formatDate(d, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
const ts = formatTime(d);
const tc = eclipseTypeClass(ec.kind);
const tl = eclipseTypeLabel(ec.kind);
const locType = currentLocal ? eclipseTypeLabel(currentLocal.kind) : null;
@@ -1458,6 +1533,7 @@ function renderInfo() {
${!currentLocal && localObserver ? `<tr><td>Am Standort</td><td>nicht sichtbar</td></tr>` : ''}
</table>
<div class="eclipse-info-phase" id="eclipsePhaseLabel">—</div>
<div class="eclipse-info-scale-note">Distanzen stark komprimiert, Größenverhältnisse für die Anschauung angepasst</div>
`;
}
@@ -1490,7 +1566,7 @@ function renderContactTable() {
contactTable.innerHTML = rows.map(([lbl, date, desc]) => `
<tr>
<td class="eclipse-contact-label">${lbl}</td>
<td class="eclipse-contact-time">${fmtUTC(date)}</td>
<td class="eclipse-contact-time">${formatTime(date)}</td>
<td class="eclipse-contact-desc">${desc}</td>
</tr>
`).join('');
@@ -1508,7 +1584,7 @@ function renderContactTable() {
contactTable.innerHTML = rows.map(([lbl, date, desc]) => `
<tr>
<td class="eclipse-contact-label">${lbl}</td>
<td class="eclipse-contact-time">${fmtUTC(date)}</td>
<td class="eclipse-contact-time">${formatTime(date)}</td>
<td class="eclipse-contact-desc">${desc}</td>
</tr>
`).join('');
@@ -1524,7 +1600,7 @@ function renderContactTable() {
contactTable.innerHTML = rows.map(([lbl, date, desc]) => `
<tr>
<td class="eclipse-contact-label">${lbl}</td>
<td class="eclipse-contact-time">${date ? fmtUTC(date) : '—'}</td>
<td class="eclipse-contact-time">${date ? formatTime(date) : '—'}</td>
<td class="eclipse-contact-desc">${desc}</td>
</tr>
`).join('');
@@ -1581,6 +1657,18 @@ function renderTimeline() {
}
}
const originalUpdateSim = updateSim;
updateSim = function() {
originalUpdateSim();
stageTimeEl.textContent = tlDisplay.textContent;
};
const originalRefreshTimeDisplays = refreshTimeDisplays;
refreshTimeDisplays = function() {
originalRefreshTimeDisplays();
stageTimeEl.textContent = tlDisplay.textContent;
};
function setupInteraction() {
canvas3d.addEventListener('contextmenu', e => e.preventDefault());
canvas3d.addEventListener('mousedown', e => {
@@ -1672,6 +1760,16 @@ function setupInteraction() {
playSpeed = parseInt(speedSel.value, 10);
});
useLocalTimeEl.addEventListener('change', () => {
useLocalTime = useLocalTimeEl.checked;
refreshTimeDisplays();
});
showStageTimeEl.addEventListener('change', () => {
showStageTime = showStageTimeEl.checked;
stageTimeEl.classList.toggle('is-hidden', !showStageTime);
});
if (umbraScaleRange && umbraScaleValue) {
const syncUmbra = () => {
umbraProxyScale = parseFloat(umbraScaleRange.value);
@@ -1695,8 +1793,7 @@ function setupInteraction() {
document.getElementById('eclipseSearchBtn').addEventListener('click', searchEclipses);
infoToggleBtn.addEventListener('click', () => {
const collapsed = infoPanel.classList.toggle('is-collapsed');
infoToggleBtn.setAttribute('aria-expanded', String(!collapsed));
setInfoPanelCollapsed(!infoPanelCollapsed);
});
btnSpaceView.addEventListener('click', () => setView('space'));