moon trend, day number, and fraction display
This commit is contained in:
1 parent
3f8d2c454c
commit
c91302adf1
2 files changed
+22
-3
No files matched your search
+20
-1
@@ -21,6 +21,23 @@ export interface LunarInfo {
|
||||
emoji: string; // 🌑🌒🌓🌔🌕🌖🌗🌘
|
||||
name: string; // localized phase name (set by caller)
|
||||
illumination: number; // 0–100 (percentage visible)
|
||||
trend: 'waxing' | 'waning';
|
||||
moonDay: number; // day of the lunar cycle (1-30)
|
||||
}
|
||||
|
||||
/** Convert moon phase (0-1) to a simple fraction string. */
|
||||
export function phaseToFraction(phase: number): string {
|
||||
const dist = Math.min(phase, 1 - phase); // distance from new or full
|
||||
const fracs: [number, string][] = [
|
||||
[0.0, '0'], [0.0625, '1/16'], [0.125, '1/8'], [0.1875, '3/16'],
|
||||
[0.25, '1/4'], [0.3125, '5/16'], [0.375, '3/8'], [0.4375, '7/16'],
|
||||
[0.5, '1/2'], [0.5625, '9/16'], [0.625, '5/8'], [0.6875, '11/16'],
|
||||
[0.75, '3/4'], [0.8125, '13/16'], [0.875, '7/8'], [0.9375, '15/16'], [1.0, '1'],
|
||||
];
|
||||
for (const [threshold, label] of fracs) {
|
||||
if (Math.abs(dist - threshold) < 0.032) return label;
|
||||
}
|
||||
return '—';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,6 +123,8 @@ export function calcSolarTimes(jdate: JDate, lat: number, lon: number, tz: numbe
|
||||
/** Moon phase info for a given Julian date. */
|
||||
export function getMoonInfo(jdate: JDate): LunarInfo {
|
||||
const phase = Paschalion.getLunarPhase(jdate);
|
||||
const trend = phase < 0.5 ? 'waxing' : 'waning';
|
||||
const moonDay = Math.floor(phase * 29.53) + 1;
|
||||
|
||||
// Map phase (0-1) to emoji (0=new, 0.5=full)
|
||||
let emoji: string;
|
||||
@@ -122,7 +141,7 @@ export function getMoonInfo(jdate: JDate): LunarInfo {
|
||||
// Illumination (0–100%)
|
||||
const illumination = Math.round((1 - Math.cos(2 * Math.PI * phase)) / 2 * 100);
|
||||
|
||||
return { phase, emoji, name: '', illumination };
|
||||
return { phase, emoji, name: '', illumination, trend, moonDay };
|
||||
}
|
||||
|
||||
/** Phase names keyed by phase bucket (0=new, 1-7 for other phases). */
|
||||
|
||||
@@ -12,7 +12,7 @@ import { DataCache } from '../core/data-cache';
|
||||
import { fontClass } from './settings-view';
|
||||
import { loadSettings } from './settings-view';
|
||||
import { ServiceView } from './service-view';
|
||||
import { calcSolarTimes, getMoonInfo, getMoonPhaseName } from '../core/astronomy';
|
||||
import { calcSolarTimes, getMoonInfo, getMoonPhaseName, phaseToFraction } from '../core/astronomy';
|
||||
|
||||
let cachedFastingPeriods: FastingPeriod[] | null = null;
|
||||
const lifeCache = new Map<string, LifeData | null>();
|
||||
@@ -953,7 +953,7 @@ export class CalendarView {
|
||||
<span class="text-navy">${solar?.sunset ?? '—'}</span>
|
||||
<span class="mx-2 text-gold/40">|</span>
|
||||
<span class="font-bold text-navy">${this.t.calendar.moonPhase}:</span>
|
||||
<span class="text-navy">${moon.emoji} ${moonName} (${moon.illumination}%)</span>
|
||||
<span class="text-navy">${moon.emoji} ${moonName} ${moon.trend === 'waxing' ? '↗' : '↘'} (day ${moon.moonDay}, ${phaseToFraction(moon.phase)}, ${moon.illumination}%)</span>
|
||||
`;
|
||||
} else {
|
||||
astroPanel.innerHTML = `<span class="text-navy-light italic">${this.t.calendar.noLocation}</span>`;
|
||||
|
||||
Reference in new issue
Block a user