import {div, h2, li} from './lib/html.js';
import {node} from './lib/nodes.js';
import {animateTransform, circle, defs, line, svg, use} from './lib/svg.js';
const unix = () => (Date.now() / 1000) | 0,
formatNumber = (n: number) => ((n | 0) + "").padStart(2, "0"),
tickers: Clock[] = [];
setInterval(() => {
const now = unix();
for (const ticker of tickers) {
ticker.tick(now);
}
}, 1000);
export default class Clock {
#node: HTMLLIElement;
#time: HTMLDivElement;
#offset: number;
#name: string;
constructor(name: string, offset: number) {
this.#offset = offset;
this.#name = name;
const now = unix(),
begin = "-" + (now + offset);
this.#node = li([
h2(name),
svg({"viewBox": "0 0 100 100"}, [
defs(line({"id": "marker", "x1": 50, "x2": 50, "y1": 1, "y2": 10, "stroke": "currentColor", "opacity": 0.5})),
circle({"cx": 50, "cy": 50, "r": 48, "fill": "none", "stroke": "currentColor", "style": "fill: var(--bg)", "stroke-width": 4}),
Array.from({"length": 12}, (_, n) => use({"href": "#marker", "transform": `rotate(${30 * n} 50 50)`})),
line({"x1": 50, "y1": 50, "x2": 50, "y2": 20, "stroke": "currentColor", "stroke-width": 4, "stroke-linecap": "round"}, animateTransform({"attributeName": "transform", "attributeType": "XML", "type": "rotate", "from": "0 50 50", "to": "360 50 50", "dur": "12h", "repeatCount": "indefinite", begin})),
line({"x1": 50, "y1": 50, "x2": 50, "y2": 10, "stroke": "currentColor", "stroke-width": 2, "stroke-linecap": "round"}, animateTransform({"attributeName": "transform", "attributeType": "XML", "type": "rotate", "from": "0 50 50", "to": "360 50 50", "dur": "1h", "repeatCount": "indefinite", begin})),
line({"x1": 50, "y1": 50, "x2": 50, "y2": 5, "stroke": "#800", "stroke-width": 1, "stroke-linecap": "round"}, animateTransform({"attributeName": "transform", "attributeType": "XML", "type": "rotate", "from": "0 50 50", "to": "360 50 50", "dur": "60s", "repeatCount": "indefinite", begin})),
circle({"cx": 50, "cy": 50, "r": 1, "fill": "#d4af37"})
]),
this.#time = div()
]);
tickers.push(this);
this.tick(now);
}
get [node]() {
return this.#node;
}
get name() {
return this.#name;
}
tick(now: number) {
const timestamp = now + this.#offset;
this.#time.textContent = `${formatNumber((timestamp % 86400) / 3600)}:${formatNumber((timestamp % 3600) / 60)}:${formatNumber(timestamp % 60)}`;
}
remove() {
const pos = tickers.indexOf(this);
if (pos >= 0) {
tickers.splice(pos, 1);
}
}
}