From 09a709ff163e6a70a790ac249364de3d33f61440 Mon Sep 17 00:00:00 2001 From: minsik Date: Mon, 25 Nov 2024 17:02:17 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B3=B4=EC=A1=B0=EC=84=A0=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/auxiliary/AuxiliaryDrawing.jsx | 4 ++ .../modal/auxiliary/AuxiliaryEdit.jsx | 8 ++- .../modal/auxiliary/AuxiliarySize.jsx | 8 ++- src/hooks/roofcover/useAuxiliaryDrawing.js | 65 ++++++++++--------- src/hooks/useContextMenu.js | 28 ++++++-- 5 files changed, 71 insertions(+), 42 deletions(-) diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx index 84e7ab91..609ff975 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryDrawing.jsx @@ -49,6 +49,7 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) { handleFix, buttonAct, setButtonAct, + cutAuxiliary, } = useAuxiliaryDrawing(id) const outerLineProps = { @@ -151,6 +152,9 @@ export default function AuxiliaryDrawing({ id, pos = { x: 50, y: 230 } }) { + diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx index da00ac06..07fc9e46 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliaryEdit.jsx @@ -5,8 +5,8 @@ import { useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' import { useState } from 'react' import { currentObjectState } from '@/store/canvasAtom' -import { useLine } from '@/hooks/useLine' import { useAuxiliaryDrawing } from '@/hooks/roofcover/useAuxiliaryDrawing' +import { useSwal } from '@/hooks/useSwal' export default function AuxiliaryEdit(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) @@ -18,9 +18,13 @@ export default function AuxiliaryEdit(props) { const [horizonSize, setHorizonSize] = useState('0') const [arrow1, setArrow1] = useState(null) const [arrow2, setArrow2] = useState(null) - const { addLine, removeLine } = useLine() const currentObject = useRecoilValue(currentObjectState) + const { swalFire } = useSwal() const handleSave = () => { + if (!horizonSize || !verticalSize || !arrow1 || !arrow2) { + swalFire({ title: '길이와 방향을 입력하세요.', type: 'alert' }) + return + } if (type === 'copy') { if (currentObject) { copy( diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx index 70245626..e984be57 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx @@ -3,12 +3,14 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import { usePopup } from '@/hooks/usePopup' import { useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' +import { useCanvas } from '@/hooks/useCanvas' export default function AuxiliarySize(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition } = props const { getMessage } = useMessage() const { closePopup } = usePopup() + const { currentObject } = useCanvas() return (
@@ -26,7 +28,7 @@ export default function AuxiliarySize(props) {
- +
mm
@@ -45,14 +47,14 @@ export default function AuxiliarySize(props) {
- +
mm
{getMessage('length')}
- +
mm
diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index 30e3982e..0d23fd44 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -92,7 +92,7 @@ export function useAuxiliaryDrawing(id) { addCanvasMouseEventListener('mouse:move', mouseMove) addCanvasMouseEventListener('mouse:down', mouseDown) - addDocumentEventListener('contextmenu', document, cutAuxiliary) + // addDocumentEventListener('contextmenu', document, cutAuxiliary) addDocumentEventListener('keydown', document, keydown[type]) return () => { @@ -135,23 +135,6 @@ export function useAuxiliaryDrawing(id) { }) } - const addBisectorLine = (target) => { - const slope = (target.y2 - target.y1) / (target.x2 - target.x1) - const bisectorSlope = -1 / slope - const length = target.length - const dx = length / Math.sqrt(1 + bisectorSlope * bisectorSlope) - const dy = bisectorSlope * dx - const endX = (target.x1 + target.x2) / 2 - const endY = (target.y1 + target.y2) / 2 - - addLine([dx, dy, endX, endY], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - name: 'auxiliaryLine', - }) - } - const keydown = { outerLine: (e) => { if (mousePointerArr.current.length === 0) { @@ -565,8 +548,24 @@ export function useAuxiliaryDrawing(id) { otherAdsorptionPoints.push(intersectionPoint) }) }) + let innerLinePoints = [] + canvas + .getObjects() + .filter((obj) => obj.innerLines) + .forEach((polygon) => { + polygon.innerLines.forEach((line) => { + innerLinePoints.push({ x: line.x1, y: line.y1 }) + innerLinePoints.push({ x: line.x2, y: line.y2 }) + }) + }) - const adsorptionPoints = [...getAdsorptionPoints(), ...roofAdsorptionPoints.current, ...otherAdsorptionPoints, ...intersectionPoints.current] + const adsorptionPoints = [ + ...getAdsorptionPoints(), + ...roofAdsorptionPoints.current, + ...otherAdsorptionPoints, + ...intersectionPoints.current, + ...innerLinePoints, + ] let arrivalPoint = { x: pointer.x, y: pointer.y } @@ -825,7 +824,6 @@ export function useAuxiliaryDrawing(id) { //lineHistory.current에 있는 선들 중 startPoint와 endPoint가 겹치는 line은 제거 // 겹치는 선 하나는 canvas에서 제거한다. - const tempLines = [...lineHistory.current] lineHistory.current = [] tempLines.forEach((line) => { @@ -849,27 +847,30 @@ export function useAuxiliaryDrawing(id) { const tempPolygonPoints = [...roofBase.points].map((obj) => { return { x: Math.round(obj.x), y: Math.round(obj.y) } }) - const roofInnerLines = innerLines.filter((line) => { + const roofInnerLines = [...roofBase.innerLines, ...innerLines].filter((line) => { const inPolygon1 = - tempPolygonPoints.some((point) => point.x === line.x1 && point.y === line.y1) || - roofBase.inPolygon({ x: line.x1, y: line.y1 }) || - roofBase.lines.some((line) => isPointOnLine(line, { x: line.x1, y: line.y1 })) + tempPolygonPoints.some((point) => Math.round(point.x) === Math.round(line.x1) && Math.round(point.y) === Math.round(line.y1)) || + roofBase.inPolygon({ x: Math.round(line.x1), y: Math.round(line.y1) }) || + roofBase.lines.some((line) => isPointOnLine(line, { x: Math.round(line.x1), y: Math.round(line.y1) })) const inPolygon2 = - tempPolygonPoints.some((point) => point.x === line.x2 && point.y === line.y2) || - roofBase.inPolygon({ x: line.x2, y: line.y2 }) || - roofBase.lines.some((line) => isPointOnLine(line, { x: line.x2, y: line.y2 })) + tempPolygonPoints.some((point) => Math.round(point.x) === Math.round(line.x2) && Math.round(point.y) === Math.round(line.y2)) || + roofBase.inPolygon({ x: Math.round(line.x2), y: Math.round(line.y2) }) || + roofBase.lines.some((line) => isPointOnLine(line, { x: Math.round(line.x2), y: Math.round(line.y2) })) if (inPolygon1 && inPolygon2) { - line.attributes = { ...line.attributes, roofId: roofBase.id, actualSize: 0, planeSize: line.getLength() } + line.attributes = { + ...line.attributes, + roofId: roofBase.id, + actualSize: line.attributes?.actualSize ?? 0, + planeSize: line.getLength(), + } return true } }) - roofBase.innerLines = [...roofInnerLines] - + roofBase.innerLines = lineHistory.current.length !== 0 ? [...roofInnerLines] : roofBase.innerLines canvas.renderAll() }) - closePopup(id) } @@ -903,6 +904,6 @@ export function useAuxiliaryDrawing(id) { setButtonAct, move, copy, - addBisectorLine, + cutAuxiliary, } } diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 1f5f59cb..331259e3 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -34,6 +34,7 @@ import { useObjectBatch } from '@/hooks/object/useObjectBatch' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { fontSelector, globalFontAtom } from '@/store/fontAtom' import { useLine } from '@/hooks/useLine' +import { useSwal } from '@/hooks/useSwal' export function useContextMenu() { const canvas = useRecoilValue(canvasState) @@ -56,6 +57,7 @@ export function useContextMenu() { const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) const { addLine, removeLine } = useLine() const commonTextFont = useRecoilValue(fontSelector('commonText')) + const { swalFire } = useSwal() const currentMenuSetting = () => { switch (currentMenu) { @@ -145,6 +147,9 @@ export function useContextMenu() { shortcut: ['d', 'D'], name: `${getMessage('contextmenu.auxiliary.remove')}(D)`, fn: () => { + const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] + const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) + roof.innerLines = [...innerLines] canvas.remove(currentObject) canvas.discardActiveObject() }, @@ -176,21 +181,34 @@ export function useContextMenu() { endY = (currentObject.y1 + currentObject.y2) / 2 - dy } - addLine([startX, startY, endX, endY], { + const line = addLine([startX, startY, endX, endY], { stroke: 'red', strokeWidth: 1, selectable: true, name: 'auxiliaryLine', + attributes: { ...currentObject.attributes }, }) + canvas + .getObjects() + .filter((obj) => obj.id === currentObject.attributes.roofId)[0] + .innerLines.push(line) }, }, - { - id: 'auxiliaryCut', - name: getMessage('contextmenu.auxiliary.cut'), - }, { id: 'auxiliaryRemoveAll', name: getMessage('contextmenu.auxiliary.remove.all'), + fn: () => { + if (!currentObject) { + swalFire({ text: '지붕을 선택해주세요.' }) + return + } + const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0].innerLines + innerLines.forEach((line) => { + canvas.remove(line) + }) + innerLines.length = 0 + canvas.renderAll() + }, }, ], ])