Initial commit: scan_web integrated recording UI
FastAPI backend + vanilla JS frontend for LiDAR/camera startup, camera settings, and rosbag recording, unifying the previous scan_gui/scan_gui_dual/ scan_gui_triple desktop tools into one web app.
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover">
|
||||
<title>scan_web</title>
|
||||
<link rel="stylesheet" href="/css/fonts.css">
|
||||
<link rel="stylesheet" href="/css/tokens.css">
|
||||
<link rel="stylesheet" href="/css/style.css">
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "/vendor/three/three.module.min.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
|
||||
<!-- Base layer, always full-screen: the live FAST-LIO point cloud. Empty
|
||||
state shown until the first accumulated points arrive. -->
|
||||
<section id="view-scan" class="scan-view">
|
||||
<canvas id="pointcloud-canvas"></canvas>
|
||||
<div id="scan-empty" class="scan-placeholder">
|
||||
<p>포인트 없음 — 시동 후 녹화를 시작하면 지도가 쌓입니다.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Fixed HUD — never scrolls, always on top of the scan view. -->
|
||||
<div class="hud">
|
||||
<div class="hud-top">
|
||||
<div id="status-badges" class="status-badges"></div>
|
||||
<div class="hud-top-right">
|
||||
<div id="map-points" class="disk-free hud-disk-free"></div>
|
||||
<div id="disk-free" class="disk-free hud-disk-free"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hud-bottom">
|
||||
<div class="hud-startup">
|
||||
<button id="btn-lidar-start" class="btn btn-green btn-hud">시동</button>
|
||||
<button id="btn-lidar-stop" class="btn btn-red btn-hud">정지</button>
|
||||
<div id="lidar-state" class="state-line">● 정지</div>
|
||||
</div>
|
||||
|
||||
<div class="hud-rec">
|
||||
<button id="btn-rec-open" class="btn btn-red btn-hud">● 녹화</button>
|
||||
<button id="btn-rec-stop" class="btn btn-gray btn-hud hidden">■ 정지</button>
|
||||
<div id="rec-meter" class="rec-meter hidden"></div>
|
||||
</div>
|
||||
|
||||
<div class="hud-actions">
|
||||
<button id="btn-settings" class="btn btn-gray btn-hud btn-icon" aria-label="설정">⚙</button>
|
||||
<button id="btn-estop" class="btn-estop btn-estop-hud">E-STOP</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings overlay — camera settings / preview / recent bags, plus the
|
||||
entry point into the log overlay. Floats over the scan view, closed by
|
||||
default. -->
|
||||
<div id="overlay-settings" class="overlay hidden">
|
||||
<div class="overlay-backdrop" data-close="overlay-settings"></div>
|
||||
<div class="overlay-sheet">
|
||||
<div class="overlay-header">
|
||||
<h2>설정</h2>
|
||||
<button class="btn-close" data-close="overlay-settings">✕</button>
|
||||
</div>
|
||||
<div class="overlay-tabs">
|
||||
<button class="pane-tab-btn active" data-pane="pane-camera-settings">카메라 설정</button>
|
||||
<button class="pane-tab-btn" data-pane="pane-camera-preview">미리보기</button>
|
||||
<button class="pane-tab-btn" data-pane="pane-lidar-test">라이다 테스트</button>
|
||||
<button class="pane-tab-btn" data-pane="pane-recent-bags">최근 녹화</button>
|
||||
<button id="btn-open-log" class="pane-tab-btn pane-tab-btn-log">로그</button>
|
||||
</div>
|
||||
<div class="overlay-body">
|
||||
<div class="pane-tab active" id="pane-camera-settings">
|
||||
<div class="tabs" id="camera-tabs"></div>
|
||||
<div id="camera-tab-panels"></div>
|
||||
</div>
|
||||
<div class="pane-tab" id="pane-camera-preview">
|
||||
<div id="camera-grid" class="camera-grid"></div>
|
||||
</div>
|
||||
<div class="pane-tab" id="pane-lidar-test">
|
||||
<p class="hint">녹화 없이 FAST-LIO만 켜서 라이다 포인트 품질을 미리 확인합니다.
|
||||
시작 후 몇 초간 흔들지 말고 가만히 두세요 — FAST-LIO가 정지 상태의 IMU로 중력 방향을 자동 정렬합니다.</p>
|
||||
<div class="btn-row">
|
||||
<button id="btn-fastlio-test-start" class="btn btn-blue">테스트 시작</button>
|
||||
<button id="btn-fastlio-test-stop" class="btn btn-gray">테스트 정지</button>
|
||||
</div>
|
||||
<div id="fastlio-test-state" class="state-line">● 정지</div>
|
||||
<h3>시점</h3>
|
||||
<div class="btn-row">
|
||||
<button id="btn-view-orbit" class="btn btn-blue">자유 시점</button>
|
||||
<button id="btn-view-lidar" class="btn btn-gray">라이다 시점</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pane-tab" id="pane-recent-bags">
|
||||
<ul id="bag-list" class="bag-list"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Recording modal — just enough to see/set the save path and filename
|
||||
before confirming; floats over the scan view. -->
|
||||
<div id="overlay-recording" class="overlay hidden">
|
||||
<div class="overlay-backdrop" data-close="overlay-recording"></div>
|
||||
<div class="overlay-sheet overlay-sheet-small">
|
||||
<div class="overlay-header">
|
||||
<h2>녹화 시작</h2>
|
||||
<button class="btn-close" data-close="overlay-recording">✕</button>
|
||||
</div>
|
||||
<div class="overlay-body">
|
||||
<div class="field-row">
|
||||
<label>저장 경로</label>
|
||||
<input type="text" id="rec-save-dir" />
|
||||
<button id="btn-browse" class="btn btn-small">…</button>
|
||||
</div>
|
||||
<div id="browse-panel" class="browse-panel hidden"></div>
|
||||
<div class="field-row">
|
||||
<label>파일 이름</label>
|
||||
<input type="text" id="rec-filename" placeholder="scan_001" />
|
||||
</div>
|
||||
<div class="btn-row">
|
||||
<button id="btn-rec-confirm" class="btn btn-red">● 녹화 시작</button>
|
||||
</div>
|
||||
<div id="rec-path" class="hint"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Log overlay — opened from inside Settings, stacks above it. -->
|
||||
<div id="overlay-log" class="overlay hidden">
|
||||
<div class="overlay-backdrop" data-close="overlay-log"></div>
|
||||
<div class="overlay-sheet">
|
||||
<div class="overlay-header">
|
||||
<h2>로그</h2>
|
||||
<div class="log-header-actions">
|
||||
<label class="log-autoscroll"><input type="checkbox" id="log-autoscroll" checked /> 자동 스크롤</label>
|
||||
<button id="btn-log-clear" class="btn btn-small btn-gray">지우기</button>
|
||||
<button class="btn-close" data-close="overlay-log">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="log-body" class="log-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="module" src="/js/app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user