- 클라이언트(React/Vite): Video.js 플레이어, 하단 스테이션바, POI/구조물 영상 오버레이, 카메라 파라미터 보정, 미니맵/RoutePanel - 서버(Express): Range 스트리밍, HLS 변환, 프레임 추출, tus 업로드, 주석 API - 최근 작업: 스테이션바 종점역 표출/양끝 정렬/미도착(재생불가) 표시, POI 라벨 '구분' 우선·컴팩트 팝업·겹침제외 토글·동일좌표 다중행, 진행방향(상/하) 우선 표출, 커서 배지 크기·픽셀 떨림 개선 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
46 lines
2.9 KiB
Markdown
46 lines
2.9 KiB
Markdown
# 오버레이가 영상과 어긋남 — object-fit:cover 크롭 정렬 (영상 해상도 사용)
|
||
|
||
**날짜**: 2026-06-24
|
||
**수정 파일**: `client/src/store/playerStore.ts`, `client/src/hooks/useVideoPlayer.ts`,
|
||
`client/src/components/player/VideoPlayer.tsx`, `client/src/components/overlay/StationOverlay.tsx`
|
||
**관련**: [2026-06-24_1051_라벨-멀리뒤로-가까이먼저-FOV진단.md](2026-06-24_1051_라벨-멀리뒤로-가까이먼저-FOV진단.md)
|
||
|
||
## 발단
|
||
"영상이 재생되는 브라우저의 해상도를 알 수 있나?" → 영상 표시 방식 점검 중 근본 원인 발견.
|
||
|
||
## 원인 (핵심)
|
||
영상은 `index.css`에서 **`object-fit: cover`** 로 표시 → 컨테이너 비율 ≠ 영상 비율(3840×2160=16:9)
|
||
이면 영상이 **확대·크롭**되어 채워짐. 그런데 **오버레이 캔버스는 컨테이너 전체**에 정규좌표(0~1)를
|
||
매핑하고 있었음. 즉 영상은 크롭된 영역에 보이는데 오버레이는 컨테이너 기준 → **가로/세로 배율·오프셋
|
||
불일치**. 이것이 라벨/선이 영상과 어긋나(멀리·가까이 다르게) 보이던 핵심 원인.
|
||
|
||
## 조치 — 오버레이를 영상 cover 사각형에 정렬 (영상 원본 해상도 사용)
|
||
1. **영상 해상도 확보**: playerStore `videoWidth/videoHeight` + `setVideoSize`. useVideoPlayer 에서
|
||
`loadedmetadata`/`loadeddata` 시 `player.videoWidth()/videoHeight()` 저장. VideoPlayer→StationOverlay prop 전달.
|
||
2. **cover 변환**: RAF draw 에서 영상 해상도로 cover 사각형 계산
|
||
```ts
|
||
const s = Math.max(W/vW, H/vH); // cover 배율(넘침=크롭)
|
||
dispW=vW*s; dispH=vH*s; offX=(W-dispW)/2; offY=(H-dispH)/2;
|
||
const vx = nx => offX + nx*dispW; // 정규(영상프레임) → 화면 px
|
||
const vy = ny => offY + ny*dispH;
|
||
```
|
||
중심선/드론궤적/측점·POI 라벨/드래그 피드백의 좌표를 모두 `*W,*H` → `vx(),vy()` 로 교체.
|
||
(나침반 HUD 는 화면 코너 고정이라 컨테이너 W/H 유지.)
|
||
3. **포인터 역변환**: `clientToVideoNorm()` 추가 — 클릭 client px → 영상프레임 정규좌표(cover 역변환).
|
||
POI 드래그 hit-test/이동이 크롭 상태에서도 정확히 일치.
|
||
4. **해상도 표시**: 카메라 파라미터 패널 진단줄에 `영상 W×H (비율 · cover 정렬)` 노출(사용자 확인용).
|
||
|
||
## 효과
|
||
- 컨테이너 비율이 16:9가 아니어도 오버레이가 **크롭된 영상과 픽셀 단위로 정렬**됨.
|
||
- 영상 해상도 미확정(vW/vH=0) 시 컨테이너 기준 폴백(기존 동작).
|
||
- 앞서 'FOV 의심'(§1051) 잔차의 상당부분이 실은 이 cover 불일치였을 가능성 큼 → 적용 후 재확인 필요.
|
||
|
||
## 검증
|
||
- `npm run build -w client` (node20) tsc + vite build 통과.
|
||
|
||
## 다음 단계
|
||
- 적용 후에도 멀·근 잔차가 남으면 그때 focal/sensorH(세로 FOV) 미세조정(§1051).
|
||
|
||
**소요 시간**: 약 15분
|
||
**Context 사용량**: input ~300k / output ~9k tokens
|