diff --git a/index.html b/index.html
index 1d1e283..5883d91 100644
--- a/index.html
+++ b/index.html
@@ -22,8 +22,8 @@
min-width: 220px;
}
#analog-clock {
- width: 180px;
- height: 180px;
+ width: 200px;
+ height: 200px;
margin: 0 auto 10px auto;
display: block;
}
@@ -71,48 +71,61 @@
font-size: 11px;
margin-left: 4px;
}
- .moon-icon-container {
- width: 18px;
- height: 18px;
- position: relative;
- }
@@ -237,15 +250,19 @@
var minuteHand = document.getElementById('minute-hand');
var secondHand = document.getElementById('second-hand');
var hourMarks = document.getElementById('hour-marks');
- var rpgArcBg = document.getElementById('rpg-arc-bg');
+ var rpgSunArc = document.getElementById('sun-arc');
+ var rpgMoonArc = document.getElementById('moon-arc');
var rpgSun = document.getElementById('rpg-sun');
var rpgSunGlow = document.getElementById('rpg-sun-glow');
var rpgSunCore = document.getElementById('rpg-sun-core');
var rpgMoon = document.getElementById('rpg-moon');
- var sunriseMarker = document.getElementById('sunrise-marker');
- var sunsetMarker = document.getElementById('sunset-marker');
- var moonriseMarker = document.getElementById('moonrise-marker');
- var moonsetMarker = document.getElementById('moonset-marker');
+ var sunRiseArrow = document.getElementById('sun-rise-arrow');
+ var sunSetArrow = document.getElementById('sun-set-arrow');
+ var moonRiseArrow = document.getElementById('moon-rise-arrow');
+ var moonSetArrow = document.getElementById('moon-set-arrow');
+
+ var SUN_ORBIT_RADIUS = 55;
+ var MOON_ORBIT_RADIUS = 75;
// Generate hour marks
for (var i = 0; i < 12; i++) {
@@ -320,7 +337,30 @@
return 'Abnehm. Sichel';
}
- var rpgMoonPhaseGroup = null;
+ function angleForTime(date) {
+ var hours = date.getHours() + date.getMinutes() / 60;
+ return ((hours / 24) * 360 - 90) * Math.PI / 180;
+ }
+
+ function pointOnCircle(date, radius) {
+ var angle = angleForTime(date);
+ return {
+ x: 100 + Math.cos(angle) * radius,
+ y: 100 + Math.sin(angle) * radius
+ };
+ }
+
+ function arcBetween(startDate, endDate, radius) {
+ var sp = pointOnCircle(startDate, radius);
+ var ep = pointOnCircle(endDate, radius);
+ var startA = angleForTime(startDate) * 180 / Math.PI;
+ var endA = angleForTime(endDate) * 180 / Math.PI;
+ var diff = endA - startA;
+ if (diff < 0) diff += 360;
+ // Use shorter arc (largeArc=0) unless the difference exceeds 180
+ var largeArc = diff > 180 ? 1 : 0;
+ return 'M ' + sp.x + ' ' + sp.y + ' A ' + radius + ' ' + radius + ' 0 ' + largeArc + ' 1 ' + ep.x + ' ' + ep.y;
+ }
function renderMoonPhaseIcon(phase) {
var icon = document.getElementById('moon-phase-icon');
@@ -352,17 +392,19 @@
function renderRpgMoon(phase) {
rpgMoon.innerHTML = '';
- var r = 6;
+ var r = 9;
+ // Background
var bg = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
bg.setAttribute('cx', '100'); bg.setAttribute('cy', '100'); bg.setAttribute('r', r);
bg.setAttribute('fill', '#1c1b1f');
rpgMoon.appendChild(bg);
+ // Illuminated part
if (phase < 0.5) {
var lit = document.createElementNS('http://www.w3.org/2000/svg', 'path');
var phaseAngle = phase * 360;
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
var sweepFlag = phase < 0.25 ? 0 : 1;
- lit.setAttribute('d', 'M 100 94 A 6 6 0 0 1 100 106 A ' + rx + ' 6 0 0 ' + sweepFlag + ' 100 94 Z');
+ lit.setAttribute('d', 'M 100 91 A 9 9 0 0 1 100 109 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 100 91 Z');
lit.setAttribute('fill', '#e6dfd1');
rpgMoon.appendChild(lit);
} else {
@@ -370,7 +412,7 @@
var phaseAngle = (1 - phase) * 360;
var rx = r * Math.abs(Math.cos(phaseAngle * Math.PI / 180));
var sweepFlag = phase > 0.75 ? 0 : 1;
- lit.setAttribute('d', 'M 100 94 A 6 6 0 0 0 100 106 A ' + rx + ' 6 0 0 ' + sweepFlag + ' 100 94 Z');
+ lit.setAttribute('d', 'M 100 91 A 9 9 0 0 0 100 109 A ' + rx + ' 9 0 0 ' + sweepFlag + ' 100 91 Z');
lit.setAttribute('fill', '#e6dfd1');
rpgMoon.appendChild(lit);
}
@@ -394,88 +436,6 @@
minuteHand.setAttribute('transform', 'rotate(' + minuteAngle + ' 100 100)');
secondHand.setAttribute('transform', 'rotate(' + secondAngle + ' 100 100)');
- var sunTimes = SunCalc.getTimes(now, PASSAU_LAT, PASSAU_LON);
- var sunriseNext = getNextEvent(sunTimes.sunrise, now, PASSAU_LAT, PASSAU_LON, 'sunrise');
- var sunsetNext = getNextEvent(sunTimes.sunset, now, PASSAU_LAT, PASSAU_LON, 'sunset');
-
- function timeToAngle(date) {
- var hours = date.getHours() + date.getMinutes() / 60;
- return ((hours / 24) * 360 - 90) * Math.PI / 180;
- }
-
- function timeToPoint(date, r) {
- var angle = timeToAngle(date);
- return { x: 100 + Math.cos(angle) * r, y: 100 + Math.sin(angle) * r };
- }
-
- var sunOrbitRadius = 62;
- var markerRadius = 48;
-
- var sr = sunriseNext.date || new Date(now.getFullYear(), now.getMonth(), now.getDate(), 6, 0, 0);
- var ss = sunsetNext.date || new Date(now.getFullYear(), now.getMonth(), now.getDate(), 18, 0, 0);
- var srPoint = timeToPoint(sr, sunOrbitRadius);
- var ssPoint = timeToPoint(ss, sunOrbitRadius);
- rpgArcBg.setAttribute('d', 'M ' + srPoint.x + ' ' + srPoint.y + ' A ' + sunOrbitRadius + ' ' + sunOrbitRadius + ' 0 0 1 ' + ssPoint.x + ' ' + ssPoint.y);
-
- if (now >= sunTimes.sunrise && now <= sunTimes.sunset) {
- var sunP = timeToPoint(now, sunOrbitRadius);
- rpgSun.setAttribute('cx', sunP.x);
- rpgSun.setAttribute('cy', sunP.y);
- rpgSun.setAttribute('opacity', '1');
- rpgSunGlow.setAttribute('cx', sunP.x);
- rpgSunGlow.setAttribute('cy', sunP.y);
- rpgSunGlow.setAttribute('opacity', '0.4');
- rpgSunCore.setAttribute('cx', sunP.x);
- rpgSunCore.setAttribute('cy', sunP.y);
- rpgSunCore.setAttribute('opacity', '1');
- } else {
- var sunP = timeToPoint(now, sunOrbitRadius);
- rpgSun.setAttribute('cx', sunP.x);
- rpgSun.setAttribute('cy', sunP.y);
- rpgSun.setAttribute('opacity', '0.4');
- rpgSunGlow.setAttribute('cx', sunP.x);
- rpgSunGlow.setAttribute('cy', sunP.y);
- rpgSunGlow.setAttribute('opacity', '0.15');
- rpgSunCore.setAttribute('cx', sunP.x);
- rpgSunCore.setAttribute('cy', sunP.y);
- rpgSunCore.setAttribute('opacity', '0.4');
- }
-
- var moonTimes = SunCalc.getMoonTimes(now, PASSAU_LAT, PASSAU_LON);
- var moonVisible = false;
- if (moonTimes.rise && moonTimes.set) {
- if (moonTimes.rise < moonTimes.set) {
- moonVisible = (now >= moonTimes.rise && now <= moonTimes.set);
- } else {
- moonVisible = (now >= moonTimes.rise || now <= moonTimes.set);
- }
- }
- var moonP = timeToPoint(now, sunOrbitRadius);
- rpgMoon.setAttribute('cx', moonP.x);
- rpgMoon.setAttribute('cy', moonP.y);
- rpgMoon.setAttribute('opacity', moonVisible ? '1' : '0.25');
-
- var srM = timeToPoint(sr, markerRadius);
- sunriseMarker.setAttribute('transform', 'translate(' + srM.x + ', ' + srM.y + ')');
- var ssM = timeToPoint(ss, markerRadius);
- sunsetMarker.setAttribute('transform', 'translate(' + ssM.x + ', ' + ssM.y + ')');
-
- if (moonTimes.rise) {
- var mrM = timeToPoint(moonTimes.rise, markerRadius);
- moonriseMarker.setAttribute('transform', 'translate(' + mrM.x + ', ' + mrM.y + ')');
- moonriseMarker.setAttribute('opacity', '1');
- } else {
- moonriseMarker.setAttribute('opacity', '0');
- }
-
- if (moonTimes.set) {
- var msM = timeToPoint(moonTimes.set, markerRadius);
- moonsetMarker.setAttribute('transform', 'translate(' + msM.x + ', ' + msM.y + ')');
- moonsetMarker.setAttribute('opacity', '1');
- } else {
- moonsetMarker.setAttribute('opacity', '0');
- }
-
// Sun times
var sunTimes = SunCalc.getTimes(now, PASSAU_LAT, PASSAU_LON);
var sunriseNext = getNextEvent(sunTimes.sunrise, now, PASSAU_LAT, PASSAU_LON, 'sunrise');
@@ -496,6 +456,66 @@
document.getElementById('moonset-value').textContent = formatTimeHM(moonsetNext.date);
document.getElementById('moonset-when').textContent = moonsetNext.label ? 'ยท ' + moonsetNext.label : '';
+ // Sun arc
+ if (sunTimes.sunrise && sunTimes.sunset) {
+ rpgSunArc.setAttribute('d', arcBetween(sunTimes.sunrise, sunTimes.sunset, SUN_ORBIT_RADIUS));
+ }
+
+ // Moon arc
+ if (moonTimes.rise && moonTimes.set) {
+ rpgMoonArc.setAttribute('d', arcBetween(moonTimes.rise, moonTimes.set, MOON_ORBIT_RADIUS));
+ }
+
+ // Sun position
+ var sunP = pointOnCircle(now, SUN_ORBIT_RADIUS);
+ rpgSun.setAttribute('cx', sunP.x);
+ rpgSun.setAttribute('cy', sunP.y);
+ rpgSunGlow.setAttribute('cx', sunP.x);
+ rpgSunGlow.setAttribute('cy', sunP.y);
+ rpgSunCore.setAttribute('cx', sunP.x);
+ rpgSunCore.setAttribute('cy', sunP.y);
+
+ var isDaytime = now >= sunTimes.sunrise && now <= sunTimes.sunset;
+ rpgSun.setAttribute('opacity', isDaytime ? '1' : '0.35');
+ rpgSunGlow.setAttribute('opacity', isDaytime ? '0.4' : '0.15');
+ rpgSunCore.setAttribute('opacity', isDaytime ? '1' : '0.35');
+
+ // Moon position
+ var moonP = pointOnCircle(now, MOON_ORBIT_RADIUS);
+ rpgMoon.setAttribute('transform', 'translate(' + moonP.x + ', ' + moonP.y + ')');
+
+ var moonVisible = false;
+ if (moonTimes.rise && moonTimes.set) {
+ if (moonTimes.rise < moonTimes.set) {
+ moonVisible = (now >= moonTimes.rise && now <= moonTimes.set);
+ } else {
+ moonVisible = (now >= moonTimes.rise || now <= moonTimes.set);
+ }
+ }
+ rpgMoon.setAttribute('opacity', moonVisible ? '1' : '0.35');
+
+ // Sun rise/set arrows
+ var srP = pointOnCircle(sunTimes.sunrise, SUN_ORBIT_RADIUS);
+ sunRiseArrow.setAttribute('transform', 'translate(' + srP.x + ', ' + srP.y + ')');
+ var ssP = pointOnCircle(sunTimes.sunset, SUN_ORBIT_RADIUS);
+ sunSetArrow.setAttribute('transform', 'translate(' + ssP.x + ', ' + ssP.y + ')');
+
+ // Moon rise/set arrows
+ if (moonTimes.rise) {
+ var mrP = pointOnCircle(moonTimes.rise, MOON_ORBIT_RADIUS);
+ moonRiseArrow.setAttribute('transform', 'translate(' + mrP.x + ', ' + mrP.y + ')');
+ moonRiseArrow.setAttribute('opacity', '1');
+ } else {
+ moonRiseArrow.setAttribute('opacity', '0');
+ }
+ if (moonTimes.set) {
+ var msP = pointOnCircle(moonTimes.set, MOON_ORBIT_RADIUS);
+ moonSetArrow.setAttribute('transform', 'translate(' + msP.x + ', ' + msP.y + ')');
+ moonSetArrow.setAttribute('opacity', '1');
+ } else {
+ moonSetArrow.setAttribute('opacity', '0');
+ }
+
// Moon phase
var moonIllum = SunCalc.getMoonIllumination(now);
document.getElementById('moon-phase-text').textContent =