fix: weggegebene Flasche beendet den Tauchgang + HUD-Feinschliff
Bug: wer die getragene Flasche im Tauchgang weggab, konnte unbegrenzt weiteratmen. Der Client hielt nur eine Slot-Nummer, die niemand mehr gegenpruefte, und der Sync lief ins Leere. ox_inventory feuert clientseitig bei jeder Inventar-Aenderung - dort wird jetzt beim Server nachgefragt. Ist die Flasche weg, kommt die Ausruestung ab; wurde sie nur umsortiert, bindet der Client auf den neuen Slot um, damit Aufraeumen im Inventar nichts kostet. HUD: - Werte aus den Uhren heraus in eine zweite Zeile: Druck, Lampe und Tiefe liegen jetzt auf einer Linie. In der Skala kollidierte die Zahl mit Strichen, Zeiger und rotem Bereich - Skaliert mit der Bildschirmhoehe (entworfen auf 1080p), sonst waere das in festen Pixeln gebaute HUD auf 1440p und 4K deutlich zu klein. config.hudScale kommt als Geschmacksregler obendrauf - Zustandsklassen sitzen jetzt am HUD statt an den Uhren, weil Instrument und Wert in getrennten Grid-Zellen liegen README-Renderings nachgezogen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,9 @@ die bei Animationen nicht mehr verschwindet.
|
|||||||
> `nui/style.css` — keine In-Game-Aufnahmen. Erzeugt mit `docs/gen-hud-svg.mjs`.
|
> `nui/style.css` — keine In-Game-Aufnahmen. Erzeugt mit `docs/gen-hud-svg.mjs`.
|
||||||
|
|
||||||
Eine Dreier-Konsole wie am echten Tauchgerät: **Finimeter** links, Restluft als
|
Eine Dreier-Konsole wie am echten Tauchgerät: **Finimeter** links, Restluft als
|
||||||
Ring in der Mitte, **Tiefenmesser** rechts.
|
Ring in der Mitte, **Tiefenmesser** rechts; die Werte darunter auf einer Linie.
|
||||||
|
Das HUD ist auf 1080p entworfen und skaliert mit der Bildschirmhöhe mit, damit es
|
||||||
|
auf 1440p und 4K nicht schrumpft.
|
||||||
|
|
||||||
**Normal** — Druck im grünen Bereich, flach getaucht, Lampe an
|
**Normal** — Druck im grünen Bereich, flach getaucht, Lampe an
|
||||||
|
|
||||||
@@ -187,6 +189,7 @@ auf z.B. `2`.
|
|||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `hudEnabled` | `true` | Ohne HUD bleibt die Ausrüstung voll nutzbar |
|
| `hudEnabled` | `true` | Ohne HUD bleibt die Ausrüstung voll nutzbar |
|
||||||
| `hudUpdateIntervalMs` | `250` | 4 Updates pro Sekunde |
|
| `hudUpdateIntervalMs` | `250` | 4 Updates pro Sekunde |
|
||||||
|
| `hudScale` | `1.0` | Größenfaktor obendrauf. Das HUD skaliert schon selbst mit der Bildschirmhöhe |
|
||||||
| `hudOnlyUnderwater` | `false` | Auf `false` schon sichtbar, sobald die Ausrüstung an ist — Finimeter ablesen ohne Inventar |
|
| `hudOnlyUnderwater` | `false` | Auf `false` schon sichtbar, sobald die Ausrüstung an ist — Finimeter ablesen ohne Inventar |
|
||||||
| `hudFollowGameHud` | `true` | Mit dem Spiel-HUD ausblenden |
|
| `hudFollowGameHud` | `true` | Mit dem Spiel-HUD ausblenden |
|
||||||
| `hudToggleKey` | `''` | Eigene Taste, leer = unbelegt |
|
| `hudToggleKey` | `''` | Eigene Taste, leer = unbelegt |
|
||||||
|
|||||||
@@ -427,6 +427,7 @@ local function startHudThread()
|
|||||||
|
|
||||||
SendNUIMessage({
|
SendNUIMessage({
|
||||||
action = 'labels',
|
action = 'labels',
|
||||||
|
scale = config.hudScale,
|
||||||
air = locale('hud.air'),
|
air = locale('hud.air'),
|
||||||
depth = locale('hud.depth'),
|
depth = locale('hud.depth'),
|
||||||
pressure = locale('hud.pressure'),
|
pressure = locale('hud.pressure'),
|
||||||
@@ -740,6 +741,30 @@ lib.onCache('ped', function(ped)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
--- Die Flasche kann während des Tauchgangs das Inventar verlassen - weggegeben,
|
||||||
|
--- abgelegt, vom Admin entfernt. Ohne diese Prüfung hielt der Client nur eine
|
||||||
|
--- Slot-Nummer, die niemand mehr gegenprüfte, und man konnte unbegrenzt
|
||||||
|
--- weitertauchen. ox_inventory feuert bei jeder Änderung, also einmal nachfragen.
|
||||||
|
AddEventHandler('ox_inventory:updateInventory', function()
|
||||||
|
if not currentGear.enabled or not activeTank then return end
|
||||||
|
|
||||||
|
CreateThread(function()
|
||||||
|
local expected = activeTank
|
||||||
|
local slot = lib.callback.await('d4rk_divegear:server:verifyTank', false, expected.slot, expected.name)
|
||||||
|
|
||||||
|
-- Während des Callbacks kann die Ausrüstung schon abgelegt worden sein.
|
||||||
|
if not currentGear.enabled or activeTank ~= expected then return end
|
||||||
|
|
||||||
|
if not slot then
|
||||||
|
exports.qbx_core:Notify(locale('error.tank_gone'), 'error')
|
||||||
|
removeGear(true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
activeTank.slot = slot
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
AddEventHandler('onResourceStop', function(resource)
|
AddEventHandler('onResourceStop', function(resource)
|
||||||
if resource ~= GetCurrentResourceName() then return end
|
if resource ~= GetCurrentResourceName() then return end
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ return {
|
|||||||
--- ruhige Anzeige ohne unnötigen NUI-Traffic.
|
--- ruhige Anzeige ohne unnötigen NUI-Traffic.
|
||||||
hudUpdateIntervalMs = 250,
|
hudUpdateIntervalMs = 250,
|
||||||
|
|
||||||
|
--- Zusätzlicher Größenfaktor für das HUD. Es skaliert schon von selbst mit
|
||||||
|
--- der Bildschirmhöhe (entworfen auf 1080p), das hier ist der Geschmacks-
|
||||||
|
--- regler obendrauf. 1.2 = 20 % größer.
|
||||||
|
hudScale = 1.0,
|
||||||
|
|
||||||
--- HUD nur unter Wasser zeigen. Auf false ist es sichtbar, sobald die
|
--- HUD nur unter Wasser zeigen. Auf false ist es sichtbar, sobald die
|
||||||
--- Ausrüstung angelegt ist - dann lässt sich der Flaschendruck am Finimeter
|
--- Ausrüstung angelegt ist - dann lässt sich der Flaschendruck am Finimeter
|
||||||
--- ablesen, ohne extra das Inventar zu öffnen.
|
--- ablesen, ohne extra das Inventar zu öffnen.
|
||||||
|
|||||||
+18
-20
@@ -25,9 +25,9 @@ const F = "'Segoe UI',Roboto,system-ui,sans-serif";
|
|||||||
// Masse spiegeln das Grid aus style.css: padding 14/20, column-gap 20,
|
// Masse spiegeln das Grid aus style.css: padding 14/20, column-gap 20,
|
||||||
// Uhr 96, Ring 92, Beschriftung darunter, Lampe in Zeile 2.
|
// Uhr 96, Ring 92, Beschriftung darunter, Lampe in Zeile 2.
|
||||||
const PAD_X = 20, PAD_Y = 14, DIAL = 96, GAUGE = 92, GAP = 20;
|
const PAD_X = 20, PAD_Y = 14, DIAL = 96, GAUGE = 92, GAP = 20;
|
||||||
const ROW1 = 112, ROW_GAP = 6, LAMP_H = 23;
|
const ROW1 = 96, ROW_GAP = 6, ROW2 = 32, LAMP_H = 23;
|
||||||
const PW = PAD_X * 2 + DIAL * 2 + GAUGE + GAP * 2;
|
const PW = PAD_X * 2 + DIAL * 2 + GAUGE + GAP * 2;
|
||||||
const PH = PAD_Y * 2 + ROW1 + ROW_GAP + LAMP_H;
|
const PH = PAD_Y * 2 + ROW1 + ROW_GAP + ROW2;
|
||||||
|
|
||||||
const W = 560, H = PH + 70;
|
const W = 560, H = PH + 70;
|
||||||
const PX = (W - PW) / 2, PY = (H - PH) / 2;
|
const PX = (W - PW) / 2, PY = (H - PH) / 2;
|
||||||
@@ -36,7 +36,8 @@ const LEFT_CX = PX + PAD_X + DIAL / 2;
|
|||||||
const RIGHT_CX = PX + PW - PAD_X - DIAL / 2;
|
const RIGHT_CX = PX + PW - PAD_X - DIAL / 2;
|
||||||
const MID_CX = PX + PW / 2;
|
const MID_CX = PX + PW / 2;
|
||||||
const DIAL_CY = PY + PAD_Y + DIAL / 2;
|
const DIAL_CY = PY + PAD_Y + DIAL / 2;
|
||||||
const GAUGE_CY = PY + PAD_Y + ROW1 / 2;
|
const GAUGE_CY = PY + PAD_Y + 2 + GAUGE / 2;
|
||||||
|
const ROW2_Y = PY + PAD_Y + ROW1 + ROW_GAP; // Werte und Lampe auf einer Linie
|
||||||
|
|
||||||
const n = (v) => Number(v.toFixed(2));
|
const n = (v) => Number(v.toFixed(2));
|
||||||
const rad = (d) => ((d - 90) * Math.PI) / 180;
|
const rad = (d) => ((d - 90) * Math.PI) / 180;
|
||||||
@@ -45,7 +46,7 @@ const pt = (cx, cy, r, d) => [cx + r * Math.cos(rad(d)), cy + r * Math.sin(rad(d
|
|||||||
const fmt = (s) => `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(Math.floor(s % 60)).padStart(2, '0')}`;
|
const fmt = (s) => `${String(Math.floor(s / 60)).padStart(2, '0')}:${String(Math.floor(s % 60)).padStart(2, '0')}`;
|
||||||
|
|
||||||
/** Zeigerinstrument. 270-Grad-Skala, unten offen - wie ein echtes Finimeter. */
|
/** Zeigerinstrument. 270-Grad-Skala, unten offen - wie ein echtes Finimeter. */
|
||||||
function dial(cx, cy, { value, max, unit, label, zoneFrom, zoneTo, needleColour, valueColour, decimals = 0 }) {
|
function dial(cx, cy, { value, max, zoneFrom, zoneTo, needleColour }) {
|
||||||
// 96px Uhr, Geometrie aus dem viewBox 0 0 100 100 skaliert
|
// 96px Uhr, Geometrie aus dem viewBox 0 0 100 100 skaliert
|
||||||
const k = DIAL / 100;
|
const k = DIAL / 100;
|
||||||
const R = 42 * k, A0 = -135, SWEEP = 270;
|
const R = 42 * k, A0 = -135, SWEEP = 270;
|
||||||
@@ -72,12 +73,15 @@ function dial(cx, cy, { value, max, unit, label, zoneFrom, zoneTo, needleColour,
|
|||||||
s += `<line x1="${n(tailX)}" y1="${n(tailY)}" x2="${n(tipX)}" y2="${n(tipY)}" stroke="${needleColour}" stroke-width="2.6" stroke-linecap="round"/>`;
|
s += `<line x1="${n(tailX)}" y1="${n(tailY)}" x2="${n(tipX)}" y2="${n(tipY)}" stroke="${needleColour}" stroke-width="2.6" stroke-linecap="round"/>`;
|
||||||
s += `<circle cx="${n(cx)}" cy="${n(cy)}" r="${n(3.4 * k)}" fill="${needleColour}"/>`;
|
s += `<circle cx="${n(cx)}" cy="${n(cy)}" r="${n(3.4 * k)}" fill="${needleColour}"/>`;
|
||||||
|
|
||||||
s += `<text x="${n(cx)}" y="${n(cy + 22)}" text-anchor="middle" font-size="16" font-weight="700" fill="${valueColour}" font-family="${F}">${value.toFixed(decimals)}<tspan font-size="10" font-weight="500" fill="${C.muted}" dx="2">${unit}</tspan></text>`;
|
|
||||||
s += `<text x="${n(cx)}" y="${n(cy + DIAL / 2 + 13)}" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}" font-family="${F}">${label}</text>`;
|
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Beschriftung und Wert unter der Uhr - eine Zeile mit der Lampe. */
|
||||||
|
function readout(cx, label, value, unit, colour) {
|
||||||
|
return `<text x="${n(cx)}" y="${n(ROW2_Y + 9)}" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}" font-family="${F}">${label}</text>
|
||||||
|
<text x="${n(cx)}" y="${n(ROW2_Y + 28)}" text-anchor="middle" font-size="19" font-weight="700" fill="${colour}" font-family="${F}">${value}<tspan font-size="11" font-weight="500" fill="${C.muted}" dx="3">${unit}</tspan></text>`;
|
||||||
|
}
|
||||||
|
|
||||||
function build({ file, title, oxygen, capacity, level, depth, depthLimit, pressure, reservePressure, lamp, deep }) {
|
function build({ file, title, oxygen, capacity, level, depth, depthLimit, pressure, reservePressure, lamp, deep }) {
|
||||||
const ratio = Math.max(0, Math.min(1, oxygen / capacity));
|
const ratio = Math.max(0, Math.min(1, oxygen / capacity));
|
||||||
const ringColour = level === 'danger' ? C.danger : level === 'warn' ? C.warn : C.accent;
|
const ringColour = level === 'danger' ? C.danger : level === 'warn' ? C.warn : C.accent;
|
||||||
@@ -101,11 +105,8 @@ function build({ file, title, oxygen, capacity, level, depth, depthLimit, pressu
|
|||||||
<rect width="${W}" height="${H}" fill="url(#water)"/>
|
<rect width="${W}" height="${H}" fill="url(#water)"/>
|
||||||
<rect x="${n(PX)}" y="${n(PY)}" width="${PW}" height="${PH}" rx="16" fill="${C.panel}" fill-opacity="0.72" stroke="${C.muted}" stroke-opacity="0.18"/>
|
<rect x="${n(PX)}" y="${n(PY)}" width="${PW}" height="${PH}" rx="16" fill="${C.panel}" fill-opacity="0.72" stroke="${C.muted}" stroke-opacity="0.18"/>
|
||||||
|
|
||||||
${dial(LEFT_CX, DIAL_CY, {
|
${dial(LEFT_CX, DIAL_CY, { value: pressure, max: 300, zoneFrom: 0, zoneTo: reservePressure, needleColour: pressureColour })}
|
||||||
value: pressure, max: 300, unit: 'bar', label: 'DRUCK',
|
${readout(LEFT_CX, 'DRUCK', Math.round(pressure), 'bar', pressureColour)}
|
||||||
zoneFrom: 0, zoneTo: reservePressure,
|
|
||||||
needleColour: pressureColour, valueColour: pressureColour
|
|
||||||
})}
|
|
||||||
|
|
||||||
<g transform="rotate(-90 ${n(MID_CX)} ${n(GAUGE_CY)})">
|
<g transform="rotate(-90 ${n(MID_CX)} ${n(GAUGE_CY)})">
|
||||||
<circle cx="${n(MID_CX)}" cy="${n(GAUGE_CY)}" r="${n(R)}" fill="none" stroke="${C.muted}" stroke-opacity="0.16" stroke-width="${n(SW)}" stroke-linecap="round"/>
|
<circle cx="${n(MID_CX)}" cy="${n(GAUGE_CY)}" r="${n(R)}" fill="none" stroke="${C.muted}" stroke-opacity="0.16" stroke-width="${n(SW)}" stroke-linecap="round"/>
|
||||||
@@ -114,15 +115,12 @@ function build({ file, title, oxygen, capacity, level, depth, depthLimit, pressu
|
|||||||
<text x="${n(MID_CX)}" y="${n(GAUGE_CY - 1)}" text-anchor="middle" font-size="21" font-weight="600" fill="${ringColour}" font-family="${F}">${fmt(oxygen)}</text>
|
<text x="${n(MID_CX)}" y="${n(GAUGE_CY - 1)}" text-anchor="middle" font-size="21" font-weight="600" fill="${ringColour}" font-family="${F}">${fmt(oxygen)}</text>
|
||||||
<text x="${n(MID_CX)}" y="${n(GAUGE_CY + 15)}" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}" font-family="${F}">LUFT</text>
|
<text x="${n(MID_CX)}" y="${n(GAUGE_CY + 15)}" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="${C.muted}" font-family="${F}">LUFT</text>
|
||||||
|
|
||||||
${dial(RIGHT_CX, DIAL_CY, {
|
${dial(RIGHT_CX, DIAL_CY, { value: depth, max: 100, zoneFrom: depthLimit, zoneTo: 100, needleColour: depthColour })}
|
||||||
value: depth, max: 100, unit: 'm', label: 'TIEFE', decimals: 1,
|
${readout(RIGHT_CX, 'TIEFE', depth.toFixed(1), 'm', depthColour)}
|
||||||
zoneFrom: depthLimit, zoneTo: 100,
|
|
||||||
needleColour: depthColour, valueColour: depthColour
|
|
||||||
})}
|
|
||||||
|
|
||||||
<rect x="${n(MID_CX - 43)}" y="${n(PY + PAD_Y + ROW1 + ROW_GAP)}" width="86" height="${LAMP_H}" rx="8" fill="${lampColour}" fill-opacity="${lamp ? 0.15 : 0.1}"/>
|
<rect x="${n(MID_CX - 43)}" y="${n(ROW2_Y + (ROW2 - LAMP_H) / 2)}" width="86" height="${LAMP_H}" rx="8" fill="${lampColour}" fill-opacity="${lamp ? 0.15 : 0.1}"/>
|
||||||
<circle cx="${n(MID_CX - 29)}" cy="${n(PY + PAD_Y + ROW1 + ROW_GAP + LAMP_H / 2)}" r="4" fill="${lampColour}"/>
|
<circle cx="${n(MID_CX - 29)}" cy="${n(ROW2_Y + ROW2 / 2)}" r="4" fill="${lampColour}"/>
|
||||||
<text x="${n(MID_CX - 19)}" y="${n(PY + PAD_Y + ROW1 + ROW_GAP + LAMP_H / 2 + 3.5)}" font-size="10" font-weight="600" letter-spacing="1.2" fill="${lampColour}" font-family="${F}">LAMPE</text>
|
<text x="${n(MID_CX - 19)}" y="${n(ROW2_Y + ROW2 / 2 + 3.5)}" font-size="10" font-weight="600" letter-spacing="1.2" fill="${lampColour}" font-family="${F}">LAMPE</text>
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
+17
-13
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 239" width="560" height="239" role="img" aria-label="Tauch-HUD: unter der Tiefengrenze des Atemgases">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 232" width="560" height="232" role="img" aria-label="Tauch-HUD: unter der Tiefengrenze des Atemgases">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
||||||
<stop offset="0%" stop-color="#0d3550"/>
|
<stop offset="0%" stop-color="#0d3550"/>
|
||||||
@@ -6,21 +6,25 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<rect width="560" height="239" fill="url(#water)"/>
|
<rect width="560" height="232" fill="url(#water)"/>
|
||||||
<rect x="98" y="35" width="364" height="169" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
<rect x="98" y="35" width="364" height="162" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
||||||
|
|
||||||
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="172.42" y1="92.78" x2="139.52" y2="114.39" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#f87171"/><text x="166" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">13<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">bar</tspan></text><text x="166" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="172.42" y1="92.78" x2="139.52" y2="114.39" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#f87171"/>
|
||||||
|
<text x="166" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
||||||
|
<text x="166" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">13<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">bar</tspan></text>
|
||||||
|
|
||||||
<g transform="rotate(-90 280 105)">
|
<g transform="rotate(-90 280 97)">
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#f87171" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="239.91"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#f87171" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="239.91"/>
|
||||||
</g>
|
</g>
|
||||||
<text x="280" y="104" text-anchor="middle" font-size="21" font-weight="600" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">00:38</text>
|
<text x="280" y="96" text-anchor="middle" font-size="21" font-weight="600" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">00:38</text>
|
||||||
<text x="280" y="120" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
<text x="280" y="112" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
||||||
|
|
||||||
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="393.13" y1="104.63" x2="397.58" y2="65.52" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#f87171"/><text x="394" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">52.4<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">m</tspan></text><text x="394" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="393.13" y1="104.63" x2="397.58" y2="65.52" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#f87171"/>
|
||||||
|
<text x="394" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
||||||
|
<text x="394" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">52.4<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">m</tspan></text>
|
||||||
|
|
||||||
<rect x="237" y="167" width="86" height="23" rx="8" fill="#38bdf8" fill-opacity="0.15"/>
|
<rect x="237" y="155.5" width="86" height="23" rx="8" fill="#38bdf8" fill-opacity="0.15"/>
|
||||||
<circle cx="251" cy="178.5" r="4" fill="#38bdf8"/>
|
<circle cx="251" cy="167" r="4" fill="#38bdf8"/>
|
||||||
<text x="261" y="182" font-size="10" font-weight="600" letter-spacing="1.2" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
<text x="261" y="170.5" font-size="10" font-weight="600" letter-spacing="1.2" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
+17
-13
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 239" width="560" height="239" role="img" aria-label="Tauch-HUD: normaler Zustand">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 232" width="560" height="232" role="img" aria-label="Tauch-HUD: normaler Zustand">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
||||||
<stop offset="0%" stop-color="#0d3550"/>
|
<stop offset="0%" stop-color="#0d3550"/>
|
||||||
@@ -6,21 +6,25 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<rect width="560" height="239" fill="url(#water)"/>
|
<rect width="560" height="232" fill="url(#water)"/>
|
||||||
<rect x="98" y="35" width="364" height="169" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
<rect x="98" y="35" width="364" height="162" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
||||||
|
|
||||||
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="167.68" y1="104.5" x2="159.09" y2="66.08" stroke="#e2e8f0" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#e2e8f0"/><text x="166" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#e2e8f0" font-family="'Segoe UI',Roboto,system-ui,sans-serif">136<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">bar</tspan></text><text x="166" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="167.68" y1="104.5" x2="159.09" y2="66.08" stroke="#e2e8f0" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#e2e8f0"/>
|
||||||
|
<text x="166" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
||||||
|
<text x="166" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#e2e8f0" font-family="'Segoe UI',Roboto,system-ui,sans-serif">136<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">bar</tspan></text>
|
||||||
|
|
||||||
<g transform="rotate(-90 280 105)">
|
<g transform="rotate(-90 280 97)">
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#38bdf8" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="136.73"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#38bdf8" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="136.73"/>
|
||||||
</g>
|
</g>
|
||||||
<text x="280" y="104" text-anchor="middle" font-size="21" font-weight="600" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">09:05</text>
|
<text x="280" y="96" text-anchor="middle" font-size="21" font-weight="600" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">09:05</text>
|
||||||
<text x="280" y="120" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
<text x="280" y="112" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
||||||
|
|
||||||
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="401.53" y1="95.47" x2="362.96" y2="103.33" stroke="#e2e8f0" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#e2e8f0"/><text x="394" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#e2e8f0" font-family="'Segoe UI',Roboto,system-ui,sans-serif">12.4<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">m</tspan></text><text x="394" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="401.53" y1="95.47" x2="362.96" y2="103.33" stroke="#e2e8f0" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#e2e8f0"/>
|
||||||
|
<text x="394" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
||||||
|
<text x="394" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#e2e8f0" font-family="'Segoe UI',Roboto,system-ui,sans-serif">12.4<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">m</tspan></text>
|
||||||
|
|
||||||
<rect x="237" y="167" width="86" height="23" rx="8" fill="#38bdf8" fill-opacity="0.15"/>
|
<rect x="237" y="155.5" width="86" height="23" rx="8" fill="#38bdf8" fill-opacity="0.15"/>
|
||||||
<circle cx="251" cy="178.5" r="4" fill="#38bdf8"/>
|
<circle cx="251" cy="167" r="4" fill="#38bdf8"/>
|
||||||
<text x="261" y="182" font-size="10" font-weight="600" letter-spacing="1.2" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
<text x="261" y="170.5" font-size="10" font-weight="600" letter-spacing="1.2" fill="#38bdf8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
+17
-13
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 239" width="560" height="239" role="img" aria-label="Tauch-HUD: Warnstufe und Reservedruck">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 560 232" width="560" height="232" role="img" aria-label="Tauch-HUD: Warnstufe und Reservedruck">
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
<linearGradient id="water" x1="0" y1="0" x2="0.6" y2="1">
|
||||||
<stop offset="0%" stop-color="#0d3550"/>
|
<stop offset="0%" stop-color="#0d3550"/>
|
||||||
@@ -6,21 +6,25 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
|
||||||
<rect width="560" height="239" fill="url(#water)"/>
|
<rect width="560" height="232" fill="url(#water)"/>
|
||||||
<rect x="98" y="35" width="364" height="169" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
<rect x="98" y="35" width="364" height="162" rx="16" fill="#09121c" fill-opacity="0.72" stroke="#94a3b8" stroke-opacity="0.18"/>
|
||||||
|
|
||||||
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="173.34" y1="94.74" x2="135.72" y2="106.32" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#f87171"/><text x="166" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">31<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">bar</tspan></text><text x="166" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
<circle cx="166" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 138.85 124.15 A 38.4 38.4 0 0 1 127.6 97" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="141.56" y1="121.44" x2="146.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="133.13" y1="107.68" x2="136.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="131.87" y1="91.59" x2="138.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="138.04" y1="76.69" x2="141.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="150.31" y1="66.21" x2="153.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="166" y1="62.44" x2="166" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="181.69" y1="66.21" x2="178.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="193.96" y1="76.69" x2="190.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="200.13" y1="91.59" x2="193.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="198.87" y1="107.68" x2="195.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="190.44" y1="121.44" x2="185.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="173.34" y1="94.74" x2="135.72" y2="106.32" stroke="#f87171" stroke-width="2.6" stroke-linecap="round"/><circle cx="166" cy="97" r="3.26" fill="#f87171"/>
|
||||||
|
<text x="166" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">DRUCK</text>
|
||||||
|
<text x="166" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#f87171" font-family="'Segoe UI',Roboto,system-ui,sans-serif">31<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">bar</tspan></text>
|
||||||
|
|
||||||
<g transform="rotate(-90 280 105)">
|
<g transform="rotate(-90 280 97)">
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#94a3b8" stroke-opacity="0.16" stroke-width="6.13" stroke-linecap="round"/>
|
||||||
<circle cx="280" cy="105" r="39.87" fill="none" stroke="#fbbf24" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="224.88"/>
|
<circle cx="280" cy="97" r="39.87" fill="none" stroke="#fbbf24" stroke-width="6.13" stroke-linecap="round" stroke-dasharray="250.49" stroke-dashoffset="224.88"/>
|
||||||
</g>
|
</g>
|
||||||
<text x="280" y="104" text-anchor="middle" font-size="21" font-weight="600" fill="#fbbf24" font-family="'Segoe UI',Roboto,system-ui,sans-serif">01:32</text>
|
<text x="280" y="96" text-anchor="middle" font-size="21" font-weight="600" fill="#fbbf24" font-family="'Segoe UI',Roboto,system-ui,sans-serif">01:32</text>
|
||||||
<text x="280" y="120" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
<text x="280" y="112" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LUFT</text>
|
||||||
|
|
||||||
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="400.7" y1="100.75" x2="366.36" y2="81.52" stroke="#fbbf24" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#fbbf24"/><text x="394" y="119" text-anchor="middle" font-size="16" font-weight="700" fill="#fbbf24" font-family="'Segoe UI',Roboto,system-ui,sans-serif">27.5<tspan font-size="10" font-weight="500" fill="#94a3b8" dx="2">m</tspan></text><text x="394" y="158" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
<circle cx="394" cy="97" r="44.16" fill="#0b1622" stroke="#94a3b8" stroke-opacity="0.25" stroke-width="1.5"/><path d="M 385.04 59.66 A 38.4 38.4 0 0 1 421.15 124.15" fill="none" stroke="#f87171" stroke-width="3.5" stroke-opacity="0.9"/><line x1="369.56" y1="121.44" x2="374.31" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="361.13" y1="107.68" x2="364.78" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="359.87" y1="91.59" x2="366.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="366.04" y1="76.69" x2="369.15" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="378.31" y1="66.21" x2="381.36" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="394" y1="62.44" x2="394" y2="66.28" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="409.69" y1="66.21" x2="406.64" y2="72.19" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="421.96" y1="76.69" x2="418.85" y2="78.94" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="428.13" y1="91.59" x2="421.5" y2="92.64" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="426.87" y1="107.68" x2="423.22" y2="106.49" stroke="#cbd5e1" stroke-opacity="0.4" stroke-width="1"/><line x1="418.44" y1="121.44" x2="413.69" y2="116.69" stroke="#cbd5e1" stroke-opacity="0.85" stroke-width="1.6"/><line x1="400.7" y1="100.75" x2="366.36" y2="81.52" stroke="#fbbf24" stroke-width="2.6" stroke-linecap="round"/><circle cx="394" cy="97" r="3.26" fill="#fbbf24"/>
|
||||||
|
<text x="394" y="160" text-anchor="middle" font-size="9" font-weight="600" letter-spacing="1.4" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">TIEFE</text>
|
||||||
|
<text x="394" y="179" text-anchor="middle" font-size="19" font-weight="700" fill="#fbbf24" font-family="'Segoe UI',Roboto,system-ui,sans-serif">27.5<tspan font-size="11" font-weight="500" fill="#94a3b8" dx="3">m</tspan></text>
|
||||||
|
|
||||||
<rect x="237" y="167" width="86" height="23" rx="8" fill="#94a3b8" fill-opacity="0.1"/>
|
<rect x="237" y="155.5" width="86" height="23" rx="8" fill="#94a3b8" fill-opacity="0.1"/>
|
||||||
<circle cx="251" cy="178.5" r="4" fill="#94a3b8"/>
|
<circle cx="251" cy="167" r="4" fill="#94a3b8"/>
|
||||||
<text x="261" y="182" font-size="10" font-weight="600" letter-spacing="1.2" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
<text x="261" y="170.5" font-size="10" font-weight="600" letter-spacing="1.2" fill="#94a3b8" font-family="'Segoe UI',Roboto,system-ui,sans-serif">LAMPE</text>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
+2
-1
@@ -8,7 +8,8 @@
|
|||||||
"tank_already_full": "Diese Tauchflasche ist bereits voll!",
|
"tank_already_full": "Diese Tauchflasche ist bereits voll!",
|
||||||
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!",
|
"out_of_air": "Deine Luft ist alle! Sofort auftauchen!",
|
||||||
"no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe.",
|
"no_lamp_on_outfit": "Deine Tauchausrüstung hat keine Lampe.",
|
||||||
"crush_depth": "Lebensgefahr! Ab %d m zerdrückt dich der Wasserdruck."
|
"crush_depth": "Lebensgefahr! Ab %d m zerdrückt dich der Wasserdruck.",
|
||||||
|
"tank_gone": "Deine Tauchflasche ist weg!"
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
"took_out": "Du hast deine Ausrüstung abgelegt!",
|
"took_out": "Du hast deine Ausrüstung abgelegt!",
|
||||||
|
|||||||
+2
-1
@@ -8,7 +8,8 @@
|
|||||||
"tank_already_full": "This air tank is already full!",
|
"tank_already_full": "This air tank is already full!",
|
||||||
"out_of_air": "You're out of air! Surface now!",
|
"out_of_air": "You're out of air! Surface now!",
|
||||||
"no_lamp_on_outfit": "Your diving suit doesn't have a lamp.",
|
"no_lamp_on_outfit": "Your diving suit doesn't have a lamp.",
|
||||||
"crush_depth": "Danger! Below %d m the water pressure will crush you."
|
"crush_depth": "Danger! Below %d m the water pressure will crush you.",
|
||||||
|
"tank_gone": "Your air tank is gone!"
|
||||||
},
|
},
|
||||||
"success": {
|
"success": {
|
||||||
"took_out": "You've taken your gear off!",
|
"took_out": "You've taken your gear off!",
|
||||||
|
|||||||
+13
-9
@@ -5,10 +5,11 @@
|
|||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Zeile 1: die drei Instrumente. Zeile 2: ihre Werte, mit der Lampe
|
||||||
|
dazwischen - alles auf einer Linie. -->
|
||||||
<div id="hud" class="hidden">
|
<div id="hud" class="hidden">
|
||||||
<!-- Finimeter: Restdruck der Flasche, roter Bereich = Reserve -->
|
<!-- Finimeter: Restdruck der Flasche, roter Bereich = Reserve -->
|
||||||
<div class="dial" id="pressure">
|
<div class="dial-face" id="pressure-face">
|
||||||
<div class="dial-face">
|
|
||||||
<svg viewBox="0 0 100 100" aria-hidden="true">
|
<svg viewBox="0 0 100 100" aria-hidden="true">
|
||||||
<circle class="face" cx="50" cy="50" r="46"></circle>
|
<circle class="face" cx="50" cy="50" r="46"></circle>
|
||||||
<path class="zone" id="pressure-zone"></path>
|
<path class="zone" id="pressure-zone"></path>
|
||||||
@@ -18,9 +19,6 @@
|
|||||||
<circle cx="50" cy="50" r="3.4"></circle>
|
<circle cx="50" cy="50" r="3.4"></circle>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="dial-value"><span id="pressure-value">0</span><span class="unit">bar</span></div>
|
|
||||||
</div>
|
|
||||||
<span id="pressure-label" class="caption">DRUCK</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Restluft als Ring, die Zahl auf die es ankommt -->
|
<!-- Restluft als Ring, die Zahl auf die es ankommt -->
|
||||||
@@ -36,8 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tiefenmesser: roter Bereich = Tiefengrenze des Atemgases -->
|
<!-- Tiefenmesser: roter Bereich = Tiefengrenze des Atemgases -->
|
||||||
<div class="dial" id="depth">
|
<div class="dial-face" id="depth-face">
|
||||||
<div class="dial-face">
|
|
||||||
<svg viewBox="0 0 100 100" aria-hidden="true">
|
<svg viewBox="0 0 100 100" aria-hidden="true">
|
||||||
<circle class="face" cx="50" cy="50" r="46"></circle>
|
<circle class="face" cx="50" cy="50" r="46"></circle>
|
||||||
<path class="zone" id="depth-zone"></path>
|
<path class="zone" id="depth-zone"></path>
|
||||||
@@ -47,9 +44,11 @@
|
|||||||
<circle cx="50" cy="50" r="3.4"></circle>
|
<circle cx="50" cy="50" r="3.4"></circle>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
<div class="dial-value"><span id="depth-value">0.0</span><span class="unit">m</span></div>
|
|
||||||
</div>
|
</div>
|
||||||
<span id="depth-label" class="caption">TIEFE</span>
|
|
||||||
|
<div class="readout" id="pressure-readout">
|
||||||
|
<span id="pressure-label" class="caption">DRUCK</span>
|
||||||
|
<div class="value"><span id="pressure-value">0</span><span class="unit">bar</span></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="lamp" class="lamp">
|
<div id="lamp" class="lamp">
|
||||||
@@ -58,6 +57,11 @@
|
|||||||
</svg>
|
</svg>
|
||||||
<span id="lamp-label">LAMPE</span>
|
<span id="lamp-label">LAMPE</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="readout" id="depth-readout">
|
||||||
|
<span id="depth-label" class="caption">TIEFE</span>
|
||||||
|
<div class="value"><span id="depth-value">0.0</span><span class="unit">m</span></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
|
|||||||
+22
-5
@@ -10,20 +10,32 @@ const DIAL_SWEEP = 270;
|
|||||||
const DIAL_R = 42;
|
const DIAL_R = 42;
|
||||||
|
|
||||||
const hud = document.getElementById('hud');
|
const hud = document.getElementById('hud');
|
||||||
|
|
||||||
|
// Das HUD ist auf 1080p entworfen. Ohne Nachskalieren waere es auf 1440p und 4K
|
||||||
|
// deutlich zu klein, weil FiveM das NUI in der echten Bildschirmaufloesung
|
||||||
|
// rendert. Der Faktor aus der Config kommt obendrauf.
|
||||||
|
const DESIGN_HEIGHT = 1080;
|
||||||
|
let configScale = 1;
|
||||||
|
|
||||||
|
function applyScale() {
|
||||||
|
const scale = Math.min(2.5, Math.max(0.6, (window.innerHeight / DESIGN_HEIGHT) * configScale));
|
||||||
|
document.documentElement.style.setProperty('--hud-scale', scale.toFixed(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
applyScale();
|
||||||
|
window.addEventListener('resize', applyScale);
|
||||||
const gaugeFill = document.getElementById('gauge-fill');
|
const gaugeFill = document.getElementById('gauge-fill');
|
||||||
const airValue = document.getElementById('air-value');
|
const airValue = document.getElementById('air-value');
|
||||||
const lamp = document.getElementById('lamp');
|
const lamp = document.getElementById('lamp');
|
||||||
|
|
||||||
const dials = {
|
const dials = {
|
||||||
pressure: {
|
pressure: {
|
||||||
root: document.getElementById('pressure'),
|
|
||||||
needle: document.getElementById('pressure-needle'),
|
needle: document.getElementById('pressure-needle'),
|
||||||
zone: document.getElementById('pressure-zone'),
|
zone: document.getElementById('pressure-zone'),
|
||||||
ticks: document.getElementById('pressure-ticks'),
|
ticks: document.getElementById('pressure-ticks'),
|
||||||
value: document.getElementById('pressure-value')
|
value: document.getElementById('pressure-value')
|
||||||
},
|
},
|
||||||
depth: {
|
depth: {
|
||||||
root: document.getElementById('depth'),
|
|
||||||
needle: document.getElementById('depth-needle'),
|
needle: document.getElementById('depth-needle'),
|
||||||
zone: document.getElementById('depth-zone'),
|
zone: document.getElementById('depth-zone'),
|
||||||
ticks: document.getElementById('depth-ticks'),
|
ticks: document.getElementById('depth-ticks'),
|
||||||
@@ -127,14 +139,14 @@ function render(state) {
|
|||||||
dials.pressure.value.textContent = String(Math.round(state.pressure ?? 0));
|
dials.pressure.value.textContent = String(Math.round(state.pressure ?? 0));
|
||||||
setNeedle(dials.pressure, state.pressure ?? 0, maxPressure);
|
setNeedle(dials.pressure, state.pressure ?? 0, maxPressure);
|
||||||
setZone(dials.pressure, 0, state.reservePressure ?? 0, maxPressure);
|
setZone(dials.pressure, 0, state.reservePressure ?? 0, maxPressure);
|
||||||
dials.pressure.root.classList.toggle('alert', !!state.reserve);
|
hud.classList.toggle('pressure-alert', !!state.reserve);
|
||||||
|
|
||||||
const depthScale = state.depthScale || 100;
|
const depthScale = state.depthScale || 100;
|
||||||
dials.depth.value.textContent = state.depth.toFixed(1);
|
dials.depth.value.textContent = state.depth.toFixed(1);
|
||||||
setNeedle(dials.depth, state.depth, depthScale);
|
setNeedle(dials.depth, state.depth, depthScale);
|
||||||
setZone(dials.depth, state.depthLimit, depthScale, depthScale);
|
setZone(dials.depth, state.depthLimit, depthScale, depthScale);
|
||||||
dials.depth.root.classList.toggle('alert', !!state.overLimit);
|
hud.classList.toggle('depth-alert', !!state.overLimit);
|
||||||
dials.depth.root.classList.toggle('deep', !state.overLimit && !!state.deep);
|
hud.classList.toggle('depth-deep', !state.overLimit && !!state.deep);
|
||||||
|
|
||||||
lamp.classList.toggle('hidden', !state.hasLamp);
|
lamp.classList.toggle('hidden', !state.hasLamp);
|
||||||
lamp.classList.toggle('on', !!state.lamp);
|
lamp.classList.toggle('on', !!state.lamp);
|
||||||
@@ -146,6 +158,11 @@ window.addEventListener('message', (event) => {
|
|||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
if (data.action === 'labels') {
|
if (data.action === 'labels') {
|
||||||
|
if (typeof data.scale === 'number' && data.scale !== configScale) {
|
||||||
|
configScale = data.scale;
|
||||||
|
applyScale();
|
||||||
|
}
|
||||||
|
|
||||||
labels.air.textContent = data.air;
|
labels.air.textContent = data.air;
|
||||||
labels.depth.textContent = data.depth;
|
labels.depth.textContent = data.depth;
|
||||||
labels.pressure.textContent = data.pressure;
|
labels.pressure.textContent = data.pressure;
|
||||||
|
|||||||
+46
-47
@@ -32,7 +32,12 @@ body {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
bottom: 7vh;
|
bottom: 7vh;
|
||||||
transform: translateX(-50%) translateY(0);
|
/* Skaliert mit der Bildschirmhöhe, sonst wäre das in festen Pixeln
|
||||||
|
entworfene HUD auf 1440p und 4K winzig. --hud-scale setzt script.js.
|
||||||
|
transform-origin unten mittig, damit das Panel beim Skalieren zentriert
|
||||||
|
bleibt und der Abstand zum unteren Rand gleich wirkt. */
|
||||||
|
transform: translateX(-50%) scale(var(--hud-scale, 1));
|
||||||
|
transform-origin: bottom center;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: auto auto auto;
|
grid-template-columns: auto auto auto;
|
||||||
grid-template-rows: auto auto;
|
grid-template-rows: auto auto;
|
||||||
@@ -51,7 +56,7 @@ body {
|
|||||||
|
|
||||||
#hud.hidden {
|
#hud.hidden {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateX(-50%) translateY(14px);
|
transform: translateX(-50%) scale(var(--hud-scale, 1)) translateY(14px);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,21 +70,19 @@ body {
|
|||||||
|
|
||||||
/* --- Zeigerinstrumente --- */
|
/* --- Zeigerinstrumente --- */
|
||||||
|
|
||||||
.dial {
|
.dial-face {
|
||||||
grid-row: 1;
|
width: 96px;
|
||||||
|
height: 96px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Werte stehen unter den Uhren, nicht darin: auf 96 px kollidiert eine Zahl in
|
||||||
|
der Skala mit Strichen, Zeiger und rotem Bereich. Zusammen mit der Lampe
|
||||||
|
ergeben sie eine durchgehende zweite Zeile. */
|
||||||
|
.readout {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 2px;
|
||||||
}
|
|
||||||
|
|
||||||
#pressure { grid-column: 1; }
|
|
||||||
#depth { grid-column: 3; }
|
|
||||||
|
|
||||||
.dial-face {
|
|
||||||
position: relative;
|
|
||||||
width: 96px;
|
|
||||||
height: 96px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial-face svg {
|
.dial-face svg {
|
||||||
@@ -87,7 +90,7 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial .face {
|
.face {
|
||||||
fill: var(--dial-face);
|
fill: var(--dial-face);
|
||||||
stroke: rgba(148, 163, 184, 0.25);
|
stroke: rgba(148, 163, 184, 0.25);
|
||||||
stroke-width: 1.5;
|
stroke-width: 1.5;
|
||||||
@@ -95,32 +98,32 @@ body {
|
|||||||
|
|
||||||
/* Skalenzahlen gibt es bewusst nicht: bei dieser Groesse liest die niemand.
|
/* Skalenzahlen gibt es bewusst nicht: bei dieser Groesse liest die niemand.
|
||||||
Der Zeiger zeigt die Tendenz, die Zahl in der Mitte den genauen Wert. */
|
Der Zeiger zeigt die Tendenz, die Zahl in der Mitte den genauen Wert. */
|
||||||
.dial .ticks line {
|
.ticks line {
|
||||||
stroke: #cbd5e1;
|
stroke: #cbd5e1;
|
||||||
stroke-opacity: 0.4;
|
stroke-opacity: 0.4;
|
||||||
stroke-width: 1;
|
stroke-width: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial .ticks line.major {
|
.ticks line.major {
|
||||||
stroke-opacity: 0.85;
|
stroke-opacity: 0.85;
|
||||||
stroke-width: 1.6;
|
stroke-width: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial .zone {
|
.zone {
|
||||||
fill: none;
|
fill: none;
|
||||||
stroke: var(--danger);
|
stroke: var(--danger);
|
||||||
stroke-width: 3.5;
|
stroke-width: 3.5;
|
||||||
stroke-opacity: 0.9;
|
stroke-opacity: 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial .needle line {
|
.needle line {
|
||||||
stroke: var(--text);
|
stroke: var(--text);
|
||||||
stroke-width: 2.6;
|
stroke-width: 2.6;
|
||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
transition: stroke 260ms ease;
|
transition: stroke 260ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial .needle circle {
|
.needle circle {
|
||||||
fill: var(--text);
|
fill: var(--text);
|
||||||
transition: fill 260ms ease;
|
transition: fill 260ms ease;
|
||||||
}
|
}
|
||||||
@@ -128,21 +131,15 @@ body {
|
|||||||
/* Kein transform-origin hier: das rotate(winkel 50 50) im transform-Attribut
|
/* Kein transform-origin hier: das rotate(winkel 50 50) im transform-Attribut
|
||||||
bringt den Drehpunkt schon mit. Beides zusammen verschiebt den Zeiger aus der
|
bringt den Drehpunkt schon mit. Beides zusammen verschiebt den Zeiger aus der
|
||||||
Uhr heraus - CSS rechnet die Origin nochmal obendrauf. */
|
Uhr heraus - CSS rechnet die Origin nochmal obendrauf. */
|
||||||
.dial .needle {
|
.needle {
|
||||||
transition: transform 260ms ease-out;
|
transition: transform 260ms ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dial-value {
|
.value {
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: baseline;
|
||||||
justify-content: center;
|
gap: 3px;
|
||||||
gap: 2px;
|
font-size: 19px;
|
||||||
/* In den offenen unteren Teil der Skala, damit die Zahl nicht am
|
|
||||||
Zeiger-Drehpunkt klebt - wie das Sichtfenster eines echten Instruments. */
|
|
||||||
padding-top: 36px;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -150,31 +147,35 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.unit {
|
.unit {
|
||||||
font-size: 10px;
|
font-size: 11px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: var(--muted);
|
color: var(--muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zeiger und Wert faerben sich, sobald der rote Bereich erreicht ist. */
|
/* Zeiger und Wert faerben sich, sobald der rote Bereich erreicht ist. Die
|
||||||
#pressure.alert .needle line,
|
Klassen sitzen am HUD, weil Uhr und Wert in getrennten Grid-Zellen liegen. */
|
||||||
#depth.alert .needle line { stroke: var(--danger); }
|
#hud.pressure-alert #pressure-needle line { stroke: var(--danger); }
|
||||||
#pressure.alert .needle circle,
|
#hud.pressure-alert #pressure-needle circle { fill: var(--danger); }
|
||||||
#depth.alert .needle circle { fill: var(--danger); }
|
#hud.pressure-alert #pressure-readout .value { color: var(--danger); }
|
||||||
#pressure.alert .dial-value,
|
|
||||||
#depth.alert .dial-value { color: var(--danger); }
|
|
||||||
|
|
||||||
#depth.deep .dial-value { color: var(--warn); }
|
#hud.depth-alert #depth-needle line { stroke: var(--danger); }
|
||||||
#depth.deep .needle line { stroke: var(--warn); }
|
#hud.depth-alert #depth-needle circle { fill: var(--danger); }
|
||||||
#depth.deep .needle circle { fill: var(--warn); }
|
#hud.depth-alert #depth-readout .value { color: var(--danger); }
|
||||||
|
|
||||||
|
#hud.depth-deep #depth-needle line { stroke: var(--warn); }
|
||||||
|
#hud.depth-deep #depth-needle circle { fill: var(--warn); }
|
||||||
|
#hud.depth-deep #depth-readout .value { color: var(--warn); }
|
||||||
|
|
||||||
/* --- Luft-Ring --- */
|
/* --- Luft-Ring --- */
|
||||||
|
|
||||||
|
/* Oben ausgerichtet: die 2px gleichen 96 gegen 92 Durchmesser aus, damit alle
|
||||||
|
drei Instrumente auf einer Achse liegen. */
|
||||||
.gauge {
|
.gauge {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 92px;
|
width: 92px;
|
||||||
height: 92px;
|
height: 92px;
|
||||||
grid-column: 2;
|
align-self: start;
|
||||||
grid-row: 1;
|
margin-top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gauge svg {
|
.gauge svg {
|
||||||
@@ -221,8 +222,6 @@ body {
|
|||||||
/* --- Lampe --- */
|
/* --- Lampe --- */
|
||||||
|
|
||||||
.lamp {
|
.lamp {
|
||||||
grid-column: 2;
|
|
||||||
grid-row: 2;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
@@ -260,7 +259,7 @@ body {
|
|||||||
#hud.danger .gauge { animation: pulse 1s ease-in-out infinite; }
|
#hud.danger .gauge { animation: pulse 1s ease-in-out infinite; }
|
||||||
|
|
||||||
/* Tiefengrenze des Atemgases ueberschritten - Tiefenrausch laeuft. */
|
/* Tiefengrenze des Atemgases ueberschritten - Tiefenrausch laeuft. */
|
||||||
#hud.overlimit #depth .dial-face { animation: pulse 1s ease-in-out infinite; }
|
#hud.overlimit #depth-face { animation: pulse 1s ease-in-out infinite; }
|
||||||
|
|
||||||
@keyframes pulse {
|
@keyframes pulse {
|
||||||
0%, 100% { opacity: 1; }
|
0%, 100% { opacity: 1; }
|
||||||
|
|||||||
@@ -118,6 +118,22 @@ end
|
|||||||
|
|
||||||
lib.callback.register('d4rk_divegear:server:getTanks', getTankList)
|
lib.callback.register('d4rk_divegear:server:getTanks', getTankList)
|
||||||
|
|
||||||
|
--- Prüft, ob der Spieler die getragene Flasche überhaupt noch hat.
|
||||||
|
--- Ohne das konnte man die Flasche im Tauchgang weggeben und trotzdem
|
||||||
|
--- weiteratmen - der Client hielt nur eine Slot-Nummer, die niemand mehr prüfte.
|
||||||
|
--- @return number? slot aktueller Slot, nil wenn die Flasche weg ist
|
||||||
|
lib.callback.register('d4rk_divegear:server:verifyTank', function(source, slotId, name)
|
||||||
|
local slot = getTankSlot(source, slotId)
|
||||||
|
|
||||||
|
if slot and slot.name == name then return slotId end
|
||||||
|
|
||||||
|
-- Nur umsortiert? Dann dieselbe Flaschensorte woanders im Inventar suchen,
|
||||||
|
-- sonst kostet jedes Verschieben im Inventar die Ausrüstung.
|
||||||
|
local found = shared.tankByName[name] and exports.ox_inventory:Search(source, 'slots', name)
|
||||||
|
|
||||||
|
return found and found[1] and found[1].slot or nil
|
||||||
|
end)
|
||||||
|
|
||||||
lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen)
|
lib.callback.register('d4rk_divegear:server:syncTank', function(source, slotId, oxygen)
|
||||||
return syncTank(source, slotId, oxygen)
|
return syncTank(source, slotId, oxygen)
|
||||||
end)
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user