|
| 1 | +import { LatLng } from "#types/LatLng"; |
| 2 | +import { MapProps } from "#types/MapProps"; |
| 3 | +import { getBounds, getMiddlePoint } from "#utils/pathUtils"; |
| 4 | +import { useCallback, useEffect, useRef, useState } from "react"; |
| 5 | + |
| 6 | +const useCardMap = ({ runningPath }: Pick<MapProps, "runningPath">) => { |
| 7 | + const container = useRef<HTMLDivElement>(null); |
| 8 | + const map = useRef<kakao.maps.Map>(); |
| 9 | + const polyLineRef = useRef<kakao.maps.Polyline>(); |
| 10 | + const [path] = useState<kakao.maps.LatLng[]>([]); |
| 11 | + |
| 12 | + useEffect(() => { |
| 13 | + if (!container.current || !runningPath) return; |
| 14 | + const { lat, lng } = getMiddlePoint(runningPath); |
| 15 | + map.current = new kakao.maps.Map(container.current, { |
| 16 | + center: new kakao.maps.LatLng(lat, lng), |
| 17 | + }); |
| 18 | + |
| 19 | + polyLineRef.current = new kakao.maps.Polyline({ |
| 20 | + map: map.current, |
| 21 | + path, |
| 22 | + }); |
| 23 | + map.current.setZoomable(false); |
| 24 | + map.current.setDraggable(false); |
| 25 | + drawPath(runningPath); |
| 26 | + const pathBounds = getBounds(runningPath || []); |
| 27 | + const sw = new kakao.maps.LatLng(pathBounds.minLat, pathBounds.minLng); |
| 28 | + const ne = new kakao.maps.LatLng(pathBounds.maxLat, pathBounds.maxLng); |
| 29 | + const mapBounds = new kakao.maps.LatLngBounds(sw, ne); |
| 30 | + map.current.setBounds(mapBounds); |
| 31 | + }, [runningPath, map]); |
| 32 | + |
| 33 | + const getLaMaByLatLng = (point: LatLng): kakao.maps.LatLng => { |
| 34 | + return new kakao.maps.LatLng(point.lat, point.lng); |
| 35 | + }; |
| 36 | + |
| 37 | + const drawPath = useCallback( |
| 38 | + async (path: LatLng[] | undefined) => { |
| 39 | + if (!path) { |
| 40 | + return; |
| 41 | + } |
| 42 | + if (!polyLineRef.current) return; |
| 43 | + polyLineRef.current.setPath(path.map((point) => getLaMaByLatLng(point))); |
| 44 | + }, |
| 45 | + [polyLineRef], |
| 46 | + ); |
| 47 | + |
| 48 | + return { |
| 49 | + map: map.current, |
| 50 | + path, |
| 51 | + renderMap: () => ( |
| 52 | + <div style={{ position: "relative" }}> |
| 53 | + <div ref={container} style={{ width: "100%", aspectRatio: `16 / 9` }} /> |
| 54 | + </div> |
| 55 | + ), |
| 56 | + }; |
| 57 | +}; |
| 58 | + |
| 59 | +export default useCardMap; |
0 commit comments