Add monoline icons to the topbar coordinates/sun readout
WAYPOINT_ICON (coords) and PENDING_ICON (countdown) reused as-is; two new
hand-drawn SUNRISE_ICON/SUNSET_ICON since NPS's symbol set has no match —
same currentColor stroke style as the rest of icons.js, so they render
monochrome in the dark topbar rather than colored emoji.
sun.js's formatSunInfo now returns {sunrise, sunset, countdown} instead of
one joined string, so map.js can place its own icon in front of each
piece instead of the module owning any markup.
This commit is contained in:
1 parent
b5466b53e4
commit
a5adb39770
4 files changed
+63
-6
No files matched your search
@@ -36,11 +36,36 @@ html, body {
|
|||||||
|
|
||||||
.topbar__coords,
|
.topbar__coords,
|
||||||
.topbar__sun {
|
.topbar__sun {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
color: #bbb;
|
color: #bbb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.topbar__sun {
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar__group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar__icon {
|
||||||
|
display: flex;
|
||||||
|
width: 13px;
|
||||||
|
height: 13px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar__icon svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.topbar__coords {
|
.topbar__coords {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,25 @@ export const RULER_ICON = `
|
|||||||
<path d="M9 10l1.5 1.5M12 7l1.5 1.5M15 4l1.5 1.5M6 13l1.5 1.5"/>
|
<path d="M9 10l1.5 1.5M12 7l1.5 1.5M15 4l1.5 1.5M6 13l1.5 1.5"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
||||||
|
// Toolbar readout glyphs (public/js/sun.js's text, assembled with these by
|
||||||
|
// map.js) — same monoline style as the sidebar icons above, no NPS source
|
||||||
|
// for either (that set has no sunrise/sunset pictogram).
|
||||||
|
export const SUNRISE_ICON = `
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M3 18h18"/>
|
||||||
|
<path d="M6 18a6 6 0 0 1 12 0"/>
|
||||||
|
<path d="M12 13V5"/>
|
||||||
|
<path d="M9 8l3-3 3 3"/>
|
||||||
|
</svg>`;
|
||||||
|
|
||||||
|
export const SUNSET_ICON = `
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M3 18h18"/>
|
||||||
|
<path d="M6 18a6 6 0 0 1 12 0"/>
|
||||||
|
<path d="M12 5v8"/>
|
||||||
|
<path d="M9 10l3 3 3-3"/>
|
||||||
|
</svg>`;
|
||||||
|
|
||||||
export const NEW_FOLDER_ICON = `
|
export const NEW_FOLDER_ICON = `
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z"/>
|
<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7z"/>
|
||||||
|
|||||||
+11
-3
@@ -14,7 +14,7 @@ import { MeasureControl } from "/js/measure.js";
|
|||||||
import { NotesControl } from "/js/notes.js";
|
import { NotesControl } from "/js/notes.js";
|
||||||
import { PluginsControl } from "/js/plugins.js";
|
import { PluginsControl } from "/js/plugins.js";
|
||||||
import { LocateControl } from "/js/locate.js";
|
import { LocateControl } from "/js/locate.js";
|
||||||
import { LAYERS_ICON } from "/js/icons.js";
|
import { LAYERS_ICON, WAYPOINT_ICON, SUNRISE_ICON, SUNSET_ICON, PENDING_ICON } from "/js/icons.js";
|
||||||
import { formatCoords, formatSunInfo } from "/js/sun.js";
|
import { formatCoords, formatSunInfo } from "/js/sun.js";
|
||||||
import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
|
import { notifySidePanelOpen, onlyOneSidePanelOpen } from "/js/panels.js";
|
||||||
import { isLoggedIn } from "/js/auth.js";
|
import { isLoggedIn } from "/js/auth.js";
|
||||||
@@ -448,7 +448,7 @@ map.once("style.load", () => {
|
|||||||
const coordsLabel = document.querySelector(".topbar__coords");
|
const coordsLabel = document.querySelector(".topbar__coords");
|
||||||
const updateCoords = () => {
|
const updateCoords = () => {
|
||||||
const { lng, lat } = map.getCenter();
|
const { lng, lat } = map.getCenter();
|
||||||
coordsLabel.textContent = formatCoords(lat, lng);
|
coordsLabel.innerHTML = `<span class="topbar__icon">${WAYPOINT_ICON}</span><span>${formatCoords(lat, lng)}</span>`;
|
||||||
};
|
};
|
||||||
updateCoords();
|
updateCoords();
|
||||||
map.on("move", updateCoords);
|
map.on("move", updateCoords);
|
||||||
@@ -477,8 +477,16 @@ const sunLabel = document.querySelector(".topbar__sun");
|
|||||||
const updateSun = () => {
|
const updateSun = () => {
|
||||||
const { lng, lat } = map.getCenter();
|
const { lng, lat } = map.getCenter();
|
||||||
const info = formatSunInfo(lat, lng);
|
const info = formatSunInfo(lat, lng);
|
||||||
sunLabel.textContent = info ?? "";
|
|
||||||
sunLabel.hidden = info === null;
|
sunLabel.hidden = info === null;
|
||||||
|
if (!info) return;
|
||||||
|
|
||||||
|
const countdownGroup = info.countdown
|
||||||
|
? `<span class="topbar__group"><span class="topbar__icon">${PENDING_ICON}</span><span>${info.countdown}</span></span>`
|
||||||
|
: "";
|
||||||
|
sunLabel.innerHTML =
|
||||||
|
`<span class="topbar__group"><span class="topbar__icon">${SUNRISE_ICON}</span><span>${info.sunrise}</span></span>` +
|
||||||
|
`<span class="topbar__group"><span class="topbar__icon">${SUNSET_ICON}</span><span>${info.sunset}</span></span>` +
|
||||||
|
countdownGroup;
|
||||||
};
|
};
|
||||||
updateSun();
|
updateSun();
|
||||||
map.on("moveend", updateSun);
|
map.on("moveend", updateSun);
|
||||||
|
|||||||
+8
-3
@@ -45,7 +45,9 @@ const DAY_MS = 24 * 60 * 60 * 1000;
|
|||||||
// null when there's no sunrise/sunset to show at all — getTimes returns
|
// null when there's no sunrise/sunset to show at all — getTimes returns
|
||||||
// null (not Invalid Date) for both on a polar day/night, per its own
|
// null (not Invalid Date) for both on a polar day/night, per its own
|
||||||
// comment in suncalc.js — the caller just hides the readout in that case
|
// comment in suncalc.js — the caller just hides the readout in that case
|
||||||
// rather than showing something misleading.
|
// rather than showing something misleading. Returns the three pieces
|
||||||
|
// separately (not one joined string) so the caller can put its own icon in
|
||||||
|
// front of each rather than this module owning any markup.
|
||||||
export function formatSunInfo(lat, lng, now = new Date()) {
|
export function formatSunInfo(lat, lng, now = new Date()) {
|
||||||
const today = getTimes(now, lat, lng);
|
const today = getTimes(now, lat, lng);
|
||||||
if (today.sunrise === null || today.sunset === null) return null;
|
if (today.sunrise === null || today.sunset === null) return null;
|
||||||
@@ -61,6 +63,9 @@ export function formatSunInfo(lat, lng, now = new Date()) {
|
|||||||
next = tomorrow.sunrise === null ? null : { label: "sunrise", at: tomorrow.sunrise };
|
next = tomorrow.sunrise === null ? null : { label: "sunrise", at: tomorrow.sunrise };
|
||||||
}
|
}
|
||||||
|
|
||||||
const countdown = next ? ` · ${formatCountdown(next.at - now)} to ${next.label}` : "";
|
return {
|
||||||
return `${formatTime(today.sunrise)}–${formatTime(today.sunset)}${countdown}`;
|
sunrise: formatTime(today.sunrise),
|
||||||
|
sunset: formatTime(today.sunset),
|
||||||
|
countdown: next ? `${formatCountdown(next.at - now)} to ${next.label}` : null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user