- 클라이언트(React/Vite): Video.js 플레이어, 하단 스테이션바, POI/구조물 영상 오버레이, 카메라 파라미터 보정, 미니맵/RoutePanel - 서버(Express): Range 스트리밍, HLS 변환, 프레임 추출, tus 업로드, 주석 API - 최근 작업: 스테이션바 종점역 표출/양끝 정렬/미도착(재생불가) 표시, POI 라벨 '구분' 우선·컴팩트 팝업·겹침제외 토글·동일좌표 다중행, 진행방향(상/하) 우선 표출, 커서 배지 크기·픽셀 떨림 개선 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1.9 KiB
1.9 KiB
StationOverlay 렌더링 최적화 — 텍스트 스무딩
소요 시간: 약 90분
Context 사용량: input ~40k / output ~12k tokens
이슈: 없음
작업 내용
문제
- 측점/지장물 텍스트 라벨이 영상 재생 중 뚝뚝 끊겨 표시됨
- 드론 pitch/GPS 노이즈 + 30fps 데이터 → 60fps RAF 스텝 차이
해결 과정
-
원인 분석
renderCacheRefuseEffect에서 CL 500개 × toCameraCoords = 매 33ms 메인 스레드 블로킹- 텍스트는 31개로 작은 부분이었음, CL이 실제 병목
- 디버그 패널 추가로 firstY 값이 5-7px 불규칙 점프 확인
-
텍스트 사전 계산 Map 도입
labelMapRef: Map<frameNum, {stationLabels, poiMarkers}>전 프레임 precomputerequestIdleCallback백그라운드 계산 (메인 스레드 비블로킹)- RAF:
Map.get(frameNum)O(1) 조회만
-
데이터 스무딩 (smoothFrame)
- ±N 프레임 이동 평균 (yaw는 sin/cos 평균 후 atan2)
- UI 슬라이더로 조절 가능 (0~60fr)
- 기본값: smooth=10
-
30fps→60fps 보간 (frac interpolation)
performance.now()로 prop 업데이트 이후 경과 시간 추정- 현재/다음 프레임 사이 선형 보간 → 스텝 제거
-
EMA (지수 이동 평균) 표시 위치 스무딩
displayedStRef,displayedPoiRef: 각 라벨별 현재 표시 위치 유지- RAF마다:
pos = prev + (target - prev) × α - UI 슬라이더로 α 조절 (0.01~1.0), 기본값: α=0.01
- α=0.01: 매우 부드럽지만 약간 뒤처짐
-
시각 개선
- 글씨 크기 2배 (9px→18px, 10px→20px)
- bold + strokeText 4px 검정 테두리 (배경 박스 제거)
- CL 중심선 재활성화
최종 기본값
- smoothHalf: 10 (±333ms 이동 평균)
- emaAlpha: 0.01 (~1600ms lag, 매우 부드러움)
산출물
client/src/components/overlay/StationOverlay.tsx전면 개편