log탭 활성화

main
dongjin kim 6 months ago
parent 0919230213
commit e7ad1f3b55

@ -15,7 +15,7 @@ document.addEventListener('DOMContentLoaded', () => {
} }
// ================================================= // =================================================
// 1. 탭 전환 로직 // 1. 탭 전환 로직 (상단 메인 탭)
// ================================================= // =================================================
const tabVideo = document.getElementById('tab-video'); const tabVideo = document.getElementById('tab-video');
const tabModels = document.getElementById('tab-models'); const tabModels = document.getElementById('tab-models');
@ -41,6 +41,54 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
} }
// =================================================
// [신규] 오른쪽 사이드바 (Summary / Log) 탭 로직
// =================================================
const btnSummary = document.getElementById('btn-summary');
const btnLog = document.getElementById('btn-log');
const summaryListEl = document.getElementById('summary-list');
const logListEl = document.getElementById('log-list');
if (btnSummary && btnLog) {
btnSummary.addEventListener('click', () => {
btnSummary.classList.add('active');
btnLog.classList.remove('active');
if(summaryListEl) summaryListEl.classList.remove('hidden');
if(logListEl) logListEl.classList.add('hidden');
});
btnLog.addEventListener('click', () => {
btnLog.classList.add('active');
btnSummary.classList.remove('active');
if(summaryListEl) summaryListEl.classList.add('hidden');
if(logListEl) logListEl.classList.remove('hidden');
});
}
// 로그 업데이트 함수 (최신 50개 유지)
function updateLogPanel(textData) {
if (!logListEl) return;
const now = new Date();
const timeStr = now.toTimeString().split(' ')[0]; // HH:MM:SS
const row = document.createElement('div');
row.className = 'log-entry';
// JSON 문자열이 너무 길 수 있으므로 적절히 자르거나 그대로 표시
// 가독성을 위해 시간 + 데이터 표시
row.innerHTML = `<span class="log-time">[${timeStr}]</span> <span class="log-msg">${textData}</span>`;
// 최신 로그가 위로 오게 하거나 아래로 오게 할 수 있음 (여기선 위로 쌓음)
logListEl.prepend(row);
// 메모리 관리를 위해 50개 넘어가면 삭제
if (logListEl.children.length > 50) {
logListEl.removeChild(logListEl.lastChild);
}
}
// ================================================= // =================================================
// [신규] Mission UI 로직 // [신규] Mission UI 로직
// ================================================= // =================================================
@ -81,7 +129,7 @@ document.addEventListener('DOMContentLoaded', () => {
.catch(e => console.error(e)); .catch(e => console.error(e));
} }
const filterBar = document.getElementById('filter-bar'); const filterBar = document.getElementById('filter-bar');
function updateFilterBar(modelCode) { function updateFilterBar(modelCode) {
if(!filterBar) return; if(!filterBar) return;
@ -146,14 +194,11 @@ const filterBar = document.getElementById('filter-bar');
zoomInput.id = 'zoom-toggle'; zoomInput.id = 'zoom-toggle';
zoomInput.checked = false; // 기본값: 선택 안 됨 zoomInput.checked = false; // 기본값: 선택 안 됨
// 줌 기능 이벤트 리스너 (필요 시 로직 구현)
zoomInput.addEventListener('change', (e) => { zoomInput.addEventListener('change', (e) => {
if(e.target.checked) { if(e.target.checked) {
console.log("Zoom In Activated"); console.log("Zoom In Activated");
// 여기에 줌 확대 로직 추가
} else { } else {
console.log("Zoom In Deactivated"); console.log("Zoom In Deactivated");
// 여기에 줌 해제 로직 추가
} }
}); });
@ -162,13 +207,11 @@ const filterBar = document.getElementById('filter-bar');
filterBar.appendChild(zoomLabel); filterBar.appendChild(zoomLabel);
} }
// 초기 필터 상태 반영
updateActiveFilters(classInputs); updateActiveFilters(classInputs);
} }
function updateActiveFilters(classInputs) { function updateActiveFilters(classInputs) {
activeClassFilters.clear(); activeClassFilters.clear();
// 체크된 항목들만 Set에 추가
classInputs.forEach(inp => { classInputs.forEach(inp => {
if(inp.checked) activeClassFilters.add(inp.dataset.cls); if(inp.checked) activeClassFilters.add(inp.dataset.cls);
}); });
@ -200,7 +243,7 @@ const filterBar = document.getElementById('filter-bar');
const fpsDisplayEl = document.getElementById("fps-display"); const fpsDisplayEl = document.getElementById("fps-display");
const resolutionEl = document.getElementById("resolution-display"); const resolutionEl = document.getElementById("resolution-display");
const connMsgEl = document.getElementById("connection-msg"); const connMsgEl = document.getElementById("connection-msg");
const summaryListEl = document.getElementById("summary-list"); // summaryListEl은 상단에서 정의됨
let ctx = null; let ctx = null;
if (canvasEl) ctx = canvasEl.getContext('2d'); if (canvasEl) ctx = canvasEl.getContext('2d');
@ -222,6 +265,9 @@ const filterBar = document.getElementById('filter-bar');
ws.onmessage = (event) => { ws.onmessage = (event) => {
const data = event.data; const data = event.data;
if (typeof data === "string") { if (typeof data === "string") {
// [Log 기능 연결] 문자열(JSON) 데이터 수신 시 로그 패널에 출력
updateLogPanel(data);
try { try {
const meta = JSON.parse(data); const meta = JSON.parse(data);
if (meta.type === "frame") { if (meta.type === "frame") {
@ -274,7 +320,7 @@ const filterBar = document.getElementById('filter-bar');
displayClassName = LABEL_MAP[tagId].classes[clsId]; displayClassName = LABEL_MAP[tagId].classes[clsId];
} }
// [수정] 필터링 로직 강화: Set에 없으면 절대 그리지 않음 (All 체크 로직과 연동) // 필터링
if (!activeClassFilters.has(displayClassName)) { if (!activeClassFilters.has(displayClassName)) {
return; return;
} }
@ -500,5 +546,3 @@ const filterBar = document.getElementById('filter-bar');
loadModelList(); loadModelList();
}); });
//2025-12-04 15:41

@ -96,8 +96,8 @@
<aside class="mission-right"> <aside class="mission-right">
<div class="right-header"> <div class="right-header">
<span class="active">Summary</span> <span id="btn-summary" class="active">Summary</span>
<span>Log</span> <span id="btn-log">Log</span>
</div> </div>
<div class="summary-content" id="summary-list"> <div class="summary-content" id="summary-list">
<div class="summary-row"> <div class="summary-row">
@ -105,6 +105,7 @@
<span class="count">-</span> <span class="count">-</span>
</div> </div>
</div> </div>
<div class="log-content hidden" id="log-list"></div>
</aside> </aside>
</div> </div>
</div> </div>
@ -215,5 +216,3 @@
<script src="app.js"></script> <script src="app.js"></script>
</body> </body>
</html> </html>
<!--//2025-12-04 15:41-->

@ -252,7 +252,7 @@ main {
/* 5-3. 우측 사이드바 (정보 패널) */ /* 5-3. 우측 사이드바 (정보 패널) */
.mission-right { .mission-right {
width: 200px; background-color: #444; width: 300px; background-color: #444;
border-left: 1px solid #666; border-left: 1px solid #666;
display: flex; flex-direction: column; display: flex; flex-direction: column;
} }
@ -274,6 +274,24 @@ main {
.summary-row .label { color: #fff; } .summary-row .label { color: #fff; }
.summary-row .count { color: #fff; font-weight: bold; } .summary-row .count { color: #fff; font-weight: bold; }
/* [신규] Log Content 스타일 */
.log-content {
padding: 10px;
overflow-y: auto;
flex-grow: 1;
font-family: 'Consolas', 'Monaco', monospace; /* 코드 폰트 */
font-size: 12px;
background-color: #222; /* 로그 배경은 더 어둡게 */
}
.log-entry {
margin-bottom: 5px;
border-bottom: 1px solid #333;
word-break: break-all; /* 긴 JSON 줄바꿈 */
color: #ccc;
}
.log-time { color: #888; font-weight: bold; margin-right: 5px; }
.log-msg { color: #0f0; } /* 메시지는 녹색 터미널 느낌 */
/* ========================================================== */ /* ========================================================== */
/* 7. 설정 탭 - AI 모델 & 관심 인물 관리 (Settings) */ /* 7. 설정 탭 - AI 모델 & 관심 인물 관리 (Settings) */
/* ========================================================== */ /* ========================================================== */
@ -340,5 +358,3 @@ main {
.modal-image { margin: auto; display: block; max-width: 90%; max-height: 90%; border-radius: 5px; animation-name: zoom; animation-duration: 0.4s; } .modal-image { margin: auto; display: block; max-width: 90%; max-height: 90%; border-radius: 5px; animation-name: zoom; animation-duration: 0.4s; }
@keyframes zoom { from {transform:scale(0)} to {transform:scale(1)} } @keyframes zoom { from {transform:scale(0)} to {transform:scale(1)} }
.close-viewer { position: absolute; top: 20px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; transition: 0.3s; cursor: pointer; z-index: 2001; } .close-viewer { position: absolute; top: 20px; right: 35px; color: #f1f1f1; font-size: 40px; font-weight: bold; transition: 0.3s; cursor: pointer; z-index: 2001; }
/*//2025-12-04 15:41*/
Loading…
Cancel
Save