Skip to content

Commit b65e358

Browse files
committed
Add rise/set time indicator arcs for planets. Add option to debug time at accelerated rate.
1 parent a5648e9 commit b65e358

10 files changed

Lines changed: 90 additions & 12 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aw-clock",
3-
"version": "1.0.5",
3+
"version": "1.0.6",
44
"license": "MIT",
55
"author": "Kerry Shetline <kerry@shetline.com>",
66
"scripts": {
@@ -19,6 +19,7 @@
1919
"js-cookie": "^2.2.0",
2020
"ks-astronomy": "^1.0.1",
2121
"ks-date-time-zone": "^1.4.0",
22+
"ks-math": "^1.1.1",
2223
"ks-util": "^1.2.0",
2324
"rxjs": "^6.2.1"
2425
},

src/app.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Settings } from './settings';
22

33
export interface AppService {
44
getCurrentTime(): number;
5+
isTimeAccelerated(): boolean;
56
updateTime(hour: number, minute: number, forceRefresh: boolean): void;
67
updateSettings(newSettings: Settings);
78
forecastHasBeenUpdated(): void;

src/clock.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,10 @@ export class Clock {
125125
const textRadius = 33.5;
126126
const constellationRadius = 24;
127127
const center = 50;
128+
const centerStr = center.toString();
128129
const clock = document.getElementById('clock');
129130
const planetTracks = document.getElementById('planet-tracks');
131+
const risenTracks = document.getElementById('risen-tracks');
130132

131133
for (let i = 0; i < 360; i += 6) {
132134
const x1 = center + radius * Math.cos(Math.PI * i / 180);
@@ -166,13 +168,15 @@ export class Clock {
166168
}
167169
}
168170

169-
const planetSymbols = [0x263C, 0x263D, 0x0263F, 0x2640, 0x2642, 0x2643, 0x2644]; // Sun, Moon, Mercury, Venus, Mars, Jupiter, Saturn
171+
const planetSymbols = [0x263C, 0x263D, 0x0263F, 0x2640, 0x2642, 0x2643, 0x2644];
172+
const planetIds = ['sun', 'moon', 'mercury', 'venus', 'mars', 'jupiter', 'saturn'];
170173

171174
planetSymbols.forEach((planet, index) => {
172175
const x = center + 10 + index * 2;
173176
const dy = 0.75 + (index % 2) * 2;
174177
const rect = document.createElementNS(SVG_NAMESPACE, 'rect');
175178
const text = document.createElementNS(SVG_NAMESPACE, 'text');
179+
const path = document.createElementNS(SVG_NAMESPACE, 'path');
176180

177181
rect.setAttributeNS(null, 'x', (x - 0.9).toString());
178182
rect.setAttributeNS(null, 'y', (center + dy - 2).toString());
@@ -182,11 +186,17 @@ export class Clock {
182186
planetTracks.appendChild(rect);
183187

184188
text.setAttributeNS(null, 'x', x.toString());
185-
text.setAttributeNS(null, 'y', center.toString());
189+
text.setAttributeNS(null, 'y', centerStr);
186190
text.setAttributeNS(null, 'dy', dy.toString());
187191
text.classList.add('constellation');
188192
text.textContent = String.fromCodePoint(planet);
189193
planetTracks.appendChild(text);
194+
195+
path.setAttributeNS(null, 'fill', 'none');
196+
path.setAttributeNS(null, 'visibility', 'inherited');
197+
path.classList.add('risen-track');
198+
path.id = `risen-${planetIds[index]}`;
199+
risenTracks.appendChild(path);
190200
});
191201
}
192202

@@ -210,7 +220,8 @@ export class Clock {
210220
this.sweep.beginElement();
211221
};
212222

213-
const doMechanicalSecondHandEffect = this.hasBeginElement && (!isRaspbian() || !this.hasCompletingAnimation);
223+
const doMechanicalSecondHandEffect = this.hasBeginElement && !this.appService.isTimeAccelerated() &&
224+
(!isRaspbian() || !this.hasCompletingAnimation);
214225
const animationTime = (doMechanicalSecondHandEffect ? SECOND_HAND_ANIMATION_TIME : 0);
215226
const now = this.appService.getCurrentTime() + animationTime;
216227
const date = new KsDateTime(now, this.timezone);

src/ephemeris.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ import {
2323
} from 'ks-astronomy';
2424
import { getDateFromDayNumber_SGC, KsDateTime, KsTimeZone } from 'ks-date-time-zone';
2525
import * as $ from 'jquery';
26-
import { setSvgHref } from './util';
26+
import { describeArc, setSvgHref } from './util';
2727
import { AppService } from './app.service';
2828
import { padLeft } from 'ks-util';
29+
import { mod } from 'ks-math';
2930

3031
const solarSystem = new SolarSystem();
3132
const eventFinder = new EventFinder();
@@ -55,6 +56,7 @@ function formatTime(date: KsDateTime, amPm: boolean) {
5556
export class Ephemeris {
5657
private planetTracks: JQuery;
5758
private planetSymbols: JQuery;
59+
private risenTracks: JQuery;
5860
private sunrises: JQuery[] = [];
5961
private sunsets: JQuery[] = [];
6062
private moons: JQuery[] = [];
@@ -70,6 +72,7 @@ export class Ephemeris {
7072

7173
this.planetTracks = $('#planet-tracks');
7274
this.planetSymbols = $('#planets');
75+
this.risenTracks = $('#risen-tracks');
7376

7477
for (let i = 0; i < 4; ++i) {
7578
this.sunrises[i] = $('#day' + i + '-sunrise');
@@ -87,10 +90,12 @@ export class Ephemeris {
8790
if (newValue) {
8891
this.planetTracks.css('visibility', 'hidden');
8992
this.planetSymbols.css('visibility', 'hidden');
93+
this.risenTracks.css('visibility', 'hidden');
9094
}
9195
else {
9296
this.planetTracks.css('visibility', 'visible');
9397
this.planetSymbols.css('visibility', 'visible');
98+
this.risenTracks.css('visibility', 'visible');
9499
}
95100
}
96101
}
@@ -118,7 +123,32 @@ export class Ephemeris {
118123
targetAltitude -= AVG_SUN_MOON_RADIUS;
119124

120125
rotate(elem, -eclipticLongitude);
121-
elem.css('stroke-width', altitude < targetAltitude ? '0.5' : '0');
126+
elem.css('stroke-width', altitude < targetAltitude ? '0.25' : '0');
127+
elem[0].setAttributeNS(null, 'r', altitude < targetAltitude ? '0.625' : '0.75');
128+
129+
const risenTrack = $('#risen-' + planetIds[index]);
130+
const rise = eventFinder.findEvent(planet, RISE_EVENT, time_JDU + 5 / 1400, observer, timezone, null, true);
131+
const set = eventFinder.findEvent(planet, SET_EVENT, time_JDU - 5 / 1440, observer, timezone);
132+
133+
if (rise && rise.ut > time_JDU - 1.1 && set && set.ut < time_JDU + 1.1) {
134+
const currentAngle = mod(-eclipticLongitude, 360);
135+
const radius = 10 + index * 2;
136+
let riseAngle = currentAngle + (time_JDU - rise.ut) * 360;
137+
let setAngle = currentAngle + (time_JDU - set.ut) * 360;
138+
139+
while (setAngle + 360 < riseAngle)
140+
setAngle += 360;
141+
142+
while (riseAngle < setAngle)
143+
riseAngle += 360;
144+
145+
const arc = describeArc(50, 50, radius, setAngle, riseAngle);
146+
147+
risenTrack[0].setAttributeNS(null, 'd', arc);
148+
risenTrack.css('visibility', 'inherited');
149+
}
150+
else
151+
risenTrack.css('visibility', 'hidden');
122152
});
123153

124154
eventFinder.getRiseAndSetEvents(SUN, wallTime.y, wallTime.m, wallTime.d, 4, observer, timezone).then(daysOfEvents => {

src/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
repeatCount="1"/>
5454
</line>
5555
</g>
56+
<g id="risen-tracks"></g>
5657
<g id="planets">
5758
<circle id="saturn" cx="72" cy="50" r="0.75" stroke="black" stroke-width="0" fill="#FF8"/>
5859
<circle id="jupiter" cx="70" cy="50" r="0.75" stroke="black" stroke-width="0" fill="orange"/>
@@ -193,7 +194,7 @@
193194
</div>
194195
</div>
195196
<div class="dialog-buttons">
196-
<span class="version-number">1.0.5</span>
197+
<span class="version-number">1.0.6</span>
197198
<button id="settings-reload">Reload</button>
198199
<span>&bull;</span>
199200
<button id="settings-cancel">Cancel</button>

src/main.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ import { Indoor } from './indoor';
3232
initTimeZoneSmall();
3333

3434
const baseTime = Date.now();
35-
const debugTime = 0; // +new Date(2018, 5, 25, 5, 8, 40, 0);
35+
const debugTime = 0; // +new Date(2018, 6, 2, 22, 30, 0, 0);
36+
const debugTimeRate = 60;
3637

3738
function parseTime(s: string): number {
3839
const parts = s.split(':');
@@ -111,11 +112,15 @@ export class AwClockApp implements AppService {
111112

112113
getCurrentTime(): number {
113114
if (debugTime)
114-
return debugTime + Date.now() - baseTime;
115+
return debugTime + (Date.now() - baseTime) * debugTimeRate;
115116
else
116117
return Date.now();
117118
}
118119

120+
isTimeAccelerated(): boolean {
121+
return (!!debugTime && debugTimeRate > 1);
122+
}
123+
119124
public start() {
120125
this.clock.start();
121126
}
@@ -139,7 +144,11 @@ export class AwClockApp implements AppService {
139144

140145
this.lastHour = hour;
141146

142-
const interval = (this.frequent ? 5 : 15);
147+
let interval = (this.frequent ? 5 : 15);
148+
149+
if (this.isTimeAccelerated())
150+
interval *= debugTimeRate;
151+
143152
const runningLate = (this.lastForecast + interval * 60000 <= now);
144153
const minuteOffset = (this.frequent ? 0 : this.pollingMinute);
145154
const millisOffset = (this.frequent || forceRefresh || runningLate ? 0 : this.pollingMillis);

src/styles.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ $constellation-font: "Apple Symbols", "Arial Unicode MS", "MS Gothic", sans-seri
44
$dialog-font: Arial, sans-serif;
55
$planet-grid: #369;
66
$clock-border: #69C;
7+
$risen-track: rgba(102, 204, 153, 0.5);
78

89
html {
910
width: 100%;
@@ -361,6 +362,11 @@ input, button, select, textarea, optgroup, option { // Ignored by macOS Chrome f
361362
fill: none;
362363
}
363364

365+
.risen-track {
366+
stroke: $risen-track;
367+
stroke-width: 0.5;
368+
}
369+
364370
.constellation {
365371
font-family: $constellation-font;
366372
font-size: 2.5px;

src/util.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import * as $ from 'jquery';
2121
import { isEdge, isSafari } from 'ks-util';
22+
import { cos_deg, Point, sin_deg } from 'ks-math';
2223

2324
export type KeyListener = (KeyboardEvent) => void;
2425

@@ -94,3 +95,21 @@ export function setSvgHref(elem: JQuery, href: string) {
9495
});
9596
}
9697
}
98+
99+
export function polarToRectangular(cx: number, cy: number, radius: number, angleInDegrees: number): Point {
100+
return {
101+
x: cx + radius * cos_deg(angleInDegrees),
102+
y: cy + radius * sin_deg(angleInDegrees)
103+
};
104+
}
105+
106+
export function describeArc(x: number, y: number, radius: number, startAngle: number, endAngle: number): string {
107+
const start = polarToRectangular(x, y, radius, startAngle);
108+
const end = polarToRectangular(x, y, radius, endAngle);
109+
const largeArcFlag = (endAngle - startAngle <= 180 ? 0 : 1);
110+
111+
return [
112+
'M', start.x, start.y,
113+
'A', radius, radius, 0, largeArcFlag, 1, end.x, end.y
114+
].join(' ');
115+
}

tslint.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"no-trailing-whitespace": true,
7171
"no-unnecessary-initializer": true,
7272
"no-unused-expression": true,
73-
"no-use-before-declare": true,
73+
"no-use-before-declare": false,
7474
"no-var-keyword": true,
7575
"object-literal-sort-keys": false,
7676
"one-line": [

0 commit comments

Comments
 (0)