Add error handling for moon position calculation
This commit is contained in:
1 parent
944982f34a
commit
e5765dd7de
1 file changed
+60
-51
+60
-51
@@ -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);
|
||||||
|
|||||||
Reference in new issue
Block a user