add predict bar för overlay
This commit is contained in:
23
src/app.js
23
src/app.js
@@ -442,6 +442,7 @@ const TRANSLATIONS = {
|
||||
"overlay.fullscreen": "Fullscreen",
|
||||
"overlay.leaderboard_live": "Live leaderboard",
|
||||
"overlay.rotating_panel": "Displaypanel",
|
||||
"overlay.next_predicted_lap": "Nästa varv",
|
||||
"overlay.event_markers": "Eventmarkörer",
|
||||
"guide.host_title": "Hur Managed AMMC körs",
|
||||
"guide.host_1": "1. AMMC körs alltid på samma maskin som `npm start` eller `node server.js` körs på.",
|
||||
@@ -902,6 +903,7 @@ const TRANSLATIONS = {
|
||||
"overlay.fullscreen": "Fullscreen",
|
||||
"overlay.leaderboard_live": "Live leaderboard",
|
||||
"overlay.rotating_panel": "Display panel",
|
||||
"overlay.next_predicted_lap": "Next lap",
|
||||
"overlay.event_markers": "Event markers",
|
||||
"guide.host_title": "How Managed AMMC Runs",
|
||||
"guide.host_1": "1. AMMC always runs on the same machine where `npm start` or `node server.js` is running.",
|
||||
@@ -3796,6 +3798,15 @@ function renderOverlayLeaderboard(rows) {
|
||||
<div class="overlay-race-driver">
|
||||
<strong>${escapeHtml(row.driverName)}</strong>
|
||||
<span>${escapeHtml(row.transponder || "-")}</span>
|
||||
<div class="overlay-prediction">
|
||||
<div class="overlay-prediction-meta">
|
||||
<label>${t("overlay.next_predicted_lap")}</label>
|
||||
<span>${row.predictedRemainingMs !== null ? formatLap(row.predictedRemainingMs) : "-"}</span>
|
||||
</div>
|
||||
<div class="overlay-prediction-track">
|
||||
<div class="overlay-prediction-fill" style="width:${Math.max(0, Math.min(100, Math.round((row.predictedProgress || 0) * 100)))}%"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overlay-race-metric">
|
||||
<label>${t("table.result")}</label>
|
||||
@@ -4511,6 +4522,7 @@ function buildLeaderboard(session) {
|
||||
const isFreePractice = sessionType === "free_practice";
|
||||
const isOpenPractice = sessionType === "open_practice";
|
||||
const isRollingPractice = isFreePractice || isOpenPractice;
|
||||
const nowTs = Date.now();
|
||||
const rows = Object.values(result.competitors).map((row) => {
|
||||
const totalElapsedMs = getCompetitorElapsedMs(session, row);
|
||||
const distanceToTargetMs = Math.abs(targetMs - totalElapsedMs);
|
||||
@@ -4519,6 +4531,15 @@ function buildLeaderboard(session) {
|
||||
const previousLapMs = passings.length >= 2 ? Number(passings[passings.length - 2].lapMs || 0) : null;
|
||||
const lapDeltaMs =
|
||||
row.lastLapMs && previousLapMs && row.lastLapMs > 0 && previousLapMs > 0 ? row.lastLapMs - previousLapMs : null;
|
||||
const predictionBaseMs =
|
||||
Number(row.lastLapMs || 0) > 0
|
||||
? Number(row.lastLapMs)
|
||||
: Number(row.bestLapMs || 0) > 0
|
||||
? Number(row.bestLapMs)
|
||||
: null;
|
||||
const currentLapElapsedMs = row.lastTimestamp ? Math.max(0, nowTs - row.lastTimestamp) : 0;
|
||||
const predictedRemainingMs = predictionBaseMs ? Math.max(0, predictionBaseMs - currentLapElapsedMs) : null;
|
||||
const predictedProgress = predictionBaseMs ? Math.min(1.25, currentLapElapsedMs / predictionBaseMs) : 0;
|
||||
return {
|
||||
...row,
|
||||
totalElapsedMs,
|
||||
@@ -4526,6 +4547,8 @@ function buildLeaderboard(session) {
|
||||
seedMetric,
|
||||
previousLapMs,
|
||||
lapDeltaMs,
|
||||
predictedRemainingMs,
|
||||
predictedProgress,
|
||||
comparisonMs:
|
||||
isRollingPractice
|
||||
? row.bestLapMs || row.lastLapMs || Number.MAX_SAFE_INTEGER
|
||||
|
||||
@@ -852,6 +852,38 @@ select:focus {
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
.overlay-prediction {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.overlay-prediction-meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.overlay-prediction-meta label,
|
||||
.overlay-prediction-meta span {
|
||||
color: var(--muted);
|
||||
font-size: 0.72rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
|
||||
.overlay-prediction-track {
|
||||
height: 4px;
|
||||
border-radius: 999px;
|
||||
overflow: hidden;
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.overlay-prediction-fill {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #ffffff, #e10600);
|
||||
}
|
||||
|
||||
.overlay-race-metric strong,
|
||||
.overlay-race-best strong {
|
||||
font-family: Orbitron, sans-serif;
|
||||
|
||||
Reference in New Issue
Block a user