Files
skyview.astronomiemuseum.de/public/geocron/plugin-ui.js
T
2026-04-02 15:40:06 +02:00

191 lines
7.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* plugin-ui.js – Layer-Steuerung (ein-/ausblenden)
* ====================================================
* Abhängigkeit: earth-core.js
*/
(function () {
const LAYERS = [
{ name: "Nacht & Dämmerung", canvasIds: ["nightCanvas", "terminatorCanvas"], defaultOn: true },
{ name: "Wolken", canvasIds: ["cloudCanvas"], defaultOn: false },
{ name: "Aurora", canvasIds: ["auroraCanvas"], defaultOn: false },
{ name: "Satelliten", canvasIds: ["orbitCanvas"], defaultOn: true },
{ name: "Sonne", canvasIds: ["sunCanvas"], defaultOn: true },
{ name: "Mond", canvasIds: ["moonCanvas"], defaultOn: true },
{ name: "Erdbeben", canvasIds: ["earthquakeCanvas"], defaultOn: false },
{ name: "Ortsmarker", canvasIds: ["markersCanvas"], defaultOn: false },
];
const CFG = {
TITLE: "Layer",
ACCENT: "#4a9eff",
ACCENT_OFF: "rgba(50, 60, 90, 0.9)",
};
// ── pendingVisibility und setVisibility VOR dem UI-Aufbau ──────
const pendingVisibility = new Map();
function setVisibility(layer, on) {
layer.canvasIds.forEach(id => {
const el = document.getElementById(id);
if (el) {
el.style.display = on ? "block" : "none";
} else {
pendingVisibility.set(id, on);
}
});
}
const observer = new MutationObserver(mutations => {
for (const mut of mutations) {
for (const node of mut.addedNodes) {
if (node.id && pendingVisibility.has(node.id)) {
node.style.display = pendingVisibility.get(node.id) ? "block" : "none";
pendingVisibility.delete(node.id);
}
}
}
if (pendingVisibility.size === 0) observer.disconnect();
});
observer.observe(document.getElementById("earth-wrapper") || document.body, {
childList: true, subtree: true,
});
// ── CSS ────────────────────────────────────────────────────────
const style = document.createElement("style");
style.textContent = `
#earth-ui {
position: absolute; bottom: 14px; left: 14px; z-index: 9999;
background: rgba(6, 10, 22, 0.78);
border: 1px solid rgba(80, 110, 190, 0.28);
border-radius: 8px; padding: 7px 10px;
font: 11px/1.4 system-ui, -apple-system, sans-serif;
color: rgba(190, 210, 255, 0.88);
user-select: none; min-width: 140px;
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
box-shadow: 0 2px 16px rgba(0,0,0,0.5);
opacity: 0.75; transition: opacity 0.2s;
}
#earth-ui:hover { opacity: 1; }
#earth-ui-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 6px; cursor: pointer; gap: 8px;
}
#earth-ui-title {
font-weight: 600; font-size: 10px;
letter-spacing: 0.1em; text-transform: uppercase;
color: rgba(140, 170, 255, 0.75);
}
#earth-ui-chevron {
font-size: 8px; color: rgba(100, 120, 180, 0.6);
transition: transform 0.2s;
}
#earth-ui-chevron.collapsed { transform: rotate(-90deg); }
#earth-ui-rows {
display: flex; flex-direction: column; gap: 4px;
overflow: hidden; max-height: 300px; opacity: 1;
transition: max-height 0.2s ease, opacity 0.15s;
}
#earth-ui-rows.collapsed { max-height: 0; opacity: 0; }
.earth-ui-row {
display: flex; align-items: center;
justify-content: space-between; gap: 8px;
}
.earth-ui-label {
font-size: 11px; color: rgba(190, 210, 255, 0.85);
transition: color 0.15s; flex: 1; cursor: pointer;
}
.earth-ui-label:hover { color: #fff; }
.earth-ui-label.off { color: rgba(100, 115, 155, 0.65); }
/* Schmaler Toggle: 28×15px */
.earth-ui-toggle { position: relative; width: 28px; height: 15px; flex-shrink: 0; }
.earth-ui-toggle input { opacity: 0; width: 0; height: 0; position: absolute; }
.earth-ui-slider {
position: absolute; inset: 0; border-radius: 15px;
background: ${CFG.ACCENT_OFF}; transition: background 0.18s; cursor: pointer;
}
.earth-ui-slider::before {
content: ""; position: absolute;
width: 10px; height: 10px; left: 2.5px; top: 50%;
transform: translateY(-50%); border-radius: 50%;
background: rgba(160, 175, 210, 0.8);
transition: left 0.18s, background 0.18s;
}
.earth-ui-toggle input:checked + .earth-ui-slider { background: ${CFG.ACCENT}; }
.earth-ui-toggle input:checked + .earth-ui-slider::before {
left: 15.5px; background: #fff;
}
`;
document.head.appendChild(style);
// ── Panel ──────────────────────────────────────────────────────
const panel = document.createElement("div");
panel.id = "earth-ui";
const header = document.createElement("div");
header.id = "earth-ui-header";
header.innerHTML = `
<span id="earth-ui-title">${CFG.TITLE}</span>
<span id="earth-ui-chevron">▼</span>
`;
panel.appendChild(header);
const rows = document.createElement("div");
rows.id = "earth-ui-rows";
panel.appendChild(rows);
let collapsed = false;
header.addEventListener("click", () => {
collapsed = !collapsed;
rows.classList.toggle("collapsed", collapsed);
document.getElementById("earth-ui-chevron").classList.toggle("collapsed", collapsed);
});
// ── Rows ───────────────────────────────────────────────────────
LAYERS.forEach(layer => {
const row = document.createElement("div");
row.className = "earth-ui-row";
const label = document.createElement("span");
label.className = "earth-ui-label";
label.textContent = layer.name;
const toggleWrap = document.createElement("label");
toggleWrap.className = "earth-ui-toggle";
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = layer.defaultOn;
const slider = document.createElement("span");
slider.className = "earth-ui-slider";
toggleWrap.appendChild(checkbox);
toggleWrap.appendChild(slider);
row.appendChild(label);
row.appendChild(toggleWrap);
rows.appendChild(row);
setVisibility(layer, layer.defaultOn);
if (!layer.defaultOn) label.classList.add("off");
checkbox.addEventListener("change", () => {
setVisibility(layer, checkbox.checked);
label.classList.toggle("off", !checkbox.checked);
});
label.addEventListener("click", () => {
checkbox.checked = !checkbox.checked;
checkbox.dispatchEvent(new Event("change"));
});
});
(document.getElementById("earth-wrapper") || document.body).appendChild(panel);
}());