245 lines
7.3 KiB
JavaScript
245 lines
7.3 KiB
JavaScript
const DEFAULT_OPTIONS = {showSeconds: true}
|
|
const HOUR_NAMES = [
|
|
"Candle", "Ice", "Comet", "Owl", "Yarn", "Mist",
|
|
"Sprout", "Rainbow", "Worm", "Rabbit", "Blossom", "Nest",
|
|
"Coral", "Cherry", "Bee", "Melon", "Seashell", "Dragon",
|
|
"Chestnut", "Kite", "Mushroom", "Lightning", "Mountain", "Lantern",
|
|
];
|
|
const HOUR_WIDTH = 70;
|
|
const HOUR_ICONS = [
|
|
"🕯️️", "❄️️", "☄️️", "🦉️", "🧶️", "🌫️️",
|
|
"🌱️", "🌈️", "🪱️", "🐇️", "🌸️", "🪺️",
|
|
"🪸️", "🍒️", "🐝️", "🍉️", "🐚️", "🐉️",
|
|
"🌰️", "🪁️", "🍄️", "⚡️️", "⛰️️", "🏮️",
|
|
];
|
|
|
|
const loadSettings = () => {
|
|
var loadedOpts;
|
|
|
|
try {
|
|
var data = localStorage.getItem("options");
|
|
console.debug("Loaded", data);
|
|
loadedOpts = JSON.parse(data);
|
|
} catch (e) {
|
|
loadedOpts = null;
|
|
}
|
|
|
|
console.debug("Parsed as", loadedOpts);
|
|
|
|
return loadedOpts || DEFAULT_OPTIONS;
|
|
};
|
|
|
|
const saveSettings = () => {
|
|
console.debug("Saving", options)
|
|
localStorage.setItem("options", JSON.stringify(options));
|
|
};
|
|
|
|
const zeroPad = (num, numZeros) => {
|
|
if (num == 0) {
|
|
return "".padStart(numZeros, "0")
|
|
}
|
|
|
|
var an = Math.abs (num);
|
|
var digitCount = 1 + Math.floor (Math.log (an) / Math.LN10);
|
|
|
|
if (digitCount >= numZeros) {
|
|
return String(num);
|
|
}
|
|
|
|
var zeroString = Math.pow (10, numZeros - digitCount).toString ().substr (1);
|
|
|
|
return num < 0 ? "-" + zeroString + an : zeroString + an;
|
|
};
|
|
|
|
const updateClock = () => {
|
|
var docCenter = document.body.offsetWidth / 2;
|
|
var momentNow = moment();
|
|
|
|
var momentUTC = momentNow.utc();
|
|
var utcHour = momentUTC.hours();
|
|
var utcMinute = momentUTC.minutes();
|
|
|
|
var momentLocal = momentNow.tz(options.timezone);
|
|
var localHour = momentLocal.hours();
|
|
var localMinute = momentLocal.minutes();
|
|
|
|
currentTimeContainer.innerHTML = (
|
|
HOUR_ICONS[utcHour]
|
|
+ "<br>"
|
|
+ momentLocal.locale(options.locale).format(options.showSeconds ? "LTS" : "LT")
|
|
+ "<br>"
|
|
+ HOUR_NAMES[utcHour]
|
|
);
|
|
|
|
var utcOffset = (
|
|
24 * HOUR_WIDTH
|
|
+ utcHour * HOUR_WIDTH
|
|
+ utcMinute * HOUR_WIDTH / 60
|
|
);
|
|
var localOffset = (
|
|
24 * HOUR_WIDTH
|
|
+ localHour * HOUR_WIDTH
|
|
+ localMinute * HOUR_WIDTH / 60
|
|
);
|
|
|
|
utcHourContainer.style.left = (docCenter - utcOffset - HOUR_WIDTH / 2) + "px";
|
|
hourNameContainer.style.left = (docCenter - utcOffset) + "px";
|
|
hourIconContainer.style.left = (docCenter - utcOffset) + "px";
|
|
localHourContainer.style.left = (docCenter - localOffset - HOUR_WIDTH / 2) + "px";
|
|
marker.style.left = docCenter + "px";
|
|
|
|
for (var nameSpan of document.getElementsByClassName("active")) {
|
|
nameSpan.classList.remove("active");
|
|
}
|
|
|
|
var currentNameSpan = document.getElementById("h-present-" + utcHour);
|
|
currentNameSpan.classList.add("active");
|
|
};
|
|
|
|
const showSettingsPanel = () => {
|
|
settingsPanel.style.display = "block";
|
|
};
|
|
|
|
const hideSettingsPanel = () => {
|
|
settingsPanel.style.display = "none";
|
|
};
|
|
|
|
const createClock = () => {
|
|
for (round = 0; round < 3; round++) {
|
|
let prefix;
|
|
switch (round) {
|
|
case 0:
|
|
prefix = "past";
|
|
break;
|
|
case 1:
|
|
prefix = "present";
|
|
break;
|
|
case 2:
|
|
prefix = "future";
|
|
break;
|
|
}
|
|
for (hour = 0; hour < 24; hour++) {
|
|
var nameClass;
|
|
|
|
if (hour < 6) {
|
|
nameClass = "winter";
|
|
} else if (hour < 12) {
|
|
nameClass = "spring";
|
|
} else if (hour < 18) {
|
|
nameClass = "summer";
|
|
} else {
|
|
nameClass = "autumn";
|
|
}
|
|
|
|
let utcSpan = document.createElement("span");
|
|
utcSpan.id = "u-" + prefix + "-" + hour;
|
|
utcSpan.innerHTML = "U " + zeroPad(hour, 2);
|
|
utcHourContainer.appendChild(utcSpan);
|
|
|
|
let localSpan = document.createElement("span");
|
|
localSpan.id = "l-" + prefix + "-" + hour;
|
|
localSpan.innerHTML = zeroPad(hour, 2);
|
|
localHourContainer.appendChild(localSpan);
|
|
|
|
let hourNameSpan = document.createElement("span");
|
|
hourNameSpan.id = "h-" + prefix + "-" + hour;
|
|
hourNameSpan.classList.add(nameClass);
|
|
hourNameSpan.innerHTML = HOUR_NAMES[hour];
|
|
hourNameContainer.appendChild(hourNameSpan);
|
|
|
|
let hourIconSpan = document.createElement("span");
|
|
hourIconSpan.id = "i-" + prefix + "-" + hour;
|
|
hourIconSpan.classList.add(nameClass);
|
|
hourIconSpan.innerHTML = HOUR_ICONS[hour];
|
|
hourIconContainer.appendChild(hourIconSpan);
|
|
}
|
|
}
|
|
};
|
|
|
|
const initSettings = () => {
|
|
var timeZoneSelector = document.getElementById("timezone-selector");
|
|
|
|
if (!options.timezone) {
|
|
options.timezone = moment.tz.guess();
|
|
}
|
|
|
|
for (tzname of moment.tz.names()) {
|
|
var tzElem = document.createElement("option");
|
|
tzElem.innerHTML = tzname;
|
|
|
|
if (tzname == options.timezone) {
|
|
tzElem.selected = true;
|
|
}
|
|
|
|
timeZoneSelector.appendChild(tzElem);
|
|
}
|
|
|
|
timeZoneSelector.addEventListener("change", () => {
|
|
options.timezone = timeZoneSelector.value;
|
|
console.log(options)
|
|
updateClock();
|
|
saveSettings();
|
|
})
|
|
|
|
var localeSelector = document.getElementById("locale-selector");
|
|
|
|
if (!options.locale) {
|
|
options.locale = moment.locale();
|
|
}
|
|
|
|
for (localename of moment.locales()) {
|
|
var locElem = document.createElement("option");
|
|
locElem.innerHTML = localename;
|
|
|
|
if (localename == options.locale) {
|
|
locElem.selected = true;
|
|
}
|
|
|
|
localeSelector.appendChild(locElem);
|
|
}
|
|
|
|
localeSelector.addEventListener("change", () => {
|
|
options.locale = localeSelector.value;
|
|
updateClock();
|
|
saveSettings();
|
|
});
|
|
|
|
var showSecondsOption = document.getElementById("show-seconds-option");
|
|
|
|
showSecondsOption.checked = options.showSeconds;
|
|
|
|
showSecondsOption.addEventListener("click", () => {
|
|
options.showSeconds = showSecondsOption.checked;
|
|
updateClock();
|
|
saveSettings();
|
|
});
|
|
|
|
showSettingsButton.addEventListener("click", showSettingsPanel);
|
|
closeSettingsButton.addEventListener("click", hideSettingsPanel);
|
|
}
|
|
|
|
const run = () => {
|
|
document.documentElement.style.setProperty("--hour-width", HOUR_WIDTH + "px");
|
|
|
|
createClock();
|
|
initSettings();
|
|
|
|
addEventListener("resize", updateClock);
|
|
updateClock();
|
|
setInterval(updateClock, 1000);
|
|
}
|
|
|
|
var options = loadSettings();
|
|
|
|
let utcHourContainer = document.getElementById("utc-hours-inner");
|
|
let hourNameContainer = document.getElementById("hour-names-inner");
|
|
let hourIconContainer = document.getElementById("hour-icons-inner");
|
|
let localHourContainer = document.getElementById("local-hours-inner");
|
|
let currentTimeContainer = document.getElementById("current-time");
|
|
let showSettingsButton = document.getElementById("settings-button");
|
|
let closeSettingsButton = document.getElementById("settings-close");
|
|
let settingsPanel = document.getElementById("settings-wrapper")
|
|
let marker = document.getElementById("marker");
|
|
|
|
run();
|