Detailkarte der Mond-Planeten-Bedeckungen: echte Mondtextur statt Flaechenfuellung

Verwendet dieselbe Mondgrafik (moon4calendar.png) wie Mondphasenansicht und
Mondjahr, korrekt zur Himmelsorientierung gedreht, mit Fallback auf die
alte Flachdarstellung solange die Textur noch nicht geladen ist.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 10:34:12 +02:00
co-authored by Claude Sonnet 5
parent 5652cc7e40
commit 71c8e832ba
+71 -11
View File
@@ -400,6 +400,13 @@ if (!empty($currentLocation) && is_array($currentLocation)) {
uranus: { body: 'Uranus', label: 'Uranus', radiusKm: 25559.0, color: '#8fd9e8' },
neptune: { body: 'Neptune', label: 'Neptun', radiusKm: 24764.0, color: '#5f7fe0' }
};
const MOON_TEXTURE = new Image();
MOON_TEXTURE.src = 'images/moons/moon4calendar.png';
MOON_TEXTURE.onload = function () {
if (STATE.selectedEventIndex !== null) {
renderOccultationMap(STATE.selectedEventIndex);
}
};
const OBSERVER = new Astronomy.Observer(
Number(SITE_LOCATION.latitude),
Number(SITE_LOCATION.longitude),
@@ -814,19 +821,11 @@ if (!empty($currentLocation) && is_array($currentLocation)) {
};
}
function drawMoonWithTerminator(ctx, centerX, centerY, radiusPx, terminatorInfo) {
const phaseFraction = terminatorInfo.phaseFraction;
const brightSideAngleRad = terminatorInfo.brightSideAngleRad;
const cosPhase = Math.max(-1, Math.min(1, 2 * phaseFraction - 1));
const isInverted = STATE.invertMap;
function drawMoonWithTerminatorFlat(ctx, radiusPx, phaseFraction, cosPhase, isInverted) {
const baseMoonFill = isInverted ? 'rgba(236, 239, 245, 0.98)' : 'rgba(24, 28, 36, 0.96)';
const litMoonFill = isInverted ? 'rgba(86, 94, 112, 0.88)' : 'rgba(228, 232, 240, 0.95)';
const moonStroke = isInverted ? 'rgba(70, 78, 96, 0.75)' : 'rgba(245,248,255,0.72)';
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(brightSideAngleRad);
ctx.beginPath();
ctx.arc(0, 0, radiusPx, 0, Math.PI * 2);
ctx.fillStyle = baseMoonFill;
@@ -836,7 +835,6 @@ if (!empty($currentLocation) && is_array($currentLocation)) {
ctx.lineWidth = 2;
ctx.strokeStyle = isInverted ? 'rgba(70, 78, 96, 0.55)' : 'rgba(170,180,195,0.35)';
ctx.stroke();
ctx.restore();
return;
}
@@ -848,7 +846,6 @@ if (!empty($currentLocation) && is_array($currentLocation)) {
ctx.lineWidth = 2;
ctx.strokeStyle = moonStroke;
ctx.stroke();
ctx.restore();
return;
}
@@ -878,7 +875,70 @@ if (!empty($currentLocation) && is_array($currentLocation)) {
ctx.lineWidth = 2;
ctx.strokeStyle = moonStroke;
ctx.stroke();
}
function drawMoonWithTerminator(ctx, centerX, centerY, radiusPx, terminatorInfo) {
const phaseFraction = terminatorInfo.phaseFraction;
const brightSideAngleRad = terminatorInfo.brightSideAngleRad;
const cosPhase = Math.max(-1, Math.min(1, 2 * phaseFraction - 1));
const isInverted = STATE.invertMap;
const textureReady = MOON_TEXTURE.complete && MOON_TEXTURE.naturalWidth > 0;
const moonStroke = isInverted ? 'rgba(70, 78, 96, 0.75)' : 'rgba(245,248,255,0.55)';
ctx.save();
ctx.translate(centerX, centerY);
ctx.rotate(brightSideAngleRad);
if (!textureReady) {
drawMoonWithTerminatorFlat(ctx, radiusPx, phaseFraction, cosPhase, isInverted);
ctx.restore();
return;
}
// Dunkle Mondscheibe als Basis (Neumondseite), darüber wird die
// Textur nur im beleuchteten Bereich eingeblendet.
ctx.save();
ctx.beginPath();
ctx.arc(0, 0, radiusPx, 0, Math.PI * 2);
ctx.clip();
ctx.fillStyle = isInverted ? 'rgba(210, 214, 224, 0.94)' : 'rgba(8, 10, 16, 0.94)';
ctx.fill();
if (phaseFraction > 0.001) {
ctx.save();
if (phaseFraction < 0.999) {
ctx.beginPath();
for (let i = 0; i <= 72; i++) {
const t = -radiusPx + 2 * radiusPx * i / 72;
const xr = Math.sqrt(Math.max(0, radiusPx * radiusPx - t * t));
const xt = -cosPhase * xr;
i === 0 ? ctx.moveTo(xt, t) : ctx.lineTo(xt, t);
}
for (let i = 72; i >= 0; i--) {
const t = -radiusPx + 2 * radiusPx * i / 72;
const xr = Math.sqrt(Math.max(0, radiusPx * radiusPx - t * t));
ctx.lineTo(xr, t);
}
ctx.closePath();
ctx.clip();
}
ctx.globalAlpha = isInverted ? 0.5 : 0.96;
// Die Textur liegt um 180 Grad gedreht vor (Sueden oben, Ost/West
// vertauscht); hier um die Bildmitte drehen, damit sie zur
// Himmelsdarstellung mit Norden oben passt.
ctx.scale(-1, -1);
ctx.drawImage(MOON_TEXTURE, -radiusPx, -radiusPx, radiusPx * 2, radiusPx * 2);
ctx.globalAlpha = 1;
ctx.restore();
}
ctx.restore();
ctx.restore();
ctx.beginPath();
ctx.arc(centerX, centerY, radiusPx, 0, Math.PI * 2);
ctx.lineWidth = 1.5;
ctx.strokeStyle = moonStroke;
ctx.stroke();
}
function chunkStars(stars, size) {