From da28e22374e81585d6f1ce9a511eb916197964c1 Mon Sep 17 00:00:00 2001 From: pushedrumex Date: Fri, 25 Nov 2022 06:22:11 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EC=A7=91=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A7=80=EB=8F=84=EC=9C=84?= =?UTF-8?q?=EC=97=90=20=EC=BD=94=EC=8A=A4=20=EB=82=98=ED=83=80=EB=82=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=84=B1=EA=B3=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/hooks/useShowMap.tsx | 57 ++++++++++++++++++++++++++++++ client/src/hooks/useWriteMap.tsx | 1 + client/src/pages/RecruitDetail.tsx | 39 ++++++++++++++++++-- client/src/types/MapProps.ts | 1 + 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 client/src/hooks/useShowMap.tsx diff --git a/client/src/hooks/useShowMap.tsx b/client/src/hooks/useShowMap.tsx new file mode 100644 index 0000000..3cf7d5f --- /dev/null +++ b/client/src/hooks/useShowMap.tsx @@ -0,0 +1,57 @@ +import ZoomControl from "#components/MapControl/ZoomControl/ZoomControl"; +import { LatLng } from "#types/LatLng"; +import { MapProps } from "#types/MapProps"; +import { useCallback, useEffect, useRef, useState } from "react"; +import useZoomControl from "./useZoomControl"; + +const useShowMap = ({ height = "100vh", center, level = 1, runningPath }: MapProps) => { + const container = useRef(null); + const map = useRef(); + const polyLineRef = useRef(); + const [path, setPath] = useState([]); + const { zoomIn, zoomOut } = useZoomControl(map); + + useEffect(() => { + if (!container.current) return; + map.current = new kakao.maps.Map(container.current, { + center: new kakao.maps.LatLng(center.lat, center.lng), + level, + }); + polyLineRef.current = new kakao.maps.Polyline({ + map: map.current, + path, + }); + DrawPath(runningPath); + }, [runningPath]); + const getLaMaByLatLng = (point: LatLng): kakao.maps.LatLng => { + return new kakao.maps.LatLng(point.lat, point.lng); + }; + const DrawPath = useCallback( + async (path: { lat: number; lng: number }[] | undefined) => { + if (!path) { + return; + } + if (!polyLineRef.current) return; + for (const point of path) { + const position = getLaMaByLatLng(point); + const newPath = [...polyLineRef.current.getPath(), position]; + setPath(newPath); + polyLineRef.current.setPath(newPath); + } + }, + [polyLineRef], + ); + + return { + map: map.current, + path, + renderMap: () => ( +
+
+ +
+ ), + }; +}; + +export default useShowMap; diff --git a/client/src/hooks/useWriteMap.tsx b/client/src/hooks/useWriteMap.tsx index ae8284b..78bcc73 100644 --- a/client/src/hooks/useWriteMap.tsx +++ b/client/src/hooks/useWriteMap.tsx @@ -46,6 +46,7 @@ const useWriteMap = ({ height = "100vh", center, level = 1 }: MapProps) => { async (mouseEvent: kakao.maps.event.MouseEvent) => { if (!polyLineRef.current) return; const position = mouseEvent.latLng; + console.log(mouseEvent.latLng); const isRoad = await checkIsRoad(position); if (isRoad) { const newPath = [...polyLineRef.current.getPath(), position]; diff --git a/client/src/pages/RecruitDetail.tsx b/client/src/pages/RecruitDetail.tsx index ce83aca..da5ad1c 100644 --- a/client/src/pages/RecruitDetail.tsx +++ b/client/src/pages/RecruitDetail.tsx @@ -7,7 +7,7 @@ import { useRecoilValue } from "recoil"; import useHttpPost from "#hooks/http/useHttpPost"; import useHttpGet from "#hooks/http/useHttpGet"; import { useEffect, useState, useCallback } from "react"; -import ViewMap from "#components/Map/ViewMap/ViewMap"; +import useShowMap from "#hooks/useShowMap"; const RecruitDetail = () => { const { id } = useParams(); @@ -21,6 +21,8 @@ const RecruitDetail = () => { const [author, setAuthor] = useState("게시자"); const [maxPpl, setMaxPpl] = useState("최대 인원"); const [currentPpl, setCurrentPpl] = useState("현재 인원"); + const [path, setPath] = useState([]); + const [middlePoint, setMiddlePoint] = useState({ lat: 0, lng: 0 }); const getPaceFormat = (sec: number): string => { return `${parseInt(String(sec / 60))}'${sec % 60}"`; @@ -44,7 +46,36 @@ const RecruitDetail = () => { alert(error.message); } }; - + const renderMap = useCallback( + useShowMap({ + height: `${window.innerHeight - 307}px`, + center: { lat: middlePoint.lat, lng: middlePoint.lng }, + runningPath: path, + level: 5, + }).renderMap, + [path, middlePoint], + ); + const getMiddlePoint = (path: { lat: number; lng: number }[]) => { + let minLat = 90; + let maxLat = -90; + let minLng = 180; + let maxLng = -180; + for (const point of path) { + if (minLat > point.lat) { + minLat = point.lat; + } + if (maxLat < point.lat) { + maxLat = point.lat; + } + if (minLng > point.lng) { + minLng = point.lng; + } + if (maxLng < point.lng) { + maxLng = point.lng; + } + } + return { lat: (minLat + maxLat) / 2, lng: (minLng + maxLng) / 2 }; + }; const getRecruitDetail = useCallback(async () => { try { const response = await get(`/recruit/${id}`); @@ -55,6 +86,8 @@ const RecruitDetail = () => { setAuthor(response.userId); setMaxPpl(response.maxPpl); setCurrentPpl(response.currentPpl); + setPath(JSON.parse(response.path)); + setMiddlePoint(getMiddlePoint(JSON.parse(response.path))); } catch {} }, []); @@ -67,7 +100,7 @@ const RecruitDetail = () => { return ( <>
- + {renderMap()} {title}
diff --git a/client/src/types/MapProps.ts b/client/src/types/MapProps.ts index 5fd6887..211eb33 100644 --- a/client/src/types/MapProps.ts +++ b/client/src/types/MapProps.ts @@ -11,4 +11,5 @@ export interface MapProps { * 숫자가 작을수록 zoom-in */ level?: number; + runningPath?: { lat: number; lng: number }[]; }