diff --git a/frontend/src/component/canvas/Canvas.tsx b/frontend/src/component/canvas/Canvas.tsx deleted file mode 100644 index 6b4e7a37..00000000 --- a/frontend/src/component/canvas/Canvas.tsx +++ /dev/null @@ -1,245 +0,0 @@ -// /* eslint-disable */ -// import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; -// import classNames from 'classnames'; -// import { ButtonState } from '@/component/common/enums'; -// import { useFloatingButton } from '@/hooks/useFloatingButton'; -// import { FloatingButton } from '@/component/common/floatingbutton/FloatingButton'; -// import { MdArrowCircleLeft, MdArrowCircleRight } from 'react-icons/md'; -// -// interface ICanvasProps { -// className?: string; -// onPointConverted?: (latLng: { lat: number; lng: number }) => { x: number; y: number } | null; -// onPointReverted?: (point: { x: number; y: number }) => { lat: number; lng: number } | null; -// } -// -// interface IPoint { -// x: number; -// y: number; -// latLng?: { lat: number; lng: number }; -// } -// -// interface ICanvasRefMethods { -// getCanvasElement: () => HTMLCanvasElement | null; -// setScale: (scale: number) => void; -// setPosition: (x: number, y: number) => void; -// clear: () => void; -// redraw: () => void; -// } -// -// // 선의 스타일 상수 -// const LINE_WIDTH = 2; -// const STROKE_STYLE = 'black'; -// const START_MARKER_COLOR = '#4CAF50'; -// const END_MARKER_COLOR = '#F44336'; -// const MARKER_RADIUS = 6; -// -// export const Canvas = forwardRef((props, ref) => { -// const canvasRef = useRef(null); -// const [points, setPoints] = useState([]); -// const [undoStack, setUndoStack] = useState([]); -// const [redoStack, setRedoStack] = useState([]); -// const [startPoint, setStartPoint] = useState(null); -// const [endPoint, setEndPoint] = useState(null); -// const { isMenuOpen, toolType, toggleMenu, handleMenuClick } = useFloatingButton(); -// -// // Transform state -// const scaleRef = useRef(1); -// const offsetRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); -// -// useEffect(() => { -// const canvas = canvasRef.current; -// if (!canvas) return; -// -// canvas.width = canvas.offsetWidth; -// canvas.height = canvas.offsetHeight; -// -// redraw(); -// }, []); -// -// const clear = () => { -// const canvas = canvasRef.current; -// const context = canvas?.getContext('2d'); -// if (!canvas || !context) return; -// -// context.clearRect(0, 0, canvas.width, canvas.height); -// }; -// -// const drawMarker = (context: CanvasRenderingContext2D, point: IPoint, color: string) => { -// const scaledRadius = MARKER_RADIUS / scaleRef.current; -// -// context.beginPath(); -// context.arc( -// (point.x - offsetRef.current.x) / scaleRef.current, -// (point.y - offsetRef.current.y) / scaleRef.current, -// scaledRadius, -// 0, -// 2 * Math.PI, -// ); -// context.fillStyle = color; -// context.fill(); -// context.strokeStyle = 'white'; -// context.lineWidth = 2 / scaleRef.current; -// context.stroke(); -// }; -// -// const redraw = () => { -// const canvas = canvasRef.current; -// const context = canvas?.getContext('2d'); -// if (!canvas || !context) return; -// -// clear(); -// -// // Set line style -// context.lineWidth = LINE_WIDTH / scaleRef.current; -// context.strokeStyle = STROKE_STYLE; -// context.lineCap = 'round'; -// context.lineJoin = 'round'; -// -// // Draw lines -// if (points.length > 0) { -// context.beginPath(); -// points.forEach((point, index) => { -// const x = (point.x - offsetRef.current.x) / scaleRef.current; -// const y = (point.y - offsetRef.current.y) / scaleRef.current; -// -// if (index === 0) { -// context.moveTo(x, y); -// } else { -// context.lineTo(x, y); -// } -// }); -// context.stroke(); -// } -// -// // Draw markers -// if (startPoint) { -// drawMarker(context, startPoint, START_MARKER_COLOR); -// } -// if (endPoint) { -// drawMarker(context, endPoint, END_MARKER_COLOR); -// } -// }; -// -// const addPoint = (point: IPoint) => { -// setPoints(prev => { -// const newPoints = [...prev, point]; -// setUndoStack(stack => [...stack, prev]); -// setRedoStack([]); -// return newPoints; -// }); -// }; -// -// const undo = () => { -// if (undoStack.length === 0) return; -// -// const previousPoints = undoStack[undoStack.length - 1]; -// setPoints(previousPoints); -// setUndoStack(stack => stack.slice(0, -1)); -// setRedoStack(stack => [...stack, points]); -// redraw(); -// }; -// -// const redo = () => { -// if (redoStack.length === 0) return; -// -// const nextPoints = redoStack[redoStack.length - 1]; -// setPoints(nextPoints); -// setRedoStack(stack => stack.slice(0, -1)); -// setUndoStack(stack => [...stack, points]); -// redraw(); -// }; -// -// const handleCanvasClick = (e: React.MouseEvent) => { -// const canvas = canvasRef.current; -// if (!canvas) return; -// -// const rect = canvas.getBoundingClientRect(); -// const x = (e.clientX - rect.left) * scaleRef.current + offsetRef.current.x; -// const y = (e.clientY - rect.top) * scaleRef.current + offsetRef.current.y; -// -// // Convert to lat/lng if converter is provided -// let latLng; -// if (props.onPointReverted) { -// latLng = props.onPointReverted({ x, y }); -// } -// -// // @ts-ignore -// const point: IPoint = { x, y, latLng }; -// -// switch (toolType) { -// case ButtonState.LINE_DRAWING: -// addPoint(point); -// break; -// case ButtonState.START_MARKER: -// setStartPoint(point); -// break; -// case ButtonState.DESTINATION_MARKER: -// setEndPoint(point); -// break; -// default: -// addPoint(point); -// break; -// } -// -// redraw(); -// }; -// -// useImperativeHandle(ref, () => ({ -// getCanvasElement: () => canvasRef.current, -// setScale: (scale: number) => { -// scaleRef.current = scale; -// redraw(); -// }, -// setPosition: (x: number, y: number) => { -// offsetRef.current = { x, y }; -// redraw(); -// }, -// clear, -// redraw, -// })); -// -// return ( -//
-//
-// -// -//
-// -// -// -//
-// -//
-//
-// ); -// }); - diff --git a/frontend/src/component/canvas/CanvasWithMap.tsx b/frontend/src/component/canvas/CanvasWithMap.tsx deleted file mode 100644 index 0f12a458..00000000 --- a/frontend/src/component/canvas/CanvasWithMap.tsx +++ /dev/null @@ -1,114 +0,0 @@ -// import { Canvas, ICanvasRefMethods } from '@/component/canvas/Canvas.tsx'; -// import { Map, IMapRefMethods } from '@/component/maps/Map.tsx'; -// import classNames from 'classnames'; -// import { ICanvasVertex } from '@/utils/screen/canvasUtils.ts'; -// import { INaverMapVertexPosition } from '@/component/maps/naverMapUtils.ts'; -// import { useRef, useEffect, useState } from 'react'; -// -// interface ICanvasWithMapProps { -// className?: string; -// lat: number; -// lng: number; -// zoom: number; -// mapType: string; -// allowCanvas?: boolean; -// } -// -// interface IMouseEventState { -// isMouseDown: boolean; -// mouseDownPosition: { x: number; y: number }; -// // mouseMovePosition: { x: number; y: number }; -// mouseDeltaPosition: { x: number; y: number }; -// } -// -// export interface ILocationObject { -// canvas: ICanvasVertex; -// map: INaverMapVertexPosition; -// } -// -// const MouseEventStateInitialValue = { -// isMouseDown: false, -// mouseDownPosition: { x: 0, y: 0 }, -// // mouseMovePosition: { x: 0, y: 0 }, -// mouseDeltaPosition: { x: 0, y: 0 }, -// }; -// -// export const CanvasWithMap = (props: ICanvasWithMapProps) => { -// const mapRefMethods = useRef(null); -// const mapElement = useRef(null); -// const canvasRefMethods = useRef(null); -// const canvasElement = useRef(null); -// const mouseEventState = useRef({ ...MouseEventStateInitialValue }); -// const [mapObject, setMapObject] = useState(null); -// -// useEffect(() => { -// if (canvasRefMethods.current?.getCanvasElement) -// canvasElement.current = canvasRefMethods.current.getCanvasElement(); -// }, []); -// -// useEffect(() => { -// mapElement.current = mapRefMethods.current?.getMapContainer() ?? null; -// }, [mapObject]); -// -// const initMap = (mapObj: naver.maps.Map | null) => { -// setMapObject(mapObj); -// }; -// -// const handleClick = (event: React.MouseEvent) => { -// mapRefMethods.current?.onMouseClickHandler(event); -// canvasRefMethods.current?.onMouseClickHandler(event); -// }; -// -// const handleMouseDown = (event: React.MouseEvent) => { -// if (!mapElement.current || !canvasElement.current) return; -// mouseEventState.current.isMouseDown = true; -// mouseEventState.current.mouseDownPosition = { x: event.clientX, y: event.clientY }; -// canvasRefMethods.current?.onMouseDownHandler(event); -// }; -// -// const handleMouseMove = (event: React.MouseEvent) => { -// if (!mapElement.current || !canvasElement.current || !mouseEventState.current.isMouseDown) -// return; -// -// // TODO: 쓰로틀링 걸기 -// mouseEventState.current.mouseDeltaPosition = { -// x: -(event.clientX - mouseEventState.current.mouseDownPosition.x), -// y: -(event.clientY - mouseEventState.current.mouseDownPosition.y), -// }; -// -// mapObject?.panBy( -// new naver.maps.Point( -// mouseEventState.current.mouseDeltaPosition.x, -// mouseEventState.current.mouseDeltaPosition.y, -// ), -// ); -// -// canvasRefMethods.current?.onMouseMoveHandler(event); -// }; -// -// const handleMouseUp = (event: React.MouseEvent) => { -// if (!mapElement.current || !canvasElement.current) return; -// mouseEventState.current = { ...MouseEventStateInitialValue }; -// canvasRefMethods.current?.onMouseUpHandler(event); -// }; -// -// return ( -//
-// {props.allowCanvas && } -// -//
-// ); -// }; \ No newline at end of file diff --git a/frontend/src/component/canvas/useEventHandlers.tsx b/frontend/src/component/canvas/useEventHandlers.tsx deleted file mode 100644 index 1e7a3d7e..00000000 --- a/frontend/src/component/canvas/useEventHandlers.tsx +++ /dev/null @@ -1,86 +0,0 @@ -// import { useRef } from 'react'; -// import { ICanvasRefMethods } from '@/component/canvas/Canvas.tsx'; -// import { IMapObject, IMapRefMethods } from '@/component/maps/Map.types.ts'; -// -// // TODO: 리팩토룅 시 null을 처리하기 -// interface IUseEventHandlers { -// ( -// canvasElement: HTMLCanvasElement | null, -// canvasRefMethods: ICanvasRefMethods | null, -// mapElement: HTMLElement | null, -// mapRefMethods: IMapRefMethods | null, -// mapObject: IMapObject | null, // 비동기 로딩 시 null로 처리가 될 수 있어서 예외처리 필요 -// ): { -// handleClick: (event: React.MouseEvent) => void; -// handleMouseDown: (event: React.MouseEvent) => void; -// handleMouseMove: (event: React.MouseEvent) => void; -// handleMouseUp: (event: React.MouseEvent) => void; -// }; -// } -// -// interface IMouseEventState { -// isMouseDown: boolean; -// mouseDownPosition: { x: number; y: number }; -// // mouseMovePosition: { x: number; y: number }; -// mouseDeltaPosition: { x: number; y: number }; -// } -// -// const MouseEventStateInitialValue = { -// isMouseDown: false, -// mouseDownPosition: { x: 0, y: 0 }, -// // mouseMovePosition: { x: 0, y: 0 }, -// mouseDeltaPosition: { x: 0, y: 0 }, -// }; -// -// export const useEventHandlers: IUseEventHandlers = ( -// canvasElement, -// canvasRefMethods, -// mapElement, -// mapRefMethods, -// mapObject, -// ) => { -// // if (!canvasElement || !canvasElement || !mapElement || !mapRefMethods || !mapObject) -// // throw new Error('🚀 useEventHandler error : null 값이 포함되어 있습니다.'); -// -// const mouseEventState = useRef({ ...MouseEventStateInitialValue }); -// -// const handleClick = (event: React.MouseEvent) => { -// mapRefMethods?.onMouseClickHandler(event); -// canvasRefMethods?.onMouseClickHandler(event); -// }; -// -// const handleMouseDown = (event: React.MouseEvent) => { -// if (!mapElement || !canvasElement) return; -// mouseEventState.current.isMouseDown = true; -// mouseEventState.current.mouseDownPosition = { x: event.clientX, y: event.clientY }; -// canvasRefMethods?.onMouseDownHandler(event); -// }; -// -// const handleMouseMove = (event: React.MouseEvent) => { -// if (!mapElement || !canvasElement || !mouseEventState.current.isMouseDown) return; -// -// // TODO: 쓰로틀링 걸기 -// mouseEventState.current.mouseDeltaPosition = { -// x: -(event.clientX - mouseEventState.current.mouseDownPosition.x), -// y: -(event.clientY - mouseEventState.current.mouseDownPosition.y), -// }; -// -// // TODO: 범용 지도에 따른 Refactoring 필요, 우선은 네이버 지도에 한해서만 수행 -// mapObject?.panBy( -// new naver.maps.Point( -// mouseEventState.current.mouseDeltaPosition.x, -// mouseEventState.current.mouseDeltaPosition.y, -// ), -// ); -// -// canvasRefMethods?.onMouseMoveHandler(event); -// }; -// -// const handleMouseUp = (event: React.MouseEvent) => { -// if (!mapElement || !canvasElement) return; -// mouseEventState.current = { ...MouseEventStateInitialValue }; -// canvasRefMethods?.onMouseUpHandler(event); -// }; -// -// return { handleClick, handleMouseDown, handleMouseMove, handleMouseUp }; -// }; diff --git a/frontend/src/component/maps/MapCanvas.tsx b/frontend/src/component/canvasWithMap/MapCanvasForDraw.tsx similarity index 95% rename from frontend/src/component/maps/MapCanvas.tsx rename to frontend/src/component/canvasWithMap/MapCanvasForDraw.tsx index 8862ef38..f7e068c0 100644 --- a/frontend/src/component/maps/MapCanvas.tsx +++ b/frontend/src/component/canvasWithMap/MapCanvasForDraw.tsx @@ -10,7 +10,12 @@ import { useUndoRedo } from '@/hooks/useUndoRedo.ts'; import startmarker from '@/assets/startmarker.png'; import endmarker from '@/assets/endmarker.png'; -export const MapCanvas = ({ width, height, initialCenter, initialZoom }: IMapCanvasProps) => { +export const MapCanvasForDraw = ({ + width, + height, + initialCenter, + initialZoom, +}: IMapCanvasProps) => { const mapRef = useRef(null); const canvasRef = useRef(null); const [projection, setProjection] = useState(null); @@ -350,24 +355,6 @@ export const MapCanvas = ({ width, height, initialCenter, initialZoom }: IMapCan } }; - // const undo = () => { - // if (undoStack.length === 0) return; - // const previousPoints = undoStack[undoStack.length - 2]; - // setPathPoints(previousPoints); - // setUndoStack(stack => stack.slice(0, -1)); - // setRedoStack(stack => [...stack, pathPoints]); - // redrawCanvas(); - // }; - // - // const redo = () => { - // if (redoStack.length === 0) return; - // const nextPoints = redoStack[redoStack.length - 1]; - // setPathPoints(nextPoints); - // setRedoStack(stack => stack.slice(0, -1)); - // setUndoStack(stack => [...stack, pathPoints]); - // redrawCanvas(); - // }; - useEffect(() => { if (isDragging) { if (canvasRef.current) { diff --git a/frontend/src/component/maps/Canvas.tsx b/frontend/src/component/canvasWithMap/MapProviderForDraw.tsx similarity index 86% rename from frontend/src/component/maps/Canvas.tsx rename to frontend/src/component/canvasWithMap/MapProviderForDraw.tsx index 0c5cf884..11e6ffb5 100644 --- a/frontend/src/component/maps/Canvas.tsx +++ b/frontend/src/component/canvasWithMap/MapProviderForDraw.tsx @@ -1,9 +1,9 @@ import { useEffect, useState } from 'react'; -import { MapCanvas } from '@/component/maps/MapCanvas.tsx'; +import { MapCanvasForDraw } from '@/component/canvasWithMap/MapCanvasForDraw.tsx'; import { DEFAULT_CENTER } from '@/lib/constants/mapConstants.ts'; import { ICanvasScreenProps } from '@/lib/types/canvasInterface.ts'; -export const FullScreenMap = ({ width, height }: ICanvasScreenProps) => { +export const MapProviderForDraw = ({ width, height }: ICanvasScreenProps) => { const [windowSize, setWindowSize] = useState({ width, height, @@ -44,7 +44,7 @@ export const FullScreenMap = ({ width, height }: ICanvasScreenProps) => { }, []); return ( - { -// const canvasRef = useRef(null); -// const { points, addPoint, undo, redo, undoStack, redoStack } = useUndoRedo([]); -// const [startPoint, setStartPoint] = useState(null); -// const [endPoint, setEndPoint] = useState(null); -// const { isMenuOpen, toolType, toggleMenu, handleMenuClick } = useFloatingButton(); -// -// const { draw, scaleRef, viewPosRef } = useDrawing({ -// canvasRef, -// points, -// startPoint, -// endPoint, -// lineWidth: LINE_WIDTH, -// strokeStyle: STROKE_STYLE, -// initialScale: NAVER_STEP_SCALES[INITIAL_ZOOM_INDEX], -// }); -// -// const { handleMouseMove, handleMouseDown, handleMouseUp } = usePanning({ viewPosRef, draw }); -// const { handleWheel } = useZoom({ -// scaleRef, -// viewPosRef, -// draw, -// stepScales: NAVER_STEP_SCALES, -// initialZoomIndex: INITIAL_ZOOM_INDEX, -// }); -// -// const handleCanvasClick = (e: React.MouseEvent) => { -// const rect = canvasRef.current?.getBoundingClientRect(); -// if (!rect) return; -// -// const x = (e.clientX - rect.left - viewPosRef.current.x) / scaleRef.current; -// const y = (e.clientY - rect.top - viewPosRef.current.y) / scaleRef.current; -// -// switch (toolType) { -// case ButtonState.LINE_DRAWING: -// addPoint({ x, y }); -// break; -// case ButtonState.START_MARKER: -// setStartPoint({ x, y }); -// break; -// case ButtonState.DESTINATION_MARKER: -// setEndPoint({ x, y }); -// break; -// default: -// break; -// } -// -// draw(); -// }; -// -// return ( -//
-//
-// -// -//
-// -//
-// -//
-//
-// ); -// }; diff --git a/frontend/src/component/maps/Map.tsx b/frontend/src/component/maps/Map.tsx deleted file mode 100644 index 016ba5e8..00000000 --- a/frontend/src/component/maps/Map.tsx +++ /dev/null @@ -1,80 +0,0 @@ -// import { NaverMap } from '@/component/maps/NaverMap.tsx'; -// import { ReactNode, useEffect, useState, useRef, forwardRef, useImperativeHandle } from 'react'; -// import classNames from 'classnames'; -// -// type IMapObject = naver.maps.Map | null; -// -// export interface IMapOptions { -// lat: number; -// lng: number; -// zoom?: number; -// } -// -// interface IMapProps extends IMapOptions { -// className?: string; -// type: string; -// initMap: (mapObject: IMapObject) => void; -// } -// -// // 부모 컴포넌트가 접근할 수 있는 메서드들을 정의한 인터페이스 -// export interface IMapRefMethods { -// getMapObject: () => naver.maps.Map | null; -// getMapContainer: () => HTMLElement | null; -// onMouseClickHandler: (event?: React.MouseEvent) => void; -// } -// -// const validateKindOfMap = (type: string) => ['naver'].includes(type); -// -// export const Map = forwardRef((props, ref) => { -// if (!validateKindOfMap(props.type)) throw new Error('Invalid map type'); -// -// const mapRef = useRef(null); -// const mapContainer = useRef(null); -// const [mapObject, setMapObject] = useState(null); -// const [MapComponent, setMapComponent] = useState(); -// -// const onMapInit = (mapObj: IMapObject) => { -// setMapObject(mapObj); -// }; -// -// useEffect(() => { -// if (props.type === 'naver') { -// const mapComponent = ( -// -// ); -// setMapComponent(mapComponent); -// } -// }, [props.lat, props.lng, props.zoom, props.type]); -// -// useEffect(() => { -// mapContainer.current = mapRef.current?.getMapContainer() ?? null; -// props.initMap(mapObject); -// }, [mapObject]); -// -// useImperativeHandle(ref, () => ({ -// getMapObject: () => mapObject, -// getMapContainer: () => mapContainer.current, -// onMouseClickHandler: () => {}, -// })); -// -// return ( -//
-// {MapComponent} -//
-// ); -// }); \ No newline at end of file diff --git a/frontend/src/component/maps/Map.types.ts b/frontend/src/component/maps/Map.types.ts deleted file mode 100644 index 83089b24..00000000 --- a/frontend/src/component/maps/Map.types.ts +++ /dev/null @@ -1,42 +0,0 @@ -export type IMapObject = naver.maps.Map; - -export type IMapLatLngBound = naver.maps.LatLngBounds; - -export interface IMapOptions { - lat: number; - lng: number; - zoom?: number; -} - -/** - * Forward Ref 를 통해서, 부모에서 자식 컴포넌트의 Ref에 접근할 때 쓰이는 인터페이스. - * 다음과 같은 목적으로 쓰인다. - * 1. 지도 컨테이너 요소와, 지도 객체를 가져온다. - * 2. 지도 객체의 이벤트 위임을 위해 자신을 컨트롤 할 수 있는 Handler를 부모에게 전달하는 역할을 한다. - * 이렇게 전달받은 핸들러로 부모 컴포넌트에서 자식에 있는 지도 객체를 컨트롤 할 수 있다. - * */ -export interface IMapRefMethods { - getMapObject: () => naver.maps.Map | null; - getMapContainer: () => HTMLElement | null; - onMouseClickHandler: (event?: React.MouseEvent) => void; -} - -// lat: 위도(y), lng: 경도(x) INaverMapVertexPosition -export interface IMapVertexCoordinate { - ne: { - lng: number; - lat: number; - }; - nw: { - lng: number; - lat: number; - }; - se: { - lng: number; - lat: number; - }; - sw: { - lng: number; - lat: number; - }; -} diff --git a/frontend/src/component/maps/NaverMap.tsx b/frontend/src/component/maps/NaverMap.tsx deleted file mode 100644 index 2718bdfa..00000000 --- a/frontend/src/component/maps/NaverMap.tsx +++ /dev/null @@ -1,40 +0,0 @@ -// import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react'; -// import { setNaverMapSync } from '@/component/maps/naverMapUtils.ts'; -// import { IMapOptions, IMapRefMethods } from '@/component/maps/Map.tsx'; -// -// interface INaverMapProps extends IMapOptions { -// onMapInit: (map: naver.maps.Map) => void; // 콜백 프로퍼티 추가 -// } -// -// export const NaverMap = forwardRef((props, ref) => { -// const naverMapObject = useRef(null); -// const naverMapContainer = useRef(null); -// const [mapOptions, setMapOptions] = useState({ -// lat: props.lat, -// lng: props.lng, -// zoom: props.zoom, -// }); -// -// useEffect(() => { -// setMapOptions({ -// lat: props.lat, -// lng: props.lng, -// zoom: props.zoom, -// }); -// }, [props.lat, props.lng, props.zoom]); -// -// useEffect(() => { -// if (naverMapContainer.current && mapOptions !== null) { -// naverMapObject.current = setNaverMapSync(naverMapContainer.current, mapOptions); -// if (naverMapObject.current !== null) props.onMapInit(naverMapObject.current); // 콜백 호출 -// } -// }, [mapOptions]); -// -// useImperativeHandle(ref, () => ({ -// getMapObject: () => naverMapObject.current, -// getMapContainer: () => naverMapContainer.current, -// onMouseClickHandler: () => {}, -// })); -// -// return
; -// }); diff --git a/frontend/src/component/maps/NaverMapSample.tsx b/frontend/src/component/maps/NaverMapSample.tsx deleted file mode 100644 index eff3a603..00000000 --- a/frontend/src/component/maps/NaverMapSample.tsx +++ /dev/null @@ -1,141 +0,0 @@ -// /* eslint-disable */ -// import React, { useEffect, useRef, useState } from 'react'; -// import { Canvas } from '@/component/canvas/Canvas'; -// -// interface MapPoint { -// lat: number; -// lng: number; -// } -// -// interface MapProps { -// initialCenter?: { lat: number; lng: number }; -// initialZoom?: number; -// } -// -// // 대한민국 영역 제한 -// const KOREA_BOUNDS = { -// sw: { lat: 33.0, lng: 125.0 }, // 서남단 -// ne: { lat: 38.0, lng: 132.0 }, // 동북단 -// }; -// -// const MIN_ZOOM = 7; // 대한민국 전체가 보이는 최소 줌 레벨 -// const MAX_ZOOM = 19; // 네이버 지도 최대 줌 레벨 -// -// export const MapWithCanvas: React.FC = ({ -// initialCenter = { lat: 36.5, lng: 127.5 }, // 대한민국 중심점 -// initialZoom = 7, -// }) => { -// const mapRef = useRef(null); -// const canvasRef = useRef(null); -// const [map, setMap] = useState(null); -// -// // 지도 초기화 -// useEffect(() => { -// const initializeMap = () => { -// if (!window.naver) return; -// -// const mapOptions = { -// center: new window.naver.maps.LatLng(initialCenter.lat, initialCenter.lng), -// zoom: initialZoom, -// minZoom: MIN_ZOOM, -// maxZoom: MAX_ZOOM, -// mapTypeControl: false, -// scaleControl: false, -// logoControl: false, -// mapDataControl: false, -// zoomControl: true, -// zoomControlOptions: { -// position: naver.maps.Position.RIGHT_CENTER, -// }, -// }; -// -// const mapInstance = new window.naver.maps.Map('map', mapOptions); -// -// // 영역 제한 설정 -// const bounds = new window.naver.maps.LatLngBounds( -// new window.naver.maps.LatLng(KOREA_BOUNDS.sw.lat, KOREA_BOUNDS.sw.lng), -// new window.naver.maps.LatLng(KOREA_BOUNDS.ne.lat, KOREA_BOUNDS.ne.lng), -// ); -// -// mapInstance.setOptions('maxBounds', bounds); -// mapRef.current = mapInstance; -// setMap(mapInstance); -// -// // 지도 이벤트 리스너 -// naver.maps.Event.addListener(mapInstance, 'zoom_changed', () => { -// updateCanvasPosition(); -// }); -// -// naver.maps.Event.addListener(mapInstance, 'center_changed', () => { -// updateCanvasPosition(); -// }); -// }; -// -// initializeMap(); -// -// return () => { -// if (mapRef.current) { -// mapRef.current.destroy(); -// } -// }; -// }, []); -// -// // 캔버스 위치 업데이트 -// const updateCanvasPosition = () => { -// if (!mapRef.current || !canvasRef.current) return; -// -// const mapBounds = mapRef.current.getBounds(); -// const projection = mapRef.current.getProjection(); -// const zoom = mapRef.current.getZoom(); -// -// // 캔버스의 위치와 크기를 지도에 맞춤 -// const canvasElement = canvasRef.current.getCanvasElement(); -// if (!canvasElement) return; -// -// // 캔버스 스케일 조정 -// const scale = Math.pow(2, zoom - MIN_ZOOM); -// canvasRef.current.setScale(scale); -// -// // 캔버스 위치 조정 -// const position = projection.fromCoordToOffset(mapRef.current.getCenter()); -// canvasRef.current.setPosition(position.x, position.y); -// }; -// -// // 지도상의 위경도를 캔버스 좌표로 변환 -// const convertLatLngToPoint = (latLng: MapPoint) => { -// if (!mapRef.current) return null; -// -// const projection = mapRef.current.getProjection(); -// const position = projection.fromCoordToOffset(new naver.maps.LatLng(latLng.lat, latLng.lng)); -// -// return { -// x: position.x, -// y: position.y, -// }; -// }; -// -// // 캔버스 좌표를 위경도로 변환 -// const convertPointToLatLng = (point: { x: number; y: number }) => { -// if (!mapRef.current) return null; -// -// const projection = mapRef.current.getProjection(); -// const latLng = projection.fromOffsetToCoord(new naver.maps.Point(point.x, point.y)); -// -// return { -// lat: latLng.y, -// lng: latLng.x, -// }; -// }; -// -// return ( -//
-//
-// -//
-// ); -// }; diff --git a/frontend/src/component/maps/mapUtils.ts b/frontend/src/component/maps/mapUtils.ts deleted file mode 100644 index 821341ac..00000000 --- a/frontend/src/component/maps/mapUtils.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { IMapVertexCoordinate, IMapObject, IMapLatLngBound } from '@/component/maps/Map.types.ts'; - -export const getMapVertexCoordinate = (map: IMapObject): IMapVertexCoordinate => { - let bounds: IMapLatLngBound; - - if (map instanceof naver.maps.Map) { - bounds = map.getBounds() as naver.maps.LatLngBounds; - } else { - throw new Error('🚀 꼭지점 좌표 가져오기 오류 : 지도 객체가 없습니다.'); - } - - const sw = bounds.getSW(); - const ne = bounds.getNE(); - return { - se: { - lng: ne.lng(), - lat: sw.lat(), - }, - sw: { - lng: sw.lng(), - lat: sw.lat(), - }, - ne: { - lng: ne.lng(), - lat: ne.lat(), - }, - nw: { - lng: sw.lng(), - lat: ne.lat(), - }, - }; -}; diff --git a/frontend/src/component/maps/naverMapUtils.ts b/frontend/src/component/maps/naverMapUtils.ts deleted file mode 100644 index 22664b78..00000000 --- a/frontend/src/component/maps/naverMapUtils.ts +++ /dev/null @@ -1,38 +0,0 @@ -// import { IMapOptions } from '@/component/maps/Map.types.ts'; -// -// export const setNaverMapOption = (mapOptions: IMapOptions): IMapOptions => { -// return { -// ...mapOptions, -// lat: mapOptions.lat ? mapOptions.lat : 37.42829747263545, -// lng: mapOptions.lng ? mapOptions.lng : 126.76620435615891, -// zoom: mapOptions.zoom ? mapOptions.zoom : 20, -// }; -// }; -// -// export const setNaverMap = ( -// htmlElement: HTMLElement, -// mapOptions: IMapOptions, -// ): Promise => { -// const { lat, lng, ...restProps } = setNaverMapOption(mapOptions); -// -// return new Promise(resolve => { -// const map = new naver.maps.Map(htmlElement, { -// center: new naver.maps.LatLng(lat, lng), -// ...restProps, -// }); -// -// resolve(map); -// }); -// }; -// -// export const setNaverMapSync = ( -// htmlElement: HTMLElement, -// mapOptions: IMapOptions, -// ): naver.maps.Map => { -// const { lat, lng, ...restProps } = setNaverMapOption(mapOptions); -// -// return new naver.maps.Map(htmlElement, { -// center: new naver.maps.LatLng(lat, lng), -// ...restProps, -// }); -// }; diff --git a/frontend/src/hooks/useDrawing.ts b/frontend/src/hooks/useDrawing.ts index b62474e1..903c6c25 100644 --- a/frontend/src/hooks/useDrawing.ts +++ b/frontend/src/hooks/useDrawing.ts @@ -1,111 +1,111 @@ -import { useRef, useEffect } from 'react'; -import startmarker from '@/assets/startmarker.png'; -import endmarker from '@/assets/endmarker.png'; - -interface IPoint { - x: number; - y: number; -} - -interface IUseDrawingProps { - canvasRef: React.RefObject; - points: IPoint[]; - startPoint: IPoint | null; - endPoint: IPoint | null; - lineWidth: number; - strokeStyle: string; - initialScale: number; -} - -const INITIAL_POSITION = { x: 0, y: 0 }; - -export const useDrawing = (props: IUseDrawingProps) => { - const scaleRef = useRef(props.initialScale); - const viewPosRef = useRef(INITIAL_POSITION); - - const startImageRef = useRef(null); - const endImageRef = useRef(null); - - useEffect(() => { - startImageRef.current = new Image(); - startImageRef.current.src = startmarker; - - endImageRef.current = new Image(); - endImageRef.current.src = endmarker; - }, []); - - const getCanvasContext = (): CanvasRenderingContext2D | null => - props.canvasRef.current?.getContext('2d') || null; - - const setTransform = (context: CanvasRenderingContext2D) => { - context.setTransform( - scaleRef.current, - 0, - 0, - scaleRef.current, - viewPosRef.current.x, - viewPosRef.current.y, - ); - }; - - const draw = () => { - const context = getCanvasContext(); - if (!context) return; - - const canvas = props.canvasRef.current; - if (!canvas) return; - - context.clearRect(0, 0, canvas.width, canvas.height); - setTransform(context); - - if (props.points.length > 1) { - context.lineWidth = props.lineWidth / scaleRef.current; - context.strokeStyle = props.strokeStyle; - context.beginPath(); - context.moveTo(props.points[0].x, props.points[0].y); - props.points.slice(1).forEach(point => context.lineTo(point.x, point.y)); - context.stroke(); - } else if (props.points.length === 1) { - context.fillStyle = props.strokeStyle; - context.beginPath(); - context.arc( - props.points[0].x, - props.points[0].y, - (props.lineWidth + 1) / scaleRef.current, - 0, - 2 * Math.PI, - ); - context.fill(); - } - - if (props.startPoint && startImageRef.current) { - const { x, y } = props.startPoint; - const markerSize = 32 / scaleRef.current; - context.drawImage( - startImageRef.current, - x - markerSize / 2, - y - markerSize, - markerSize, - markerSize, - ); - } - - if (props.endPoint && endImageRef.current) { - const { x, y } = props.endPoint; - const markerSize = 32 / scaleRef.current; - context.drawImage( - endImageRef.current, - x - markerSize / 2, - y - markerSize, - markerSize, - markerSize, - ); - } - }; - - useEffect(() => { - draw(); - }, [props.points, props.startPoint, props.endPoint]); - - return { draw, scaleRef, viewPosRef }; -}; +// import { useRef, useEffect } from 'react'; +// import startmarker from '@/assets/startmarker.png'; +// import endmarker from '@/assets/endmarker.png'; +// +// interface IPoint { +// x: number; +// y: number; +// } +// +// interface IUseDrawingProps { +// canvasRef: React.RefObject; +// points: IPoint[]; +// startPoint: IPoint | null; +// endPoint: IPoint | null; +// lineWidth: number; +// strokeStyle: string; +// initialScale: number; +// } +// +// const INITIAL_POSITION = { x: 0, y: 0 }; +// +// export const useDrawing = (props: IUseDrawingProps) => { +// const scaleRef = useRef(props.initialScale); +// const viewPosRef = useRef(INITIAL_POSITION); +// +// const startImageRef = useRef(null); +// const endImageRef = useRef(null); +// +// useEffect(() => { +// startImageRef.current = new Image(); +// startImageRef.current.src = startmarker; +// +// endImageRef.current = new Image(); +// endImageRef.current.src = endmarker; +// }, []); +// +// const getCanvasContext = (): CanvasRenderingContext2D | null => +// props.canvasRef.current?.getContext('2d') || null; +// +// const setTransform = (context: CanvasRenderingContext2D) => { +// context.setTransform( +// scaleRef.current, +// 0, +// 0, +// scaleRef.current, +// viewPosRef.current.x, +// viewPosRef.current.y, +// ); +// }; +// +// const draw = () => { +// const context = getCanvasContext(); +// if (!context) return; +// +// const canvas = props.canvasRef.current; +// if (!canvas) return; +// +// context.clearRect(0, 0, canvas.width, canvas.height); +// setTransform(context); +// +// if (props.points.length > 1) { +// context.lineWidth = props.lineWidth / scaleRef.current; +// context.strokeStyle = props.strokeStyle; +// context.beginPath(); +// context.moveTo(props.points[0].x, props.points[0].y); +// props.points.slice(1).forEach(point => context.lineTo(point.x, point.y)); +// context.stroke(); +// } else if (props.points.length === 1) { +// context.fillStyle = props.strokeStyle; +// context.beginPath(); +// context.arc( +// props.points[0].x, +// props.points[0].y, +// (props.lineWidth + 1) / scaleRef.current, +// 0, +// 2 * Math.PI, +// ); +// context.fill(); +// } +// +// if (props.startPoint && startImageRef.current) { +// const { x, y } = props.startPoint; +// const markerSize = 32 / scaleRef.current; +// context.drawImage( +// startImageRef.current, +// x - markerSize / 2, +// y - markerSize, +// markerSize, +// markerSize, +// ); +// } +// +// if (props.endPoint && endImageRef.current) { +// const { x, y } = props.endPoint; +// const markerSize = 32 / scaleRef.current; +// context.drawImage( +// endImageRef.current, +// x - markerSize / 2, +// y - markerSize, +// markerSize, +// markerSize, +// ); +// } +// }; +// +// useEffect(() => { +// draw(); +// }, [props.points, props.startPoint, props.endPoint]); +// +// return { draw, scaleRef, viewPosRef }; +// }; diff --git a/frontend/src/hooks/usePanning.ts b/frontend/src/hooks/usePanning.ts index f058b7d8..bb3e47e0 100644 --- a/frontend/src/hooks/usePanning.ts +++ b/frontend/src/hooks/usePanning.ts @@ -1,42 +1,42 @@ -import { useRef } from 'react'; - -interface IUsePanningProps { - viewPosRef: React.MutableRefObject<{ x: number; y: number }>; - draw: () => void; -} - -const INITIAL_POSITION = { x: 0, y: 0 }; - -export const usePanning = (props: IUsePanningProps) => { - const panningRef = useRef(false); - const startPosRef = useRef(INITIAL_POSITION); - - const handleMouseMove = (e: React.MouseEvent) => { - if (!panningRef.current || !props.viewPosRef.current) return; - - const viewPos = props.viewPosRef.current; - const { x, y } = startPosRef.current; - - viewPos.x = e.clientX - x; - viewPos.y = e.clientY - y; - - props.draw(); - }; - - const handleMouseDown = (e: React.MouseEvent) => { - if (!props.viewPosRef.current) return; - - const viewPos = props.viewPosRef.current; - startPosRef.current = { - x: e.clientX - viewPos.x, - y: e.clientY - viewPos.y, - }; - panningRef.current = true; - }; - - const handleMouseUp = () => { - panningRef.current = false; - }; - - return { handleMouseMove, handleMouseDown, handleMouseUp }; -}; +// import { useRef } from 'react'; +// +// interface IUsePanningProps { +// viewPosRef: React.MutableRefObject<{ x: number; y: number }>; +// draw: () => void; +// } +// +// const INITIAL_POSITION = { x: 0, y: 0 }; +// +// export const usePanning = (props: IUsePanningProps) => { +// const panningRef = useRef(false); +// const startPosRef = useRef(INITIAL_POSITION); +// +// const handleMouseMove = (e: React.MouseEvent) => { +// if (!panningRef.current || !props.viewPosRef.current) return; +// +// const viewPos = props.viewPosRef.current; +// const { x, y } = startPosRef.current; +// +// viewPos.x = e.clientX - x; +// viewPos.y = e.clientY - y; +// +// props.draw(); +// }; +// +// const handleMouseDown = (e: React.MouseEvent) => { +// if (!props.viewPosRef.current) return; +// +// const viewPos = props.viewPosRef.current; +// startPosRef.current = { +// x: e.clientX - viewPos.x, +// y: e.clientY - viewPos.y, +// }; +// panningRef.current = true; +// }; +// +// const handleMouseUp = () => { +// panningRef.current = false; +// }; +// +// return { handleMouseMove, handleMouseDown, handleMouseUp }; +// }; diff --git a/frontend/src/hooks/useZoom.ts b/frontend/src/hooks/useZoom.ts index ef82bf48..14e1a482 100644 --- a/frontend/src/hooks/useZoom.ts +++ b/frontend/src/hooks/useZoom.ts @@ -1,46 +1,46 @@ -import { useRef } from 'react'; - -interface IUseZoomProps { - scaleRef: React.MutableRefObject; - viewPosRef: React.MutableRefObject<{ x: number; y: number }>; - draw: () => void; - stepScales: number[]; - initialZoomIndex: number; -} - -export const useZoom = (props: IUseZoomProps) => { - const zoomIndexRef = useRef(props.initialZoomIndex); - const MIN_SCALE_INDEX = 0; - const MAX_SCALE_INDEX = props.stepScales.length - 1; - - const handleWheel = (e: React.WheelEvent) => { - const viewPos = props.viewPosRef; - const scale = props.scaleRef; - - if (!viewPos || scale.current === null) return; - - e.preventDefault(); - const { offsetX, offsetY } = e.nativeEvent; - - if (e.deltaY < 0 && zoomIndexRef.current > MIN_SCALE_INDEX) { - zoomIndexRef.current -= 1; - } else if (e.deltaY > 0 && zoomIndexRef.current < MAX_SCALE_INDEX) { - zoomIndexRef.current += 1; - } - - const newScale = - props.stepScales[props.initialZoomIndex] / props.stepScales[zoomIndexRef.current]; - const xs = (offsetX - viewPos.current.x) / scale.current; - const ys = (offsetY - viewPos.current.y) / scale.current; - - scale.current = newScale; - viewPos.current = { - x: offsetX - xs * scale.current, - y: offsetY - ys * scale.current, - }; - - props.draw(); - }; - - return { handleWheel, zoomIndexRef }; -}; +// import { useRef } from 'react'; +// +// interface IUseZoomProps { +// scaleRef: React.MutableRefObject; +// viewPosRef: React.MutableRefObject<{ x: number; y: number }>; +// draw: () => void; +// stepScales: number[]; +// initialZoomIndex: number; +// } +// +// export const useZoom = (props: IUseZoomProps) => { +// const zoomIndexRef = useRef(props.initialZoomIndex); +// const MIN_SCALE_INDEX = 0; +// const MAX_SCALE_INDEX = props.stepScales.length - 1; +// +// const handleWheel = (e: React.WheelEvent) => { +// const viewPos = props.viewPosRef; +// const scale = props.scaleRef; +// +// if (!viewPos || scale.current === null) return; +// +// e.preventDefault(); +// const { offsetX, offsetY } = e.nativeEvent; +// +// if (e.deltaY < 0 && zoomIndexRef.current > MIN_SCALE_INDEX) { +// zoomIndexRef.current -= 1; +// } else if (e.deltaY > 0 && zoomIndexRef.current < MAX_SCALE_INDEX) { +// zoomIndexRef.current += 1; +// } +// +// const newScale = +// props.stepScales[props.initialZoomIndex] / props.stepScales[zoomIndexRef.current]; +// const xs = (offsetX - viewPos.current.x) / scale.current; +// const ys = (offsetY - viewPos.current.y) / scale.current; +// +// scale.current = newScale; +// viewPos.current = { +// x: offsetX - xs * scale.current, +// y: offsetY - ys * scale.current, +// }; +// +// props.draw(); +// }; +// +// return { handleWheel, zoomIndexRef }; +// }; diff --git a/frontend/src/pages/DrawRoute.tsx b/frontend/src/pages/DrawRoute.tsx index 25a26183..629fe2a5 100644 --- a/frontend/src/pages/DrawRoute.tsx +++ b/frontend/src/pages/DrawRoute.tsx @@ -2,7 +2,7 @@ import { useContext, useEffect } from 'react'; import { FooterContext } from '@/component/layout/footer/LayoutFooterProvider'; import { useParams } from 'react-router-dom'; import { UserContext } from '@/context/UserContext'; -import { FullScreenMap } from '@/component/maps/Canvas.tsx'; +import { MapProviderForDraw } from '@/component/canvasWithMap/MapProviderForDraw.tsx'; export const DrawRoute = () => { const { users, setUsers } = useContext(UserContext); @@ -66,7 +66,7 @@ export const DrawRoute = () => {
{/* TODO: 동율님 mock 데이터 관련 버튼 없애고 나서, height={window.innerHeight - 180} 으로 변경해주시면 됩니다! */} - +
); diff --git a/frontend/src/pages/Main.tsx b/frontend/src/pages/Main.tsx index 7e5f7639..ae446d95 100644 --- a/frontend/src/pages/Main.tsx +++ b/frontend/src/pages/Main.tsx @@ -3,7 +3,7 @@ import { MdFormatListBulleted } from 'react-icons/md'; import { FooterContext } from '@/component/layout/footer/LayoutFooterProvider'; import { useNavigate } from 'react-router-dom'; import { buttonActiveType } from '@/component/layout/enumTypes'; -import { FullScreenMap } from '@/component/maps/Canvas.tsx'; +import { MapProviderForDraw } from '@/component/canvasWithMap/MapProviderForDraw.tsx'; import { BottomSheet } from '@/component/bottomsheet/BottomSheet.tsx'; import { Content } from '@/component/content/Content.tsx'; import { loadLocalData, saveLocalData } from '@/utils/common/manageLocalData.ts'; @@ -100,7 +100,7 @@ export const Main = () => { {/* eslint-disable-next-line no-nested-ternary */} {lat && lng ? ( otherLocations ? ( - + ) : (
Loading map data...