Changes to the Statusdisplay

This commit is contained in:
Carsten Graf
2026-01-24 14:51:33 +01:00
parent 77f1ebc1f1
commit 5ef5e6d636
3 changed files with 150 additions and 5 deletions

View File

@@ -376,9 +376,10 @@ body {
transition: transform 0.3s ease; transition: transform 0.3s ease;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: flex-start;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
position: relative;
} }
.lane h2 { .lane h2 {
@@ -388,6 +389,7 @@ body {
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
font-family: "Segoe UI", Arial, sans-serif; font-family: "Segoe UI", Arial, sans-serif;
flex-shrink: 0;
} }
.swimmer-name { .swimmer-name {
@@ -426,6 +428,10 @@ body {
font-family: "Courier New", monospace; font-family: "Courier New", monospace;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
line-height: 1; line-height: 1;
position: relative;
z-index: 1;
flex-shrink: 0;
order: 1;
} }
.status { .status {
@@ -435,6 +441,34 @@ body {
border-radius: 20px; border-radius: 20px;
display: inline-block; display: inline-block;
font-weight: 600; font-weight: 600;
position: relative;
z-index: 2;
}
.status:not(.large-status) {
position: relative;
order: 2;
margin-top: auto;
}
.status.large-status {
font-size: clamp(1.8rem, 5vw, 5rem);
position: absolute;
left: 50%;
transform: translateX(-50%);
z-index: 10;
margin: 0 !important;
padding: clamp(8px, 1.5vh, 15px) clamp(15px, 3vw, 30px);
white-space: normal;
pointer-events: none;
text-align: center;
background-color: rgba(0, 0, 0, 0.85) !important;
backdrop-filter: blur(5px);
width: calc(100% - 40px);
max-width: calc(100% - 40px);
word-wrap: break-word;
line-height: 1.3;
overflow: visible;
} }
.status.finished { .status.finished {

View File

@@ -56,19 +56,19 @@
<div class="lane"> <div class="lane">
<div id="name1" class="swimmer-name" style="display: none"></div> <div id="name1" class="swimmer-name" style="display: none"></div>
<h2>🏊‍♀️ Bahn 1</h2> <h2>🏊‍♀️ Bahn 1</h2>
<div id="time1" class="time-display">00.00</div>
<div id="status1" class="status standby"> <div id="status1" class="status standby">
Standby: Drücke beide Buttons einmal Standby: Drücke beide Buttons einmal
</div> </div>
<div id="time1" class="time-display">00.00</div>
</div> </div>
<div class="lane"> <div class="lane">
<div id="name2" class="swimmer-name" style="display: none"></div> <div id="name2" class="swimmer-name" style="display: none"></div>
<h2>🏊‍♂️ Bahn 2</h2> <h2>🏊‍♂️ Bahn 2</h2>
<div id="time2" class="time-display">00.00</div>
<div id="status2" class="status standby"> <div id="status2" class="status standby">
Standby: Drücke beide Buttons einmal Standby: Drücke beide Buttons einmal
</div> </div>
<div id="time2" class="time-display">00.00</div>
</div> </div>
</div> </div>
@@ -442,12 +442,66 @@
document.getElementById("time1").textContent = formatTime(display1); document.getElementById("time1").textContent = formatTime(display1);
const time1Element = document.getElementById("time1");
const lane1Element = time1Element.closest(".lane");
const h2_1 = lane1Element.querySelector("h2");
if (!lane1Connected) { if (!lane1Connected) {
s1.className = "status standby"; s1.className = "status standby large-status";
s1.textContent = "Standby: Drücke beide Buttons einmal"; s1.textContent = "Standby: Drücke beide Buttons einmal";
// Position über time-display, aber innerhalb des Containers
if (s1.classList.contains("large-status")) {
const time1Rect = time1Element.getBoundingClientRect();
const lane1Rect = lane1Element.getBoundingClientRect();
const h2Rect = h2_1.getBoundingClientRect();
const time1Center = time1Rect.top - lane1Rect.top + time1Rect.height / 2;
const h2Bottom = h2Rect.bottom - lane1Rect.top;
// Stelle sicher, dass die obere Kante der Status-Box unter h2 beginnt
// Beginne unter h2 (ohne translate(-50%, -50%) beginnt die Box von oben)
const startTop = h2Bottom + 10;
// Positioniere so, dass die Box über time-display zentriert ist, aber nicht über h2 hinausragt
// Berechne die benötigte Höhe, um über time-display zentriert zu sein
const statusHeight = s1.offsetHeight || 200; // Verwende tatsächliche Höhe oder Schätzwert
const targetTop = Math.max(startTop, time1Center - statusHeight / 2);
s1.style.top = targetTop + "px";
s1.style.transform = "translateX(-50%)";
// Stelle sicher, dass die Box innerhalb des Containers bleibt
const maxHeight = lane1Rect.height - targetTop - 30;
s1.style.maxHeight = maxHeight + "px";
s1.style.overflow = "auto";
}
} else { } else {
s1.className = `status ${status1}`; s1.className = `status ${status1}`;
// Add large-status class if not running and not finished
if (status1 !== "running" && status1 !== "finished") {
s1.classList.add("large-status");
// Position über time-display, aber innerhalb des Containers
const time1Rect = time1Element.getBoundingClientRect();
const lane1Rect = lane1Element.getBoundingClientRect();
const h2Rect = h2_1.getBoundingClientRect();
const time1Center = time1Rect.top - lane1Rect.top + time1Rect.height / 2;
const h2Bottom = h2Rect.bottom - lane1Rect.top;
// Stelle sicher, dass die obere Kante der Status-Box unter h2 beginnt
// Beginne unter h2 (ohne translate(-50%, -50%) beginnt die Box von oben)
const startTop = h2Bottom + 10;
// Positioniere so, dass die Box über time-display zentriert ist, aber nicht über h2 hinausragt
// Berechne die benötigte Höhe, um über time-display zentriert zu sein
const statusHeight = s1.offsetHeight || 200; // Verwende tatsächliche Höhe oder Schätzwert
const targetTop = Math.max(startTop, time1Center - statusHeight / 2);
s1.style.top = targetTop + "px";
s1.style.transform = "translateX(-50%)";
// Stelle sicher, dass die Box innerhalb des Containers bleibt
const maxHeight = lane1Rect.height - targetTop - 30;
s1.style.maxHeight = maxHeight + "px";
s1.style.overflow = "auto";
} else {
s1.classList.remove("large-status");
s1.style.top = "";
s1.style.transform = "";
s1.style.maxHeight = "";
}
switch (status1) { switch (status1) {
case "ready": case "ready":
s1.textContent = "Bereit für den Start!"; s1.textContent = "Bereit für den Start!";
@@ -468,12 +522,66 @@
document.getElementById("time2").textContent = formatTime(display2); document.getElementById("time2").textContent = formatTime(display2);
const time2Element = document.getElementById("time2");
const lane2Element = time2Element.closest(".lane");
const h2_2 = lane2Element.querySelector("h2");
if (!lane2Connected) { if (!lane2Connected) {
s2.className = "status standby"; s2.className = "status standby large-status";
s2.textContent = "Standby: Drücke beide Buttons einmal"; s2.textContent = "Standby: Drücke beide Buttons einmal";
// Position über time-display, aber innerhalb des Containers
if (s2.classList.contains("large-status")) {
const time2Rect = time2Element.getBoundingClientRect();
const lane2Rect = lane2Element.getBoundingClientRect();
const h2Rect = h2_2.getBoundingClientRect();
const time2Center = time2Rect.top - lane2Rect.top + time2Rect.height / 2;
const h2Bottom = h2Rect.bottom - lane2Rect.top;
// Stelle sicher, dass die obere Kante der Status-Box unter h2 beginnt
// Beginne unter h2 (ohne translate(-50%, -50%) beginnt die Box von oben)
const startTop = h2Bottom + 10;
// Positioniere so, dass die Box über time-display zentriert ist, aber nicht über h2 hinausragt
// Berechne die benötigte Höhe, um über time-display zentriert zu sein
const statusHeight = s2.offsetHeight || 200; // Verwende tatsächliche Höhe oder Schätzwert
const targetTop = Math.max(startTop, time2Center - statusHeight / 2);
s2.style.top = targetTop + "px";
s2.style.transform = "translateX(-50%)";
// Stelle sicher, dass die Box innerhalb des Containers bleibt
const maxHeight = lane2Rect.height - targetTop - 30;
s2.style.maxHeight = maxHeight + "px";
s2.style.overflow = "auto";
}
} else { } else {
s2.className = `status ${status2}`; s2.className = `status ${status2}`;
// Add large-status class if not running and not finished
if (status2 !== "running" && status2 !== "finished") {
s2.classList.add("large-status");
// Position über time-display, aber innerhalb des Containers
const time2Rect = time2Element.getBoundingClientRect();
const lane2Rect = lane2Element.getBoundingClientRect();
const h2Rect = h2_2.getBoundingClientRect();
// Stelle sicher, dass die obere Kante der Status-Box unter h2 beginnt
const h2Bottom = h2Rect.bottom - lane2Rect.top;
const time2Center = time2Rect.top - lane2Rect.top + time2Rect.height / 2;
// Beginne unter h2 (ohne translate(-50%, -50%) beginnt die Box von oben)
const startTop = h2Bottom + 10;
// Positioniere so, dass die Box über time-display zentriert ist, aber nicht über h2 hinausragt
// Berechne die benötigte Höhe, um über time-display zentriert zu sein
const statusHeight = s2.offsetHeight || 200; // Verwende tatsächliche Höhe oder Schätzwert
const targetTop = Math.max(startTop, time2Center - statusHeight / 2);
s2.style.top = targetTop + "px";
s2.style.transform = "translateX(-50%)";
// Stelle sicher, dass die Box innerhalb des Containers bleibt
const maxHeight = lane2Rect.height - targetTop - 30;
s2.style.maxHeight = maxHeight + "px";
s2.style.overflow = "auto";
} else {
s2.classList.remove("large-status");
s2.style.top = "";
s2.style.transform = "";
s2.style.maxHeight = "";
}
switch (status2) { switch (status2) {
case "ready": case "ready":
s2.textContent = "Bereit für den Start!"; s2.textContent = "Bereit für den Start!";

View File

@@ -22,6 +22,9 @@ monitor_speed = 115200
build_flags = build_flags =
-DBOARD_HAS_PSRAM -DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue -mfix-esp32-psram-cache-issue
-DBATTERY_PIN=16
board_upload.flash_size = 16MB
board_build.partitions = default_16MB.csv
targets = uploadfs targets = uploadfs
board_build.psram = disabled board_build.psram = disabled
lib_deps = lib_deps =