Court + Trajectory: split layout — 3D 80% left, cam previews + VAR in sidebar right

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ruslan Bakiev
2026-03-06 13:39:58 +07:00
parent 6fbc17c6e0
commit 351e3818f9

View File

@@ -94,22 +94,38 @@
}
.viewport-3d canvas { width: 100% !important; height: 100% !important; }
/* Court tab: 3D scene takes most space, cameras are small below */
.court-viewport-main {
height: calc(100vh - 240px);
min-height: 400px;
/* Split layout: 3D left ~80%, sidebar right ~20% with cam previews */
.split-layout {
display: flex;
height: calc(100vh - 100px);
overflow: hidden;
}
.split-main {
flex: 1;
position: relative;
min-width: 0;
}
.split-main .viewport-3d {
width: 100%;
height: 100%;
border-top: none;
}
.cameras-small {
padding: 4px 8px;
.split-sidebar {
width: 220px;
flex-shrink: 0;
display: flex;
flex-direction: column;
gap: 6px;
padding: 6px;
background: #0d0d20;
border-left: 1px solid #222;
overflow-y: auto;
}
.cam-box-small {
max-width: 320px;
flex: 0 0 auto;
}
.cam-box-small img {
.split-sidebar img {
width: 100%;
border-radius: 4px;
border: 1px solid #222;
display: block;
}
/* Calibrate button */
@@ -141,21 +157,21 @@
.calibrate-status .ok { color: #4ecca3; }
.calibrate-status .fail { color: #ff4444; }
/* VAR panel */
.var-panel {
/* VAR panel (sidebar version) */
.var-panel-sidebar {
display: flex;
align-items: stretch;
gap: 12px;
padding: 8px 16px;
flex-direction: column;
gap: 8px;
padding: 10px;
background: #111128;
border-top: 1px solid #222;
min-height: 60px;
border-radius: 6px;
border: 1px solid #222;
margin-top: 4px;
}
.var-indicator {
display: flex;
align-items: center;
gap: 8px;
padding: 0 12px;
}
.var-dot {
width: 14px;
@@ -189,8 +205,7 @@
.var-info .var-dist { color: #aaa; }
.var-snapshot {
width: 160px;
height: 90px;
width: 100%;
border-radius: 4px;
border: 1px solid #333;
object-fit: cover;
@@ -202,6 +217,7 @@
justify-content: center;
color: #444;
font-size: 11px;
height: 60px;
}
/* Event banner */
@@ -279,42 +295,42 @@
CAM 1: <span id="calStatus1">not calibrated</span>
</div>
</div>
<div class="viewport-3d court-viewport-main" id="court-3d"></div>
<div class="cameras cameras-small">
<div class="cam-box cam-box-small">
<img id="court-cam0" alt="Camera 0">
<div class="split-layout">
<div class="split-main">
<div class="viewport-3d" id="court-3d"></div>
</div>
<div class="cam-box cam-box-small">
<div class="split-sidebar">
<img id="court-cam0" alt="Camera 0">
<img id="court-cam1" alt="Camera 1">
</div>
</div>
</div>
<!-- Tab 3: Trajectory -->
<!-- Tab 3: Trajectory — 3D left, cam previews + VAR panel right -->
<div class="tab-content" id="tab-trajectory">
<div class="cameras">
<div class="cam-box">
<div class="split-layout">
<div class="split-main">
<div class="viewport-3d" id="trajectory-3d"></div>
</div>
<div class="split-sidebar">
<img id="traj-cam0" alt="Camera 0">
</div>
<div class="cam-box">
<img id="traj-cam1" alt="Camera 1">
<!-- VAR panel in sidebar -->
<div class="var-panel-sidebar">
<div class="var-indicator">
<div class="var-dot" id="varDot"></div>
<div class="var-label" id="varLabel">VAR</div>
</div>
<div class="var-info" id="varInfo">
<div class="var-line" id="varLine">No events</div>
<div class="var-timer" id="varTimer"></div>
<div class="var-dist" id="varDist"></div>
</div>
<img class="var-snapshot" id="varSnapshot" style="display:none">
<div class="var-snapshot empty" id="varSnapshotEmpty">No snapshot</div>
</div>
</div>
</div>
<div class="viewport-3d" id="trajectory-3d"></div>
<!-- VAR panel at the bottom of trajectory tab -->
<div class="var-panel">
<div class="var-indicator">
<div class="var-dot" id="varDot"></div>
<div class="var-label" id="varLabel">VAR</div>
</div>
<div class="var-info" id="varInfo">
<div class="var-line" id="varLine">No events</div>
<div class="var-timer" id="varTimer"></div>
<div class="var-dist" id="varDist"></div>
</div>
<img class="var-snapshot" id="varSnapshot" style="display:none">
<div class="var-snapshot empty" id="varSnapshotEmpty">No snapshot</div>
</div>
</div>
<div class="info-panel">