Zhen Ye commited on
Commit
b2e7d79
·
1 Parent(s): 1c2827d

fixed radar view

Browse files
LaserPerception/LaserPerception.css CHANGED
@@ -750,7 +750,7 @@ input[type="number"]:focus {
750
 
751
  .engage-grid {
752
  display: grid;
753
- grid-template-columns: 4.5fr 0.5fr;
754
  gap: 12px;
755
  min-height: 0;
756
  transition: grid-template-columns 0.3s ease;
@@ -769,11 +769,19 @@ input[type="number"]:focus {
769
  flex-direction: column;
770
  gap: 12px;
771
  min-height: 0;
772
- max-width: 320px;
773
  }
774
 
775
  .radar {
776
- height: 180px;
 
 
 
 
 
 
 
 
 
777
  }
778
 
779
  .strip {
 
750
 
751
  .engage-grid {
752
  display: grid;
753
+ grid-template-columns: 2.5fr 1.5fr;
754
  gap: 12px;
755
  min-height: 0;
756
  transition: grid-template-columns 0.3s ease;
 
769
  flex-direction: column;
770
  gap: 12px;
771
  min-height: 0;
 
772
  }
773
 
774
  .radar {
775
+ height: 540px;
776
+ display: flex;
777
+ flex-direction: column;
778
+ }
779
+
780
+ .radar canvas {
781
+ flex: 1;
782
+ width: 100%;
783
+ height: 100%;
784
+ display: block;
785
  }
786
 
787
  .strip {
LaserPerception/LaserPerception.html CHANGED
@@ -400,7 +400,7 @@
400
  </div>
401
  </h3>
402
 
403
- <div class="viewbox" style="min-height: 650px;">
404
  <video id="videoEngage" playsinline muted></video>
405
  <canvas id="engageOverlay" class="overlay"></canvas>
406
  <div class="watermark">LOCK · DIST · DWELL · AIMPOINT · FIRE/ASSESS</div>
 
400
  </div>
401
  </h3>
402
 
403
+ <div class="viewbox" style="min-height: 420px;">
404
  <video id="videoEngage" playsinline muted></video>
405
  <canvas id="engageOverlay" class="overlay"></canvas>
406
  <div class="watermark">LOCK · DIST · DWELL · AIMPOINT · FIRE/ASSESS</div>
LaserPerception/LaserPerception.js CHANGED
@@ -19,6 +19,7 @@
19
  const clamp = (x, a, b) => Math.min(b, Math.max(a, x));
20
  const lerp = (a, b, t) => a + (b - a) * t;
21
  const now = () => performance.now();
 
22
 
23
  const state = {
24
  videoUrl: null,
@@ -177,6 +178,9 @@
177
  const chipFeed = $("#chipFeed");
178
 
179
  const btnEngage = $("#btnEngage");
 
 
 
180
  const btnPause = $("#btnPause");
181
  const btnReset = $("#btnReset");
182
  const btnToggleSidebar = $("#btnToggleSidebar");
@@ -2311,24 +2315,7 @@
2311
  const ay = b.y + b.h * d.aim.rely;
2312
  drawAimpoint(ctx, ax, ay, isSel);
2313
 
2314
- // label
2315
- const range = Math.round(d.baseRange_m || 0);
2316
- const dwell = (d.baseDwell_s != null) ? d.baseDwell_s.toFixed(1) : "—";
2317
- const pk = (d.pkill != null) ? Math.round(d.pkill * 100) : "—";
2318
-
2319
- ctx.font = "bold 14px " + getComputedStyle(document.body).fontFamily;
2320
- const tag = `${d.id} · ${d.label} · R=${range}m · DWELL=${dwell}s · Pk=${pk}%`;
2321
- const tw = ctx.measureText(tag).width;
2322
- const tx = clamp(b.x, 6, w - tw - 12);
2323
- const ty = clamp(b.y - 12, 18, h - 12);
2324
-
2325
- ctx.fillStyle = "rgba(0,0,0,.50)";
2326
- ctx.strokeStyle = "rgba(255,255,255,.14)";
2327
- ctx.lineWidth = 1;
2328
- roundRect(ctx, tx - 6, ty - 14, tw + 12, 18, 8, true, true);
2329
-
2330
- ctx.fillStyle = "rgba(255,255,255,.86)";
2331
- ctx.fillText(tag, tx, ty);
2332
  });
2333
 
2334
  // click-to-select on canvas (manual aimpoint override can be added later)
@@ -2801,11 +2788,16 @@
2801
  } else if (tr.state === "ASSESS") {
2802
  tr.assessT += dtSec;
2803
  if (tr.assessT >= assessS) {
2804
- tr.killed = true;
2805
- tr.state = "KILL";
2806
- state.tracker.beamOn = false; // stop beam after kill to make it dramatic
2807
- chipBeam.textContent = "BEAM:OFF";
2808
- log(`Target ${tr.id} assessed neutralized.`, "g");
 
 
 
 
 
2809
  }
2810
  }
2811
 
@@ -2908,10 +2900,7 @@
2908
  if (!killed) {
2909
  drawAimpoint(ctx, ax, ay, isSel);
2910
  } else {
2911
- // killed marker
2912
- ctx.fillStyle = "rgba(34,197,94,.95)";
2913
- ctx.font = "14px " + getComputedStyle(document.body).fontFamily;
2914
- ctx.fillText("NEUTRALIZED", b.x + 10, b.y + 22);
2915
  }
2916
 
2917
  // dwell ring
@@ -2924,23 +2913,7 @@
2924
  ctx.stroke();
2925
  }
2926
 
2927
- // label with distance + dwell + margin
2928
- const rangeTag = Number.isFinite(displayRange.range)
2929
- ? `${Math.round(displayRange.range)}m (${displayRange.source})`
2930
- : "—";
2931
- const tag = `${tr.id} · R=${rangeTag} · DWELL=${reqD.toFixed(1)}s · ΔP=${margin >= 0 ? "+" : ""}${margin.toFixed(1)}kW`;
2932
- ctx.font = "bold 14px " + getComputedStyle(document.body).fontFamily;
2933
- const tw = ctx.measureText(tag).width;
2934
- const tx = clamp(b.x, 6, w - tw - 12);
2935
- const ty = clamp(b.y - 12, 18, h - 12);
2936
-
2937
- ctx.fillStyle = "rgba(0,0,0,.55)";
2938
- ctx.strokeStyle = "rgba(255,255,255,.14)";
2939
- ctx.lineWidth = 1;
2940
- roundRect(ctx, tx - 6, ty - 14, tw + 12, 18, 8, true, true);
2941
-
2942
- ctx.fillStyle = "rgba(255,255,255,.86)";
2943
- ctx.fillText(tag, tx, ty);
2944
 
2945
  // engagement strip indicator near bbox bottom
2946
  const st = tr.state || "TRACK";
@@ -2950,9 +2923,7 @@
2950
  ctx.fillRect(b.x, b.y + b.h + 4, clamp(b.w * 0.55, 70, b.w), 5);
2951
  ctx.globalAlpha = 1;
2952
 
2953
- ctx.fillStyle = "rgba(255,255,255,.82)";
2954
- ctx.font = "11px " + getComputedStyle(document.body).fontFamily;
2955
- ctx.fillText(st, b.x, b.y + b.h + 18);
2956
 
2957
  // beam line to selected aimpoint
2958
  if (state.tracker.beamOn && isSel && !killed) {
@@ -3026,6 +2997,14 @@
3026
  // ========= Radar rendering =========
3027
  function renderRadar() {
3028
  const ctx = radarCanvas.getContext("2d");
 
 
 
 
 
 
 
 
3029
  const w = radarCanvas.width, h = radarCanvas.height;
3030
  ctx.clearRect(0, 0, w, h);
3031
 
@@ -3033,7 +3012,7 @@
3033
  ctx.fillStyle = "rgba(0,0,0,.35)";
3034
  ctx.fillRect(0, 0, w, h);
3035
 
3036
- const cx = w * 0.5, cy = h * 0.55;
3037
  const R = Math.min(w, h) * 0.42;
3038
 
3039
  // rings
@@ -3065,7 +3044,7 @@
3065
  ctx.fill();
3066
 
3067
  // tracks as blips
3068
- const tracks = state.tracker.tracks.filter(t => !t.killed);
3069
  tracks.forEach(tr => {
3070
  const areaRange = rangeFromArea(tr);
3071
  const displayRange = getTrackDisplayRange(tr);
@@ -3087,16 +3066,17 @@
3087
  const py = cy + Math.sin(bearing) * rad;
3088
 
3089
  // color by engagement state
3090
- const col = tr.state === "FIRE" ? "rgba(239,68,68,.9)" :
3091
- (tr.state === "ASSESS" ? "rgba(245,158,11,.9)" :
3092
- "rgba(124,58,237,.9)");
 
3093
 
3094
  ctx.fillStyle = col;
3095
  ctx.beginPath();
3096
  ctx.arc(px, py, 5, 0, Math.PI * 2);
3097
  ctx.fill();
3098
 
3099
- ctx.fillStyle = "rgba(255,255,255,.75)";
3100
  ctx.font = "11px " + getComputedStyle(document.body).fontFamily;
3101
  const rangeLabel = Number.isFinite(displayRange.range)
3102
  ? `${Math.round(displayRange.range)}m`
 
19
  const clamp = (x, a, b) => Math.min(b, Math.max(a, x));
20
  const lerp = (a, b, t) => a + (b - a) * t;
21
  const now = () => performance.now();
22
+ const ENABLE_KILL = false;
23
 
24
  const state = {
25
  videoUrl: null,
 
178
  const chipFeed = $("#chipFeed");
179
 
180
  const btnEngage = $("#btnEngage");
181
+
182
+ // Debug hook for console inspection
183
+ window.__LP_STATE__ = state;
184
  const btnPause = $("#btnPause");
185
  const btnReset = $("#btnReset");
186
  const btnToggleSidebar = $("#btnToggleSidebar");
 
2315
  const ay = b.y + b.h * d.aim.rely;
2316
  drawAimpoint(ctx, ax, ay, isSel);
2317
 
2318
+ // no text overlay on first-frame view
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2319
  });
2320
 
2321
  // click-to-select on canvas (manual aimpoint override can be added later)
 
2788
  } else if (tr.state === "ASSESS") {
2789
  tr.assessT += dtSec;
2790
  if (tr.assessT >= assessS) {
2791
+ if (ENABLE_KILL) {
2792
+ tr.killed = true;
2793
+ tr.state = "KILL";
2794
+ state.tracker.beamOn = false; // stop beam after kill to make it dramatic
2795
+ chipBeam.textContent = "BEAM:OFF";
2796
+ log(`Target ${tr.id} assessed neutralized.`, "g");
2797
+ } else {
2798
+ tr.state = "ASSESS";
2799
+ tr.assessT = 0;
2800
+ }
2801
  }
2802
  }
2803
 
 
2900
  if (!killed) {
2901
  drawAimpoint(ctx, ax, ay, isSel);
2902
  } else {
2903
+ // killed marker (no text overlay)
 
 
 
2904
  }
2905
 
2906
  // dwell ring
 
2913
  ctx.stroke();
2914
  }
2915
 
2916
+ // no text overlay on engage view
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2917
 
2918
  // engagement strip indicator near bbox bottom
2919
  const st = tr.state || "TRACK";
 
2923
  ctx.fillRect(b.x, b.y + b.h + 4, clamp(b.w * 0.55, 70, b.w), 5);
2924
  ctx.globalAlpha = 1;
2925
 
2926
+ // no state text overlay on engage view
 
 
2927
 
2928
  // beam line to selected aimpoint
2929
  if (state.tracker.beamOn && isSel && !killed) {
 
2997
  // ========= Radar rendering =========
2998
  function renderRadar() {
2999
  const ctx = radarCanvas.getContext("2d");
3000
+ const rect = radarCanvas.getBoundingClientRect();
3001
+ const dpr = devicePixelRatio || 1;
3002
+ const targetW = Math.max(1, Math.floor(rect.width * dpr));
3003
+ const targetH = Math.max(1, Math.floor(rect.height * dpr));
3004
+ if (radarCanvas.width !== targetW || radarCanvas.height !== targetH) {
3005
+ radarCanvas.width = targetW;
3006
+ radarCanvas.height = targetH;
3007
+ }
3008
  const w = radarCanvas.width, h = radarCanvas.height;
3009
  ctx.clearRect(0, 0, w, h);
3010
 
 
3012
  ctx.fillStyle = "rgba(0,0,0,.35)";
3013
  ctx.fillRect(0, 0, w, h);
3014
 
3015
+ const cx = w * 0.5, cy = h * 0.5;
3016
  const R = Math.min(w, h) * 0.42;
3017
 
3018
  // rings
 
3044
  ctx.fill();
3045
 
3046
  // tracks as blips
3047
+ const tracks = state.tracker.tracks;
3048
  tracks.forEach(tr => {
3049
  const areaRange = rangeFromArea(tr);
3050
  const displayRange = getTrackDisplayRange(tr);
 
3066
  const py = cy + Math.sin(bearing) * rad;
3067
 
3068
  // color by engagement state
3069
+ const col = tr.killed ? "rgba(148,163,184,.65)" :
3070
+ (tr.state === "FIRE" ? "rgba(239,68,68,.9)" :
3071
+ (tr.state === "ASSESS" ? "rgba(245,158,11,.9)" :
3072
+ "rgba(124,58,237,.9)"));
3073
 
3074
  ctx.fillStyle = col;
3075
  ctx.beginPath();
3076
  ctx.arc(px, py, 5, 0, Math.PI * 2);
3077
  ctx.fill();
3078
 
3079
+ ctx.fillStyle = tr.killed ? "rgba(148,163,184,.75)" : "rgba(255,255,255,.75)";
3080
  ctx.font = "11px " + getComputedStyle(document.body).fontFamily;
3081
  const rangeLabel = Number.isFinite(displayRange.range)
3082
  ? `${Math.round(displayRange.range)}m`