기록 재생 중 자동 갱신 리셋 방지

This commit is contained in:
seo
2026-07-11 07:24:30 +09:00
parent eea0846e68
commit b34cd5e17f
2 changed files with 18 additions and 6 deletions
+2
View File
@@ -74,6 +74,8 @@ Naver Map에는 단일 Polyline 중심의 부드러운 경로선을 먼저 그
기록 시간 슬라이더를 움직이면 얼굴 아이콘 선택 마커가 해당 시점으로 이동하고, 지도 아래에는 `월. 일. 시간` 형식의 선택 시각만 간결하게 표시합니다. 경로 재생도 같은 얼굴 아이콘 마커를 사용합니다. 재생 버튼은 지점 수에 따라 의미 있는 배속만 남겨 `2x`, `5x`, `10x`, `20x`, `50x`, `100x`, `500x` 순서로 돌고, 각 배속에서 최소 80단계 이상 보여줄 수 없으면 해당 배속은 건너뜁니다. 80m 반경 안에서 10분 이상 머문 구간은 체류 지점 마커로 묶어 표시하며, 클릭 시 체류 시간과 시작/종료 시각을 확인할 수 있습니다. 기록 시간 슬라이더를 움직이면 얼굴 아이콘 선택 마커가 해당 시점으로 이동하고, 지도 아래에는 `월. 일. 시간` 형식의 선택 시각만 간결하게 표시합니다. 경로 재생도 같은 얼굴 아이콘 마커를 사용합니다. 재생 버튼은 지점 수에 따라 의미 있는 배속만 남겨 `2x`, `5x`, `10x`, `20x`, `50x`, `100x`, `500x` 순서로 돌고, 각 배속에서 최소 80단계 이상 보여줄 수 없으면 해당 배속은 건너뜁니다. 80m 반경 안에서 10분 이상 머문 구간은 체류 지점 마커로 묶어 표시하며, 클릭 시 체류 시간과 시작/종료 시각을 확인할 수 있습니다.
재생 중 주기적 위치 갱신으로 히스토리 경로가 다시 그려져도 현재 재생 위치를 유지합니다. 재생 타이머는 시작 당시 지점 목록에 고정하지 않고 최신 히스토리 지점 목록을 기준으로 계속 진행합니다.
라이브 위치에는 설정된 집 150m 원과 GPS 정확도 원만 표시합니다. 히스토리 범위 조회나 기록 재생 중에는 현재 위치 사진 마커와 정확도 원을 숨기고, 종료 지점 정보창을 자동으로 열지 않습니다. `Naver 지도` 버튼은 히스토리 선택 지점 또는 현재 위치를 Naver 지도에서 바로 엽니다. 라이브 위치에는 설정된 집 150m 원과 GPS 정확도 원만 표시합니다. 히스토리 범위 조회나 기록 재생 중에는 현재 위치 사진 마커와 정확도 원을 숨기고, 종료 지점 정보창을 자동으로 열지 않습니다. `Naver 지도` 버튼은 히스토리 선택 지점 또는 현재 위치를 Naver 지도에서 바로 엽니다.
## 센서 표시 정책 ## 센서 표시 정책
+16 -6
View File
@@ -1964,14 +1964,20 @@ function startHistoryPlayback(speed) {
let tick = 0; let tick = 0;
mapState.playbackTimer = setInterval(() => { mapState.playbackTimer = setInterval(() => {
const index = Math.min(mapState.playbackIndex || 0, points.length - 1); const currentPoints = mapState.historyPoints || [];
const point = points[index]; if (!currentPoints.length) {
stopHistoryPlayback();
return;
}
const index = Math.min(mapState.playbackIndex || 0, currentPoints.length - 1);
const point = currentPoints[index];
moveSelectedHistoryPoint(index, false); moveSelectedHistoryPoint(index, false);
if (tick % 8 === 0) mapState.map.panTo(point.latlng); if (tick % 8 === 0) mapState.map.panTo(point.latlng);
const nextIndex = index + speed; const nextIndex = index + speed;
if (nextIndex >= points.length) { if (nextIndex >= currentPoints.length) {
moveSelectedHistoryPoint(points.length - 1, false); moveSelectedHistoryPoint(currentPoints.length - 1, false);
stopHistoryPlayback(); stopHistoryPlayback();
return; return;
} }
@@ -2272,9 +2278,13 @@ function applyHistoryCounts(data) {
function renderHistoryPoints(rawPoints) { function renderHistoryPoints(rawPoints) {
if (!mapState.map || !rawPoints?.length) return; if (!mapState.map || !rawPoints?.length) return;
const keepPlaybackIndex = !!mapState.playbackTimer;
const previousPlaybackIndex = Number.isFinite(mapState.playbackIndex) ? mapState.playbackIndex : 0;
const points = filterHistoryOutliers(rawPoints); const points = filterHistoryOutliers(rawPoints);
mapState.historyPoints = points; mapState.historyPoints = points;
mapState.playbackIndex = 0; mapState.playbackIndex = keepPlaybackIndex
? Math.max(0, Math.min(points.length - 1, previousPlaybackIndex))
: 0;
drawSpeedTrack(points); drawSpeedTrack(points);
mapState.stayPoints = buildStayPoints(points); mapState.stayPoints = buildStayPoints(points);
mapState.homeStats = buildHomeStats(points); mapState.homeStats = buildHomeStats(points);
@@ -2360,7 +2370,7 @@ function renderHistoryPoints(rawPoints) {
mapState.historyBoundsFitted = true; mapState.historyBoundsFitted = true;
} }
if (!_overrideRange && !mapState.initialInfoOpened && mapState.historyEndMarker?.infoWindow) { if (!_overrideRange && !keepPlaybackIndex && !mapState.initialInfoOpened && mapState.historyEndMarker?.infoWindow) {
mapState.historyEndMarker.infoWindow.open(mapState.map, mapState.historyEndMarker); mapState.historyEndMarker.infoWindow.open(mapState.map, mapState.historyEndMarker);
mapState.openInfoWindow = mapState.historyEndMarker.infoWindow; mapState.openInfoWindow = mapState.historyEndMarker.infoWindow;
mapState.initialInfoOpened = true; mapState.initialInfoOpened = true;