diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 3b36974f..249984c7 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -25,6 +25,7 @@ export function useMode() { const points = useRef([]) const historyPoints = useRef([]) const historyLines = useRef([]) + const startPoint = useRef() const [canvas, setCanvas] = useState(null) const [zoom, setZoom] = useState(100) const [fontSize] = useRecoilState(fontSizeState) @@ -35,6 +36,8 @@ export function useMode() { const [endPoint, setEndPoint] = useState(null) + const pointCount = useRef(0) + const [roofPolygonPattern, setRoofPolygonPattern] = useRecoilState(roofPolygonPatternArrayState) const [canvasSize] = useRecoilState(canvasSizeState) @@ -102,6 +105,62 @@ export function useMode() { canvas?.renderAll() } + useEffect(() => { + if (pointCount.current <= 2) { + removeGuideLines() + return + } + drawGuideLines() + }, [pointCount.current]) + + const removeGuideLines = () => { + const guideLines = canvas?._objects.filter((obj) => obj.name === 'guideLine') + guideLines?.forEach((item) => canvas?.remove(item)) + } + + const drawGuideLines = () => { + // 이름이 guideLine인 가이드라인을 제거합니다. + removeGuideLines() + + const arrivalX = startPoint.current?.left + const arrivalY = startPoint.current?.top + + const lastX = endPoint?.left + const lastY = endPoint?.top + + if (lastX === arrivalX || lastY === arrivalY) { + // 둘중 하나라도 같으면 guideLine은 한개만 생성 + const guideLine = new QLine([lastX, lastY, arrivalX, arrivalY], { + fontSize: fontSize, + stroke: 'black', + strokeWidth: 1, + strokeDashArray: [1, 1, 1], + }) + guideLine.name = 'guideLine' + canvas?.add(guideLine) + } else { + const guideLine1 = new QLine([lastX, lastY, lastX, arrivalY], { + fontSize: fontSize, + stroke: 'black', + strokeWidth: 1, + strokeDashArray: [1, 1, 1], + }) + + const guideLine2 = new QLine([guideLine1.x2, guideLine1.y2, arrivalX, arrivalY], { + fontSize: fontSize, + stroke: 'black', + strokeWidth: 1, + strokeDashArray: [1, 1, 1], + }) + + guideLine1.name = 'guideLine' + guideLine2.name = 'guideLine' + + canvas?.add(guideLine1) + canvas?.add(guideLine2) + } + } + /** * 마우스 포인터의 가이드라인을 제거합니다. */ @@ -125,12 +184,10 @@ export function useMode() { const pointer = canvas?.getPointer(e.e) // 마우스 포인터 위치랑 endPoint를 연결하는 line 생성 - const line = new QLine([endPoint.left, endPoint.top, pointer.x, pointer.y], { + const line = new fabric.Line([endPoint.left, endPoint.top, pointer.x, pointer.y], { stroke: 'black', - strokeWidth: 2, + strokeWidth: 1, selectable: false, - viewLengthText: true, - fontSize: fontSize, }) line.set({ name: 'connectLine' }) @@ -235,8 +292,6 @@ export function useMode() { selectable: false, }) - setEndPoint(endPointCircle) - canvas?.add(endPointCircle) historyPoints.current.push(endPointCircle) @@ -244,6 +299,10 @@ export function useMode() { points.current.forEach((point) => { canvas?.remove(point) }) + + setEndPoint(endPointCircle) + pointCount.current = pointCount.current + 1 + points.current = [endPointCircle] canvas.renderAll() @@ -317,6 +376,8 @@ export function useMode() { const changeMode = (canvas, mode) => { setEndPoint(null) + pointCount.current = 0 + setMode(mode) // mode변경 시 이전 이벤트 제거 setCanvas(canvas) @@ -338,6 +399,10 @@ export function useMode() { originY: 'center', selectable: false, }) + if (!startPoint.current) { + startPoint.current = circle + pointCount.current = pointCount.current + 1 + } setEndPoint(circle) @@ -347,6 +412,7 @@ export function useMode() { if (points.current.length === 2) { const length = Number(prompt('길이를 입력하세요:')) + // length 값이 숫자가 아닌 경우 if (isNaN(length) || length === 0) { //마지막 추가 된 points 제거합니다. @@ -382,40 +448,10 @@ export function useMode() { } } - const line = new QLine( - [points.current[0].left, points.current[0].top, points.current[0].left + scaledVector.x, points.current[0].top + scaledVector.y], - { - stroke: 'black', - strokeWidth: 2, - selectable: false, - viewLengthText: true, - direction: getDirection(points.current[0], points.current[1]), - fontSize: fontSize, - }, - ) + const verticalLength = scaledVector.y + const horizontalLength = scaledVector.x - pushHistoryLine(line) - - // 라인의 끝에 점을 추가합니다. - const endPointCircle = new fabric.Circle({ - radius: 1, - fill: 'transparent', // 원 안을 비웁니다. - stroke: 'black', // 원 테두리 색상을 검은색으로 설정합니다. - left: points.current[0].left + scaledVector.x, - top: points.current[0].top + scaledVector.y, - originX: 'center', - originY: 'center', - selectable: false, - }) - setEndPoint(endPointCircle) - canvas?.add(endPointCircle) - - historyPoints.current.push(endPointCircle) - - points.current.forEach((point) => { - canvas?.remove(point) - }) - points.current = [endPointCircle] + drawCircleAndLine(verticalLength, horizontalLength) } }