IMU Anzeige verbssert
This commit is contained in:
+117
-65
@@ -94,50 +94,76 @@
|
||||
S: <span id="overlay-distance">0,00</span> m
|
||||
</div>
|
||||
<div class="c-xhair">
|
||||
<svg viewBox="-90 -90 180 180" xmlns="http://www.w3.org/2000/svg" width="180" height="180">
|
||||
<!-- äußerer rotierender Strichelring -->
|
||||
<circle class="xh-rot" cx="0" cy="0" r="82" fill="none" stroke="rgba(0,255,145,.2)" stroke-width="1" stroke-dasharray="4 10"/>
|
||||
<!-- mittlerer Ring, Gegenrichtung -->
|
||||
<circle class="xh-rot-rev" cx="0" cy="0" r="60" fill="none" stroke="rgba(0,255,145,.15)" stroke-width=".75" stroke-dasharray="2 16"/>
|
||||
<!-- innerer fester Ring -->
|
||||
<circle cx="0" cy="0" r="16" fill="none" stroke="rgba(0,255,145,.3)" stroke-width=".75"/>
|
||||
<!-- Kreuzlinien mit Lücke in der Mitte -->
|
||||
<line x1="-86" y1="0" x2="-19" y2="0" stroke="rgba(0,255,145,.6)" stroke-width="1"/>
|
||||
<line x1="19" y1="0" x2="86" y2="0" stroke="rgba(0,255,145,.6)" stroke-width="1"/>
|
||||
<line x1="0" y1="-86" x2="0" y2="-19" stroke="rgba(0,255,145,.6)" stroke-width="1"/>
|
||||
<line x1="0" y1="19" x2="0" y2="86" stroke="rgba(0,255,145,.6)" stroke-width="1"/>
|
||||
<!-- Skalenstriche bei r=60 -->
|
||||
<line x1="-60" y1="-6" x2="-60" y2="6" stroke="rgba(0,255,145,.45)" stroke-width=".75"/>
|
||||
<line x1="60" y1="-6" x2="60" y2="6" stroke="rgba(0,255,145,.45)" stroke-width=".75"/>
|
||||
<line x1="-6" y1="-60" x2="6" y2="-60" stroke="rgba(0,255,145,.45)" stroke-width=".75"/>
|
||||
<line x1="-6" y1="60" x2="6" y2="60" stroke="rgba(0,255,145,.45)" stroke-width=".75"/>
|
||||
<!-- Skalenstriche bei r=38 -->
|
||||
<line x1="-38" y1="-3.5" x2="-38" y2="3.5" stroke="rgba(0,255,145,.3)" stroke-width=".5"/>
|
||||
<line x1="38" y1="-3.5" x2="38" y2="3.5" stroke="rgba(0,255,145,.3)" stroke-width=".5"/>
|
||||
<line x1="-3.5" y1="-38" x2="3.5" y2="-38" stroke="rgba(0,255,145,.3)" stroke-width=".5"/>
|
||||
<line x1="-3.5" y1="38" x2="3.5" y2="38" stroke="rgba(0,255,145,.3)" stroke-width=".5"/>
|
||||
<!-- Eckklammern -->
|
||||
<path d="M-74,-58 L-74,-74 L-58,-74" fill="none" stroke="rgba(0,255,145,.75)" stroke-width="1.5"/>
|
||||
<path d="M58,-74 L74,-74 L74,-58" fill="none" stroke="rgba(0,255,145,.75)" stroke-width="1.5"/>
|
||||
<path d="M-74,58 L-74,74 L-58,74" fill="none" stroke="rgba(0,255,145,.75)" stroke-width="1.5"/>
|
||||
<path d="M58,74 L74,74 L74,58" fill="none" stroke="rgba(0,255,145,.75)" stroke-width="1.5"/>
|
||||
<!-- pulsierender Ring -->
|
||||
<circle class="xh-pulse" cx="0" cy="0" r="6" fill="none" stroke="rgba(0,255,145,.7)" stroke-width="1"/>
|
||||
<svg viewBox="-110 -110 220 220" xmlns="http://www.w3.org/2000/svg" width="220" height="220">
|
||||
<!-- outer rotating dashed ring -->
|
||||
<circle class="xh-rot" cx="0" cy="0" r="103" fill="none" stroke="rgba(0,255,145,.14)" stroke-width="1" stroke-dasharray="4 13"/>
|
||||
<!-- roll arc (static) r=96, ±60° from top -->
|
||||
<path d="M -83.1 -48 A 96 96 0 0 1 83.1 -48" fill="none" stroke="rgba(0,255,145,.32)" stroke-width="1.25"/>
|
||||
<!-- roll tick marks via rotate() -->
|
||||
<g transform="rotate(0)"> <line x1="0" y1="-96" x2="0" y2="-84" stroke="rgba(0,255,145,.72)" stroke-width="1.5"/></g>
|
||||
<g transform="rotate(10)"> <line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.38)" stroke-width="1"/></g>
|
||||
<g transform="rotate(-10)"><line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.38)" stroke-width="1"/></g>
|
||||
<g transform="rotate(20)"> <line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.38)" stroke-width="1"/></g>
|
||||
<g transform="rotate(-20)"><line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.38)" stroke-width="1"/></g>
|
||||
<g transform="rotate(30)"> <line x1="0" y1="-96" x2="0" y2="-86" stroke="rgba(0,255,145,.58)" stroke-width="1.25"/></g>
|
||||
<g transform="rotate(-30)"><line x1="0" y1="-96" x2="0" y2="-86" stroke="rgba(0,255,145,.58)" stroke-width="1.25"/></g>
|
||||
<g transform="rotate(45)"> <line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.32)" stroke-width="1"/></g>
|
||||
<g transform="rotate(-45)"><line x1="0" y1="-96" x2="0" y2="-89" stroke="rgba(0,255,145,.32)" stroke-width="1"/></g>
|
||||
<!-- counter-rotating middle ring -->
|
||||
<circle class="xh-rot-rev" cx="0" cy="0" r="72" fill="none" stroke="rgba(0,255,145,.12)" stroke-width=".75" stroke-dasharray="2 20"/>
|
||||
<!-- inner fixed ring -->
|
||||
<circle cx="0" cy="0" r="20" fill="none" stroke="rgba(0,255,145,.25)" stroke-width=".75"/>
|
||||
<!-- cross lines with center gap -->
|
||||
<line x1="-107" y1="0" x2="-23" y2="0" stroke="rgba(0,255,145,.55)" stroke-width="1"/>
|
||||
<line x1="23" y1="0" x2="107" y2="0" stroke="rgba(0,255,145,.55)" stroke-width="1"/>
|
||||
<line x1="0" y1="-107" x2="0" y2="-23" stroke="rgba(0,255,145,.55)" stroke-width="1"/>
|
||||
<line x1="0" y1="23" x2="0" y2="107" stroke="rgba(0,255,145,.55)" stroke-width="1"/>
|
||||
<!-- scale ticks r=72 -->
|
||||
<line x1="-72" y1="-7" x2="-72" y2="7" stroke="rgba(0,255,145,.38)" stroke-width=".75"/>
|
||||
<line x1="72" y1="-7" x2="72" y2="7" stroke="rgba(0,255,145,.38)" stroke-width=".75"/>
|
||||
<line x1="-7" y1="-72" x2="7" y2="-72" stroke="rgba(0,255,145,.38)" stroke-width=".75"/>
|
||||
<line x1="-7" y1="72" x2="7" y2="72" stroke="rgba(0,255,145,.38)" stroke-width=".75"/>
|
||||
<!-- scale ticks r=46 -->
|
||||
<line x1="-46" y1="-4" x2="-46" y2="4" stroke="rgba(0,255,145,.22)" stroke-width=".5"/>
|
||||
<line x1="46" y1="-4" x2="46" y2="4" stroke="rgba(0,255,145,.22)" stroke-width=".5"/>
|
||||
<line x1="-4" y1="-46" x2="4" y2="-46" stroke="rgba(0,255,145,.22)" stroke-width=".5"/>
|
||||
<line x1="-4" y1="46" x2="4" y2="46" stroke="rgba(0,255,145,.22)" stroke-width=".5"/>
|
||||
<!-- corner brackets -->
|
||||
<path d="M-90,-72 L-90,-90 L-72,-90" fill="none" stroke="rgba(0,255,145,.72)" stroke-width="1.5"/>
|
||||
<path d="M72,-90 L90,-90 L90,-72" fill="none" stroke="rgba(0,255,145,.72)" stroke-width="1.5"/>
|
||||
<path d="M-90,72 L-90,90 L-72,90" fill="none" stroke="rgba(0,255,145,.72)" stroke-width="1.5"/>
|
||||
<path d="M72,90 L90,90 L90,72" fill="none" stroke="rgba(0,255,145,.72)" stroke-width="1.5"/>
|
||||
<!-- pulsing center ring -->
|
||||
<circle class="xh-pulse" cx="0" cy="0" r="7" fill="none" stroke="rgba(0,255,145,.65)" stroke-width="1"/>
|
||||
<!-- IMU group -->
|
||||
<g id="imu-horizon-group" opacity="0">
|
||||
<g id="imu-horizon-frame">
|
||||
<line id="imu-horizon-main" x1="-28" y1="0" x2="28" y2="0" stroke="rgba(0,255,145,.82)" stroke-width="1.25"/>
|
||||
<line x1="-9" y1="-9.9" x2="9" y2="-9.9" stroke="rgba(0,255,145,.36)" stroke-width=".9"/>
|
||||
<line x1="-13" y1="-19.8" x2="13" y2="-19.8" stroke="rgba(0,255,145,.36)" stroke-width=".9"/>
|
||||
<line x1="-9" y1="9.9" x2="9" y2="9.9" stroke="rgba(0,255,145,.36)" stroke-width=".9"/>
|
||||
<line x1="-13" y1="19.8" x2="13" y2="19.8" stroke="rgba(0,255,145,.36)" stroke-width=".9"/>
|
||||
<!-- roll pointer triangle (only rotates, no pitch offset) -->
|
||||
<g id="imu-roll-pointer">
|
||||
<polygon points="0,-90 -5.5,-79 5.5,-79" fill="rgba(0,255,145,.88)"/>
|
||||
</g>
|
||||
<text id="imu-heading-text" x="0" y="-48" fill="rgba(0,255,145,.78)" font-size="8.5" text-anchor="middle">HDG 0°</text>
|
||||
<text id="imu-roll-text" x="-56" y="52" fill="rgba(0,255,145,.78)" font-size="8.5" text-anchor="middle">R +0.0°</text>
|
||||
<text id="imu-pitch-text" x="56" y="52" fill="rgba(0,255,145,.78)" font-size="8.5" text-anchor="middle">P +0.0°</text>
|
||||
<!-- horizon + pitch ladder (rotates AND translates with pitch) -->
|
||||
<g id="imu-horizon-frame">
|
||||
<line x1="-11" y1="-33" x2="11" y2="-33" stroke="rgba(0,255,145,.28)" stroke-width=".9"/>
|
||||
<line x1="-11" y1="33" x2="11" y2="33" stroke="rgba(0,255,145,.28)" stroke-width=".9"/>
|
||||
<line x1="-17" y1="-22" x2="17" y2="-22" stroke="rgba(0,255,145,.44)" stroke-width=".9"/>
|
||||
<line x1="-17" y1="22" x2="17" y2="22" stroke="rgba(0,255,145,.44)" stroke-width=".9"/>
|
||||
<line x1="-10" y1="-11" x2="10" y2="-11" stroke="rgba(0,255,145,.3)" stroke-width=".85"/>
|
||||
<line x1="-10" y1="11" x2="10" y2="11" stroke="rgba(0,255,145,.3)" stroke-width=".85"/>
|
||||
<line id="imu-horizon-main" x1="-40" y1="0" x2="40" y2="0" stroke="rgba(0,255,145,.92)" stroke-width="1.5"/>
|
||||
<line x1="-40" y1="0" x2="-32" y2="-5" stroke="rgba(0,255,145,.92)" stroke-width="1.5"/>
|
||||
<line x1="40" y1="0" x2="32" y2="-5" stroke="rgba(0,255,145,.92)" stroke-width="1.5"/>
|
||||
</g>
|
||||
<!-- HDG readout with background box -->
|
||||
<rect x="-27" y="-70" width="54" height="13" fill="rgba(0,15,8,.58)" rx="1"/>
|
||||
<line x1="-27" y1="-70" x2="27" y2="-70" stroke="rgba(0,255,145,.28)" stroke-width=".5"/>
|
||||
<text id="imu-heading-text" x="0" y="-61.5" fill="rgba(0,255,145,.9)" font-size="9" text-anchor="middle" letter-spacing="1">HDG 000°</text>
|
||||
<!-- roll / pitch readouts -->
|
||||
<text id="imu-roll-text" x="-73" y="76" fill="rgba(0,255,145,.72)" font-size="7.5" text-anchor="middle">R +0.0°</text>
|
||||
<text id="imu-pitch-text" x="73" y="76" fill="rgba(0,255,145,.72)" font-size="7.5" text-anchor="middle">P +0.0°</text>
|
||||
</g>
|
||||
<!-- Mittelpunkt -->
|
||||
<circle cx="0" cy="0" r="2.5" fill="rgba(0,255,145,.9)"/>
|
||||
<circle cx="0" cy="0" r="1" fill="rgba(255,255,255,.7)"/>
|
||||
<!-- center dot -->
|
||||
<circle cx="0" cy="0" r="3" fill="rgba(0,255,145,.92)"/>
|
||||
<circle cx="0" cy="0" r="1.2" fill="rgba(255,255,255,.8)"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="c-scanlines"></div>
|
||||
@@ -336,6 +362,7 @@ function normalizeHeadingDeg(value) {
|
||||
function updateImuOverlaySvg() {
|
||||
var group = document.getElementById("imu-horizon-group");
|
||||
var frame = document.getElementById("imu-horizon-frame");
|
||||
var rollPointer = document.getElementById("imu-roll-pointer");
|
||||
var headingText = document.getElementById("imu-heading-text");
|
||||
var rollText = document.getElementById("imu-roll-text");
|
||||
var pitchText = document.getElementById("imu-pitch-text");
|
||||
@@ -350,11 +377,14 @@ function updateImuOverlaySvg() {
|
||||
var rollDeg = Number(imuOverlayState.rollDeg || 0);
|
||||
var pitchDeg = Number(imuOverlayState.pitchDeg || 0);
|
||||
var headingDeg = normalizeHeadingDeg(imuOverlayState.yawDeg);
|
||||
var pitchOffset = Math.max(-26, Math.min(26, pitchDeg * 1.1));
|
||||
var pitchOffset = Math.max(-55, Math.min(55, pitchDeg * 2.2));
|
||||
|
||||
group.setAttribute("opacity", "1");
|
||||
frame.setAttribute("transform", "rotate(" + (-rollDeg).toFixed(2) + ") translate(0 " + pitchOffset.toFixed(2) + ")");
|
||||
headingText.textContent = "HDG " + Math.round(headingDeg) + "°";
|
||||
if (rollPointer) {
|
||||
rollPointer.setAttribute("transform", "rotate(" + (-rollDeg).toFixed(2) + ")");
|
||||
}
|
||||
headingText.textContent = "HDG " + String(Math.round(headingDeg)).padStart(3, "0") + "°";
|
||||
rollText.textContent = "R " + formatSignedNumber(rollDeg, 1) + "°";
|
||||
pitchText.textContent = "P " + formatSignedNumber(pitchDeg, 1) + "°";
|
||||
}
|
||||
@@ -1076,44 +1106,66 @@ function drawImuHorizonOverlay(context, canvasWidth, canvasHeight, size) {
|
||||
|
||||
var cx = canvasWidth / 2;
|
||||
var cy = canvasHeight / 2;
|
||||
var unit = size / 180;
|
||||
var unit = size / 220;
|
||||
var rollRad = Number(imuOverlayState.rollDeg || 0) * Math.PI / 180;
|
||||
var pitchOffsetPx = Math.max(-26, Math.min(26, Number(imuOverlayState.pitchDeg || 0) * 0.9 * unit));
|
||||
var pitchOffsetPx = Math.max(-55, Math.min(55, Number(imuOverlayState.pitchDeg || 0) * 2.2)) * unit;
|
||||
var headingDeg = normalizeHeadingDeg(imuOverlayState.yawDeg);
|
||||
var rollDeg = Number(imuOverlayState.rollDeg || 0);
|
||||
var pitchDeg = Number(imuOverlayState.pitchDeg || 0);
|
||||
|
||||
/* roll pointer triangle (only roll, no pitch) */
|
||||
context.save();
|
||||
context.translate(cx, cy);
|
||||
context.rotate(-rollRad);
|
||||
context.beginPath();
|
||||
context.moveTo(0, -90 * unit);
|
||||
context.lineTo(-5.5 * unit, -79 * unit);
|
||||
context.lineTo(5.5 * unit, -79 * unit);
|
||||
context.closePath();
|
||||
context.fillStyle = "rgba(0,255,145,.88)";
|
||||
context.fill();
|
||||
context.restore();
|
||||
|
||||
/* horizon + pitch ladder */
|
||||
context.save();
|
||||
context.translate(cx, cy);
|
||||
context.rotate(-rollRad);
|
||||
context.translate(0, pitchOffsetPx);
|
||||
|
||||
context.strokeStyle = "rgba(0,255,145,.82)";
|
||||
context.lineWidth = 1.25 * unit;
|
||||
context.beginPath();
|
||||
context.moveTo(-28 * unit, 0);
|
||||
context.lineTo(28 * unit, 0);
|
||||
context.stroke();
|
||||
|
||||
context.strokeStyle = "rgba(0,255,145,.36)";
|
||||
context.lineWidth = 0.9 * unit;
|
||||
[-18, -9, 9, 18].forEach(function(stepDeg) {
|
||||
var y = stepDeg * 1.1 * unit;
|
||||
var span = Math.abs(stepDeg) === 18 ? 13 : 9;
|
||||
[
|
||||
{ y: -33, span: 11, op: .28 }, { y: 33, span: 11, op: .28 },
|
||||
{ y: -22, span: 17, op: .44 }, { y: 22, span: 17, op: .44 },
|
||||
{ y: -11, span: 10, op: .3 }, { y: 11, span: 10, op: .3 }
|
||||
].forEach(function(pl) {
|
||||
context.beginPath();
|
||||
context.moveTo(-span * unit, y);
|
||||
context.lineTo(span * unit, y);
|
||||
context.moveTo(-pl.span * unit, pl.y * unit);
|
||||
context.lineTo(pl.span * unit, pl.y * unit);
|
||||
context.strokeStyle = "rgba(0,255,145," + pl.op + ")";
|
||||
context.lineWidth = 0.9 * unit;
|
||||
context.stroke();
|
||||
});
|
||||
|
||||
context.strokeStyle = "rgba(0,255,145,.92)";
|
||||
context.lineWidth = 1.5 * unit;
|
||||
context.beginPath(); context.moveTo(-40 * unit, 0); context.lineTo(40 * unit, 0); context.stroke();
|
||||
context.beginPath(); context.moveTo(-40 * unit, 0); context.lineTo(-32 * unit, -5 * unit); context.stroke();
|
||||
context.beginPath(); context.moveTo(40 * unit, 0); context.lineTo(32 * unit, -5 * unit); context.stroke();
|
||||
context.restore();
|
||||
|
||||
/* HDG box + text labels */
|
||||
context.save();
|
||||
context.font = (8.5 * unit) + 'px "IBM Plex Mono", "Roboto Mono", monospace';
|
||||
context.fillStyle = "rgba(0,255,145,.78)";
|
||||
var bw = 54 * unit, bh = 13 * unit;
|
||||
context.fillStyle = "rgba(0,15,8,.58)";
|
||||
context.fillRect(cx - bw / 2, cy - 70 * unit, bw, bh);
|
||||
context.font = (9 * unit) + 'px "Consolas","Cascadia Mono",monospace';
|
||||
context.fillStyle = "rgba(0,255,145,.9)";
|
||||
context.textAlign = "center";
|
||||
context.textBaseline = "middle";
|
||||
context.fillText("HDG " + Math.round(headingDeg) + "°", cx, cy - (48 * unit));
|
||||
context.fillText("R " + formatSignedNumber(imuOverlayState.rollDeg, 1) + "°", cx - (56 * unit), cy + (52 * unit));
|
||||
context.fillText("P " + formatSignedNumber(imuOverlayState.pitchDeg, 1) + "°", cx + (56 * unit), cy + (52 * unit));
|
||||
context.fillText("HDG " + String(Math.round(headingDeg)).padStart(3, "0") + "°", cx, cy - 63.5 * unit);
|
||||
context.font = (7.5 * unit) + 'px "Consolas","Cascadia Mono",monospace';
|
||||
context.fillStyle = "rgba(0,255,145,.72)";
|
||||
context.fillText("R " + formatSignedNumber(rollDeg, 1) + "°", cx - 73 * unit, cy + 76 * unit);
|
||||
context.fillText("P " + formatSignedNumber(pitchDeg, 1) + "°", cx + 73 * unit, cy + 76 * unit);
|
||||
context.restore();
|
||||
}
|
||||
|
||||
@@ -1263,7 +1315,7 @@ function drawHudOverlayToCanvas(context, canvasWidth, canvasHeight) {
|
||||
context.fillText(document.getElementById("cam-live-text").textContent, canvasWidth / 2 + (6 * camScale * scaleToCanvas), padding);
|
||||
context.restore();
|
||||
|
||||
drawCrosshairOverlayToCanvas(context, canvasWidth, canvasHeight, 180 * camScale * scaleToCanvas);
|
||||
drawCrosshairOverlayToCanvas(context, canvasWidth, canvasHeight, 220 * camScale * scaleToCanvas);
|
||||
drawVignetteAndScanlines(context, canvasWidth, canvasHeight);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user