feat: 침수심 범례 애니메이션 기능 추가

This commit is contained in:
swcho
2025-08-05 16:18:40 +09:00
parent 115fbbfc99
commit 71a7335de4
2 changed files with 37 additions and 28 deletions
+10 -11
View File
@@ -7,7 +7,7 @@ import GisApp from "@common/business_components/ui/map/lib/gis.core";
import SearchModal from "./searchModal/searchModal";
import FeatureClickEventPopup from "./components/popupComponent/featureClickEventPopup";
import { SearchBar } from "./searchBar/searchBar";
import { WaterDepth } from "./waterDepth/waterDepth";
import { WaterDepth, WATER_DEPTH_LAYER_TYPES, ORDERED_LAYERS } from "./waterDepth/waterDepth";
// 타입 정의 추가
export type LyrStngProps = {
@@ -41,6 +41,7 @@ const Map = () => {
const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); // SearchModal 열림 상태
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
const [showWaterDepth, setShowWaterDepth] = useState(false); // WaterDepth 표시 여부
const [isPlaying, setIsPlaying] = useState(false);
useEffect(() => {
@@ -121,23 +122,16 @@ const Map = () => {
// WaterDepth 표시 여부를 결정하는 함수
const handleWaterDepthVisibility = useCallback((checkedIds: string[], checkedNodesData: any[]) => {
// 침수 관련 레이어 ID들 (실제 데이터에 맞게 수정 필요)
const waterDepthLayerTypes = [
'tb_ms_flood_dngr_map', // 침수위험지도
'tb_ms_sbmrg_dngr_map' // 도시침수지도
];
// 체크된 레이어 중에 침수 관련 레이어가 있는지 확인
const hasWaterDepthLayer = checkedNodesData.some(node =>
waterDepthLayerTypes.includes(node.data?.lyrTyNm)
const waterDepthLayers = checkedNodesData.filter(node =>
WATER_DEPTH_LAYER_TYPES.includes(node.data?.lyrTyNm)
);
const hasWaterDepthLayer = waterDepthLayers.length > 0;
setShowWaterDepth(hasWaterDepthLayer);
}, []);
// 체크된 레이어 변경 처리 함수
const handleCheckedLayersChange = useCallback((checkedIds: string[], checkedNodesData: any[]) => {
// WaterDepth 표시 여부 결정
handleWaterDepthVisibility(checkedIds, checkedNodesData);
}, [handleWaterDepthVisibility]);
@@ -161,6 +155,11 @@ const Map = () => {
onCheckedLayersChange={handleCheckedLayersChange}
searchBar={SearchBar}
waterDepth={showWaterDepth ? WaterDepth : undefined}
isPlaying={isPlaying}
setIsPlaying={setIsPlaying}
targetLayerTypes={WATER_DEPTH_LAYER_TYPES}
orderedLayers={ORDERED_LAYERS}
checkInterval={1000}
/>
</div>
);
@@ -3,17 +3,39 @@
import React, { useRef, useEffect, useState } from "react";
import { Label } from "@common/components/ui/label";
export const WATER_DEPTH_LAYER_TYPES = [
'tb_ms_flood_dngr_map',
'tb_ms_sbmrg_dngr_map'
];
// 지정된 순서에 따른 lyr_sn 배열
export const ORDERED_LAYERS = [
'27', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 30년 빈도
'28', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 50년 빈도
'3', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 80년 빈도
'4', // 침수위험지도(tb_ms_sbmrg_dngr_map) - 100년 빈도
'59', // 도시침수지도(tb_ms_flood_dngr_map) - 30년 빈도
'60', // 도시침수지도(tb_ms_flood_dngr_map) - 50년 빈도
'58' // 도시침수지도(tb_ms_flood_dngr_map) - 80년 빈도
];
interface WaterDepthProps {
onClose?: () => void;
isPlaying: boolean;
setIsPlaying: (isPlaying: boolean) => void;
}
export function WaterDepth({
onClose,
isPlaying,
setIsPlaying,
}: WaterDepthProps) {
const [isPlaying, setIsPlaying] = useState<boolean>(false);
useEffect(() => {
if (setIsPlaying) setIsPlaying(isPlaying);
}, [isPlaying, setIsPlaying]);
const handlePlayToggle = () => {
setIsPlaying((prev) => !prev);
setIsPlaying(!isPlaying);
};
return (
@@ -21,23 +43,11 @@ export function WaterDepth({
<div className="bg-white rounded-lg shadow-lg border border-gray-200 w-[160px] px-4 py-3">
<div className="card-header flex items-center justify-between">
<Label className="text-3xl text-gray-900 font-bold">침수심 범례</Label>
<button
type="button"
className="ml-2"
onClick={handlePlayToggle}
>
<button type="button" className="ml-2" onClick={handlePlayToggle}>
{isPlaying ? (
<img
src="/images/map/toolbar/pause_button.png"
alt="pause"
className="w-6 h-6 object-contain"
/>
<img src="/images/map/toolbar/pause_button.png" alt="pause" className="w-6 h-6 object-contain" />
) : (
<img
src="/images/map/toolbar/play_button_arrowhead.png"
alt="play"
className="w-6 h-6 object-contain"
/>
<img src="/images/map/toolbar/play_button_arrowhead.png" alt="play" className="w-6 h-6 object-contain" />
)}
</button>
</div>