diff --git a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx index 73e48ff2..1b99f039 100644 --- a/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx +++ b/src/components/floor-plan/modal/outerlinesetting/OuterLineWall.jsx @@ -20,13 +20,15 @@ import { QLine } from '@/components/fabric/QLine' import { useLine } from '@/hooks/useLine' import { distanceBetweenPoints } from '@/util/canvas-util' import { calculateAngle } from '@/util/qpolygon-utils' +import { usePolygon } from '@/hooks/usePolygon' export default function OuterLineWall(props) { const { setShowOutlineModal } = props const { getMessage } = useMessage() const { addCanvasMouseEventListener, addDocumentEventListener, removeAllMouseEventListeners, removeAllDocumentEventListeners, removeMouseEvent } = useEvent() - const { addLineText, removeLineText } = useLine() + const { addLine, removeLine } = useLine() + const { addPolygonByLines } = usePolygon() const verticalHorizontalMode = useRecoilValue(verticalHorizontalModeState) const length1Ref = useRef(null) @@ -41,6 +43,8 @@ export default function OuterLineWall(props) { const arrow1Ref = useRef(arrow1) const arrow2Ref = useRef(arrow2) + const isFix = useRef(false) + const [angle1, setAngle1] = useRecoilState(outerLineAngle1State) const canvas = useRecoilValue(canvasState) @@ -123,17 +127,11 @@ export default function OuterLineWall(props) { useEffect(() => { canvas ?.getObjects() - .filter((obj) => obj.name === 'outerLine') + .filter((obj) => obj.name === 'outerLine' || obj.name === 'helpGuideLine') .forEach((obj) => { - canvas?.remove(obj) - removeLineText(obj) + removeLine(obj) }) - canvas - ?.getObjects() - .filter((obj) => obj.name === 'helpGuideLine' || (obj.name === 'lengthTxt' && obj.parent?.name === 'helpGuideLine')) - .forEach((obj) => canvas?.remove(obj)) - canvas?.remove(canvas?.getObjects().find((obj) => obj.name === 'startPoint')) // point가 변경 될때마다 이벤트 리스너를 제거하고 다시 등록 @@ -230,16 +228,27 @@ export default function OuterLineWall(props) { }, [points]) const drawLine = (point1, point2, idx) => { - const line = new QLine([point1.x, point1.y, point2.x, point2.y], { + addLine([point1.x, point1.y, point2.x, point2.y], { stroke: 'black', strokeWidth: 3, idx: idx, selectable: false, name: 'outerLine', }) + } - canvas?.add(line) - addLineText(line) + const settingLine = () => { + const outerLines = canvas?.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.forEach((line) => { + removeLine(line) + }) + + addPolygonByLines(outerLines, { + fill: 'rgba(0,0,0,0)', + stroke: 'black', + strokeWidth: 3, + }) + setShowOutlineModal(false) } // 직각 완료될 경우 확인 @@ -512,11 +521,10 @@ export default function OuterLineWall(props) { } setPoints((prev) => { - if (prev.length === 0) { - return [] - } return [...prev, { x: prev[0].x, y: prev[0].y }] }) + + isFix.current = true } return ( diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 044a5e58..c0e74faf 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -12,6 +12,7 @@ import { defineQPloygon } from '@/util/qpolygon-utils' import { writeImage } from '@/lib/canvas' import { useCanvasEvent } from '@/hooks/useCanvasEvent' import { post } from '@/lib/Axios' +import { v4 as uuidv4 } from 'uuid' export function useCanvas(id) { const [canvas, setCanvas] = useRecoilState(canvasState) @@ -88,6 +89,7 @@ export function useCanvas(id) { canvas.getObjects().length > 0 && canvas?.clear() // settings for all canvas in the app fabric.Object.prototype.transparentCorners = false + fabric.Object.prototype.id = uuidv4() fabric.Object.prototype.cornerColor = '#2BEBC8' fabric.Object.prototype.cornerStyle = 'rect' fabric.Object.prototype.cornerStrokeColor = '#2BEBC8' diff --git a/src/hooks/useCanvasEvent.js b/src/hooks/useCanvasEvent.js index 9a30ccde..55a34cb2 100644 --- a/src/hooks/useCanvasEvent.js +++ b/src/hooks/useCanvasEvent.js @@ -84,7 +84,7 @@ export function useCanvasEvent() { target.setControlVisible(controlKey, false) }) }) - target.on('editing:exited', () => { + /*target.on('editing:exited', () => { if (isNaN(target.text.trim())) { target.set({ text: previousValue }) canvas?.renderAll() @@ -124,7 +124,7 @@ export function useCanvasEvent() { canvas?.add(newPolygon) canvas?.remove(targetParent) canvas?.renderAll() - }) + })*/ target.on('moving', (e) => { if (target.parentDirection === 'left' || target.parentDirection === 'right') { diff --git a/src/hooks/useLine.js b/src/hooks/useLine.js index 3fbb9051..e701a2ff 100644 --- a/src/hooks/useLine.js +++ b/src/hooks/useLine.js @@ -13,6 +13,7 @@ export const useLine = () => { }) canvas?.add(line) + addLineText(line) return line } @@ -34,6 +35,11 @@ export const useLine = () => { return text } + const removeLine = (line) => { + removeLineText(line) + canvas?.remove(line) + } + const removeLineText = (line) => { canvas?.remove(canvas?.getObjects().find((obj) => obj.parent === line)) } @@ -52,7 +58,7 @@ export const useLine = () => { } return { - addLineText, - removeLineText, + addLine, + removeLine, } } diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 60db96b9..b364bf86 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1,5 +1,7 @@ import { canvasState, fontFamilyState, fontSizeState } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' +import { fabric } from 'fabric' +import { getDirectionByPoint } from '@/util/canvas-util' export const usePolygon = () => { const canvas = useRecoilValue(canvasState) @@ -13,12 +15,84 @@ export const usePolygon = () => { }) canvas?.add(polygon) + addLengthText(polygon) } - const addPolygonByLines = (lines) => {} + const addPolygonByLines = (lines, options) => { + const points = createPolygonPointsFromOuterLines(lines) + + addPolygon(points, { + ...options, + }) + } + + const addLengthText = (polygon) => { + const points = polygon.get('points') + points.forEach((start, i) => { + const end = points[(i + 1) % points.length] + const dx = end.x - start.x + const dy = end.y - start.y + const length = Number(Math.sqrt(dx * dx + dy * dy).toFixed(1)) * 10 + + const midPoint = new fabric.Point((start.x + end.x) / 2, (start.y + end.y) / 2) + + const degree = (Math.atan2(dy, dx) * 180) / Math.PI + + // Create new text object if it doesn't exist + const text = new fabric.IText(length.toString(), { + left: midPoint.x, + top: midPoint.y, + fontSize: fontSize, + parentId: polygon.id, + minX: Math.min(start.x, end.x), + maxX: Math.max(start.x, end.x), + minY: Math.min(start.y, end.y), + maxY: Math.max(start.y, end.y), + parentDirection: getDirectionByPoint(start, end), + parentDegree: degree, + dirty: true, + editable: true, + selectable: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + idx: i, + name: 'lengthText', + parent: this, + }) + + // this.texts.push(text) + canvas.add(text) + }) + canvas.renderAll() + } + + const createPolygonPointsFromOuterLines = (outerLines) => { + if (!outerLines || outerLines.length === 0) { + return [] + } + + // Extract points from outerLines + + return outerLines.map((line) => ({ + x: line.x1, + y: line.y1, + })) + } + + const removePolygon = (polygon) => { + const texts = canvas.getObjects().filter((obj) => obj.parentId === polygon.id) + texts.forEach((text) => { + canvas.remove(text) + }) + + canvas.remove(polygon) + canvas.renderAll() + } return { addPolygon, addPolygonByLines, + removePolygon, } }