fix(map): Globe 렌더링 안정화 및 툴팁 유지 개선 #29
@ -1,6 +1,5 @@
|
|||||||
import { useEffect, type MutableRefObject } from 'react';
|
import { useEffect, useRef, type MutableRefObject } from 'react';
|
||||||
import type maplibregl from 'maplibre-gl';
|
import type maplibregl from 'maplibre-gl';
|
||||||
import { onMapStyleReady } from '../lib/mapCore';
|
|
||||||
import type { MapProjectionId } from '../types';
|
import type { MapProjectionId } from '../types';
|
||||||
|
|
||||||
export function useFlyTo(
|
export function useFlyTo(
|
||||||
@ -19,7 +18,11 @@ export function useFlyTo(
|
|||||||
) {
|
) {
|
||||||
const { selectedMmsi, shipData, mapInitiatedSelectRef, fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom } = opts;
|
const { selectedMmsi, shipData, mapInitiatedSelectRef, fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom } = opts;
|
||||||
|
|
||||||
// 패널(좌측 목록)에서 선택 시 해당 선박 위치로 이동
|
// shipData를 ref로 — 의존성에서 제외하여 AIS poll마다 재실행 방지
|
||||||
|
const shipDataRef = useRef(shipData);
|
||||||
|
useEffect(() => { shipDataRef.current = shipData; }, [shipData]);
|
||||||
|
|
||||||
|
// 패널(좌측 목록)에서 선택 시 해당 선박 위치로 즉시 이동
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 지도 내부 클릭에서 발생한 선택이면 스킵
|
// 지도 내부 클릭에서 발생한 선택이면 스킵
|
||||||
if (mapInitiatedSelectRef.current) {
|
if (mapInitiatedSelectRef.current) {
|
||||||
@ -30,53 +33,37 @@ export function useFlyTo(
|
|||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map || selectedMmsi == null) return;
|
if (!map || selectedMmsi == null) return;
|
||||||
|
|
||||||
const target = shipData.find((t) => t.mmsi === selectedMmsi);
|
const target = shipDataRef.current.find((t) => t.mmsi === selectedMmsi);
|
||||||
if (!target || !Number.isFinite(target.lon) || !Number.isFinite(target.lat)) return;
|
if (!target || !Number.isFinite(target.lon) || !Number.isFinite(target.lat)) return;
|
||||||
|
|
||||||
const apply = () => {
|
try {
|
||||||
const flyOpts = { center: [target.lon, target.lat] as [number, number], duration: 700 };
|
const flyOpts = { center: [target.lon, target.lat] as [number, number], duration: 400 };
|
||||||
if (projectionRef.current === 'globe') {
|
if (projectionRef.current === 'globe') {
|
||||||
map.flyTo(flyOpts);
|
map.flyTo(flyOpts);
|
||||||
} else {
|
} else {
|
||||||
map.easeTo(flyOpts);
|
map.easeTo(flyOpts);
|
||||||
}
|
}
|
||||||
};
|
} catch {
|
||||||
|
// ignore — style not ready 등
|
||||||
if (map.isStyleLoaded()) {
|
|
||||||
apply();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
const stop = onMapStyleReady(map, apply);
|
}, [selectedMmsi]);
|
||||||
return () => { stop(); };
|
|
||||||
}, [selectedMmsi, shipData]);
|
|
||||||
|
|
||||||
// 선단 포커스 이동
|
// 선단 포커스 이동
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const map = mapRef.current;
|
const map = mapRef.current;
|
||||||
if (!map || fleetFocusLon == null || fleetFocusLat == null || !Number.isFinite(fleetFocusLon) || !Number.isFinite(fleetFocusLat))
|
if (!map || fleetFocusLon == null || fleetFocusLat == null || !Number.isFinite(fleetFocusLon) || !Number.isFinite(fleetFocusLat))
|
||||||
return;
|
return;
|
||||||
const lon = fleetFocusLon;
|
|
||||||
const lat = fleetFocusLat;
|
|
||||||
const zoom = fleetFocusZoom ?? 10;
|
|
||||||
|
|
||||||
const apply = () => {
|
try {
|
||||||
const flyOpts = { center: [lon, lat] as [number, number], zoom, duration: 700 };
|
const flyOpts = { center: [fleetFocusLon, fleetFocusLat] as [number, number], zoom: fleetFocusZoom ?? 10, duration: 500 };
|
||||||
if (projectionRef.current === 'globe') {
|
if (projectionRef.current === 'globe') {
|
||||||
map.flyTo(flyOpts);
|
map.flyTo(flyOpts);
|
||||||
} else {
|
} else {
|
||||||
map.easeTo(flyOpts);
|
map.easeTo(flyOpts);
|
||||||
}
|
}
|
||||||
};
|
} catch {
|
||||||
|
// ignore
|
||||||
if (map.isStyleLoaded()) {
|
|
||||||
apply();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const stop = onMapStyleReady(map, apply);
|
|
||||||
return () => {
|
|
||||||
stop();
|
|
||||||
};
|
|
||||||
}, [fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom]);
|
}, [fleetFocusId, fleetFocusLon, fleetFocusLat, fleetFocusZoom]);
|
||||||
}
|
}
|
||||||
|
|||||||
불러오는 중...
Reference in New Issue
Block a user