Add error handling for moon position calculation

This commit is contained in:
Richard Zink committed 2026-10-07 08:04:44 +02:00
1 parent 944982f34a
commit e5765dd7de
1 file changed
+60 -51
+60 -51
View File
@@ -364,58 +364,60 @@
} }
function getMoonPosition(now, moonTimes) { function getMoonPosition(now, moonTimes) {
var rise = moonTimes.rise; try {
var set = moonTimes.set; var rise = moonTimes.rise;
var set = moonTimes.set;
if (!rise || !set) { if (!rise || !set) {
return { point: pointOnCircle(now, MOON_ORBIT_RADIUS), isVisible: false }; return { point: pointOnCircle(now, MOON_ORBIT_RADIUS), isVisible: false };
}
// Determine if moon is visible (above horizon)
var isVisible;
if (rise <= set) {
isVisible = (now >= rise && now <= set);
} else {
isVisible = (now >= rise || now <= set);
}
if (!isVisible) {
// Below horizon - position based on current time (grayed out)
return { point: pointOnCircle(now, MOON_ORBIT_RADIUS), isVisible: false };
}
// Above horizon - interpolate between moonrise and moonset
var riseAngle = angleForTime(rise);
var setAngle = angleForTime(set);
// Calculate the angular difference (could be negative if crossing midnight)
var diff = setAngle - riseAngle;
// Normalize so we take the "shorter" path that matches the moon arc
if (diff > Math.PI) diff -= 2 * Math.PI;
if (diff < -Math.PI) diff += 2 * Math.PI;
// Calculate progress (0 at rise, 1 at set)
var progress;
if (rise <= set) {
progress = (now.getTime() - rise.getTime()) / (set.getTime() - rise.getTime());
} else {
if (now >= rise) {
var endMs = set.getTime() + 24 * 3600 * 1000;
progress = (now.getTime() - rise.getTime()) / (endMs - rise.getTime());
} else {
progress = (now.getTime() + 24 * 3600 * 1000 - rise.getTime()) /
(set.getTime() + 24 * 3600 * 1000 - rise.getTime());
} }
}
var moonAngle = riseAngle + diff * progress; // Determine if moon is visible (above horizon)
return { var isVisible;
point: { if (rise <= set) {
x: 100 + Math.cos(moonAngle) * MOON_ORBIT_RADIUS, isVisible = (now >= rise && now <= set);
y: 100 + Math.sin(moonAngle) * MOON_ORBIT_RADIUS } else {
}, isVisible = (now >= rise || now <= set);
isVisible: true }
};
if (!isVisible) {
return { point: pointOnCircle(now, MOON_ORBIT_RADIUS), isVisible: false };
}
// Above horizon - interpolate between moonrise and moonset
var riseAngle = angleForTime(rise);
var setAngle = angleForTime(set);
// Calculate the angular difference (could be negative if crossing midnight)
var diff = setAngle - riseAngle;
if (diff > Math.PI) diff -= 2 * Math.PI;
if (diff < -Math.PI) diff += 2 * Math.PI;
// Calculate progress (0 at rise, 1 at set)
var progress;
if (rise <= set) {
progress = (now.getTime() - rise.getTime()) / (set.getTime() - rise.getTime());
} else {
if (now >= rise) {
var endMs = set.getTime() + 24 * 3600 * 1000;
progress = (now.getTime() - rise.getTime()) / (endMs - rise.getTime());
} else {
progress = (now.getTime() + 24 * 3600 * 1000 - rise.getTime()) /
(set.getTime() + 24 * 3600 * 1000 - rise.getTime());
}
}
var moonAngle = riseAngle + diff * progress;
return {
point: {
x: 100 + Math.cos(moonAngle) * MOON_ORBIT_RADIUS,
y: 100 + Math.sin(moonAngle) * MOON_ORBIT_RADIUS
},
isVisible: true
};
} catch (e) {
return { point: pointOnCircle(now, MOON_ORBIT_RADIUS), isVisible: false };
}
} }
function renderMoonPhaseIcon(phase) { function renderMoonPhaseIcon(phase) {
@@ -538,8 +540,15 @@
// Moon position - interpolated between moonrise and moonset on the orbit // Moon position - interpolated between moonrise and moonset on the orbit
var moonPos = getMoonPosition(now, moonTimes); var moonPos = getMoonPosition(now, moonTimes);
rpgMoon.setAttribute('transform', 'translate(' + moonPos.point.x + ', ' + moonPos.point.y + ')'); if (!moonPos || !moonPos.point || isNaN(moonPos.point.x) || isNaN(moonPos.point.y)) {
rpgMoon.setAttribute('opacity', moonPos.isVisible ? '1' : '0.35'); // Fallback to current time position
var fallbackP = pointOnCircle(now, MOON_ORBIT_RADIUS);
rpgMoon.setAttribute('transform', 'translate(' + fallbackP.x + ', ' + fallbackP.y + ')');
rpgMoon.setAttribute('opacity', '0.35');
} else {
rpgMoon.setAttribute('transform', 'translate(' + moonPos.point.x + ', ' + moonPos.point.y + ')');
rpgMoon.setAttribute('opacity', moonPos.isVisible ? '1' : '0.35');
}
// Sun rise/set arrows // Sun rise/set arrows
var srP = pointOnCircle(sunTimes.sunrise, SUN_ORBIT_RADIUS); var srP = pointOnCircle(sunTimes.sunrise, SUN_ORBIT_RADIUS);