Improve moon phase visualization using fraction for terminator ellipse
This commit is contained in:
1 parent
5ea523e6c4
commit
b4c3669006
1 file changed
+56
-33
+56
-33
@@ -193,7 +193,7 @@
|
|||||||
|
|
||||||
<!-- Moon position (with phase) -->
|
<!-- Moon position (with phase) -->
|
||||||
<g id="rpg-moon">
|
<g id="rpg-moon">
|
||||||
<circle id="rpg-moon-bg" cx="0" cy="0" r="9" fill="#b0a89a" stroke="#e6dfd1" stroke-width="1"/>
|
<circle id="rpg-moon-bg" cx="0" cy="0" r="9" fill="#1c1b1f" stroke="#999187" stroke-width="1"/>
|
||||||
<path id="rpg-moon-lit" d="" fill="#e6dfd1"/>
|
<path id="rpg-moon-lit" d="" fill="#e6dfd1"/>
|
||||||
<path id="rpg-moon-dark" d="" fill="#54514f"/>
|
<path id="rpg-moon-dark" d="" fill="#54514f"/>
|
||||||
</g>
|
</g>
|
||||||
@@ -219,7 +219,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="info-row">
|
<div class="info-row">
|
||||||
<div class="info-icon">
|
<div class="info-icon">
|
||||||
<svg id="moon-phase-icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="#e6dfd1"/></svg>
|
<svg id="moon-phase-icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9" fill="#1c1b1f"/></svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="info-content"><span class="info-label">Mondphase</span><span class="info-value" id="moon-phase-text">--</span></div>
|
<div class="info-content"><span class="info-label">Mondphase</span><span class="info-value" id="moon-phase-text">--</span></div>
|
||||||
</div>
|
</div>
|
||||||
@@ -500,50 +500,73 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMoonPhaseIcon(phase) {
|
function renderMoonPhaseIcon(phase, fraction) {
|
||||||
var icon = document.getElementById('moon-phase-icon');
|
var icon = document.getElementById('moon-phase-icon');
|
||||||
icon.innerHTML = '';
|
icon.innerHTML = '';
|
||||||
|
|
||||||
|
var r = 9;
|
||||||
|
// Background: dark full circle
|
||||||
var bg = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
var bg = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
||||||
bg.setAttribute('cx', '12'); bg.setAttribute('cy', '12'); bg.setAttribute('r', '9');
|
bg.setAttribute('cx', '12'); bg.setAttribute('cy', '12'); bg.setAttribute('r', r);
|
||||||
bg.setAttribute('fill', '#b0a89a');
|
bg.setAttribute('fill', '#1c1b1f');
|
||||||
bg.setAttribute('stroke', '#e6dfd1');
|
bg.setAttribute('stroke', '#999187');
|
||||||
bg.setAttribute('stroke-width', '0.5');
|
bg.setAttribute('stroke-width', '0.5');
|
||||||
icon.appendChild(bg);
|
icon.appendChild(bg);
|
||||||
|
|
||||||
|
// Calculate terminator ellipse radius from fraction
|
||||||
|
// rx > 0 (crescent): terminator curves into the lit area
|
||||||
|
// rx < 0 (gibbous): terminator curves into the dark area
|
||||||
|
var rx = r * (1 - 2 * fraction);
|
||||||
|
|
||||||
|
var path;
|
||||||
if (phase < 0.5) {
|
if (phase < 0.5) {
|
||||||
var lit = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
// Waxing: right side lit, left side dark
|
||||||
var r = 9;
|
if (rx > 0) {
|
||||||
var phaseAngle = phase * 360;
|
// Crescent
|
||||||
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
|
path = 'M 12 3 A 9 9 0 0 0 12 21 A ' + rx + ' 9 0 0 1 12 3 Z';
|
||||||
var sweepFlag = phase < 0.25 ? 0 : 1;
|
} else {
|
||||||
lit.setAttribute('d', 'M 12 3 A 9 9 0 0 1 12 21 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 12 3 Z');
|
// Gibbous
|
||||||
lit.setAttribute('fill', '#e6dfd1');
|
path = 'M 12 3 A 9 9 0 0 0 12 21 A ' + Math.abs(rx) + ' 9 0 0 0 12 3 Z';
|
||||||
icon.appendChild(lit);
|
}
|
||||||
} else {
|
} else {
|
||||||
var lit = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
// Waning: left side lit, right side dark
|
||||||
var r = 9;
|
if (rx > 0) {
|
||||||
var phaseAngle = (1 - phase) * 360;
|
// Crescent
|
||||||
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
|
path = 'M 12 3 A 9 9 0 0 1 12 21 A ' + rx + ' 9 0 0 0 12 3 Z';
|
||||||
var sweepFlag = phase > 0.75 ? 0 : 1;
|
} else {
|
||||||
lit.setAttribute('d', 'M 12 3 A 9 9 0 0 0 12 21 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 12 3 Z');
|
// Gibbous
|
||||||
lit.setAttribute('fill', '#e6dfd1');
|
path = 'M 12 3 A 9 9 0 0 1 12 21 A ' + Math.abs(rx) + ' 9 0 0 1 12 3 Z';
|
||||||
icon.appendChild(lit);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lit = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||||
|
lit.setAttribute('d', path);
|
||||||
|
lit.setAttribute('fill', '#e6dfd1');
|
||||||
|
icon.appendChild(lit);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRpgMoon(phase) {
|
function renderRpgMoon(phase, fraction) {
|
||||||
var r = 9;
|
var r = 9;
|
||||||
rpgMoonDark.setAttribute('d', '');
|
rpgMoonDark.setAttribute('d', '');
|
||||||
|
|
||||||
|
var rx = r * (1 - 2 * fraction);
|
||||||
|
|
||||||
|
var path;
|
||||||
if (phase < 0.5) {
|
if (phase < 0.5) {
|
||||||
var phaseAngle = phase * 360;
|
if (rx > 0) {
|
||||||
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
|
path = 'M 0 -9 A 9 9 0 0 0 0 9 A ' + rx + ' 9 0 0 1 0 -9 Z';
|
||||||
var sweepFlag = phase < 0.25 ? 0 : 1;
|
} else {
|
||||||
rpgMoonLit.setAttribute('d', 'M 0 -9 A 9 9 0 0 1 0 9 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 0 -9 Z');
|
path = 'M 0 -9 A 9 9 0 0 0 0 9 A ' + Math.abs(rx) + ' 9 0 0 0 0 -9 Z';
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
var phaseAngle = (1 - phase) * 360;
|
if (rx > 0) {
|
||||||
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
|
path = 'M 0 -9 A 9 9 0 0 1 0 9 A ' + rx + ' 9 0 0 0 0 -9 Z';
|
||||||
var sweepFlag = phase > 0.75 ? 0 : 1;
|
} else {
|
||||||
rpgMoonLit.setAttribute('d', 'M 0 -9 A 9 9 0 0 0 0 9 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 0 -9 Z');
|
path = 'M 0 -9 A 9 9 0 0 1 0 9 A ' + Math.abs(rx) + ' 9 0 0 1 0 -9 Z';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpgMoonLit.setAttribute('d', path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateClockAndEvents() {
|
function updateClockAndEvents() {
|
||||||
@@ -648,8 +671,8 @@
|
|||||||
var moonIllum = SunCalc.getMoonIllumination(now);
|
var moonIllum = SunCalc.getMoonIllumination(now);
|
||||||
document.getElementById('moon-phase-text').textContent =
|
document.getElementById('moon-phase-text').textContent =
|
||||||
getMoonPhaseText(moonIllum.phase) + ' ' + Math.round(moonIllum.fraction * 100) + '%';
|
getMoonPhaseText(moonIllum.phase) + ' ' + Math.round(moonIllum.fraction * 100) + '%';
|
||||||
renderMoonPhaseIcon(moonIllum.phase);
|
renderMoonPhaseIcon(moonIllum.phase, moonIllum.fraction);
|
||||||
renderRpgMoon(moonIllum.phase);
|
renderRpgMoon(moonIllum.phase, moonIllum.fraction);
|
||||||
}
|
}
|
||||||
|
|
||||||
var startTime = Date.now();
|
var startTime = Date.now();
|
||||||
|
|||||||
Reference in new issue
Block a user