From fad86d45853c7ddc4f4ccd64fbae9014e8e9c029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EC=8B=9D?= <43837214+Minsiki@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:14:03 +0900 Subject: [PATCH] =?UTF-8?q?currentObject=EB=B3=84=20context=EB=A9=94?= =?UTF-8?q?=EB=89=B4=EC=97=90=20=EC=84=A0=ED=83=9D=20menu=20=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useContextMenu.js | 463 ++++++++++++++++++------------------ 1 file changed, 237 insertions(+), 226 deletions(-) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index 731d7476..97e9cf6c 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -118,145 +118,8 @@ export function useContextMenu() { ]) break case 'outline': - setContextMenu([ - [ - { - id: 'roofMaterialPlacement', - name: getMessage('contextmenu.roof.material.placement'), - component: , - }, - - { - id: 'roofMaterialRemoveAll', - name: getMessage('contextmenu.roof.material.remove.all'), - fn: () => removeAllRoofMaterial(), - }, - { - id: 'selectMove', - name: getMessage('contextmenu.select.move'), - fn: (currentMousePos) => { - moveRoofMaterial(currentMousePos) - }, - }, - { - id: 'wallLineRemove', - name: getMessage('contextmenu.wallline.remove'), - fn: (currentMousePos) => { - removeOuterLines(currentMousePos) - }, - }, - ], - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'auxiliaryMove', - name: `${getMessage('contextmenu.auxiliary.move')}(M)`, - shortcut: ['m', 'M'], - component: , - }, - { - id: 'auxiliaryCopy', - name: `${getMessage('contextmenu.auxiliary.copy')}(C)`, - shortcut: ['c', 'C'], - component: , - }, - { - id: 'auxiliaryRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.auxiliary.remove')}(D)`, - fn: () => { - if (!currentObject) return - const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] - if (!roof) { - // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거 - canvas.remove(currentObject) - canvas.discardActiveObject() - return - } - const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) - roof.innerLines = [...innerLines] - canvas.remove(currentObject) - canvas.discardActiveObject() - }, - }, - { - id: 'auxiliaryVerticalBisector', - name: getMessage('contextmenu.auxiliary.vertical.bisector'), - fn: () => { - if (!currentObject) return - const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1) - const length = currentObject.length - - let startX, startY, endX, endY - if (slope === 0) { - startX = endX = (currentObject.x1 + currentObject.x2) / 2 - startY = currentObject.y2 - length / 2 - endY = currentObject.y2 + length / 2 - } else if (slope === Infinity) { - startX = currentObject.x1 - length / 2 - startY = endY = (currentObject.y1 + currentObject.y2) / 2 - endX = currentObject.x1 + length / 2 - } else { - const bisectorSlope = -1 / slope - const dx = length / 2 / Math.sqrt(1 + bisectorSlope * bisectorSlope) - const dy = bisectorSlope * dx - - startX = (currentObject.x1 + currentObject.x2) / 2 + dx - startY = (currentObject.y1 + currentObject.y2) / 2 + dy - endX = (currentObject.x1 + currentObject.x2) / 2 - dx - endY = (currentObject.y1 + currentObject.y2) / 2 - dy - } - - const line = addLine([startX, startY, endX, endY], { - stroke: 'red', - strokeWidth: 1, - selectable: true, - name: 'auxiliaryLine', - attributes: { ...currentObject.attributes }, - }) - - if (!currentObject.attributes.roofId) { - return - } - - canvas - .getObjects() - .filter((obj) => obj.id === currentObject.attributes.roofId)[0] - .innerLines.push(line) - }, - }, - { - id: 'auxiliaryRemoveAll', - name: getMessage('contextmenu.auxiliary.remove.all'), - fn: () => { - if (!currentObject) { - swalFire({ text: getMessage('roof.is.not.selected') }) - return - } - const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines - if (innerLines) { - innerLines.forEach((line) => { - canvas.remove(line) - }) - innerLines.length = 0 - } - - // 확정되지 않은 보조선 - const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) - - notFixedAuxiliaryLines.forEach((line) => { - canvas.remove(line) - }) - - canvas.renderAll() - }, - }, - ], - ]) + if (['roof', 'auxiliaryLine'].includes(currentObject?.name)) { + } break default: setContextMenu([]) @@ -305,96 +168,244 @@ export function useContextMenu() { switch (currentObject.name) { case 'triangleDormer': case 'pentagonDormer': - setContextMenu([ - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'dormerRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.remove')}(D)`, - fn: () => deleteObject(), - }, - { - id: 'dormerMove', - shortcut: ['m', 'M'], - name: `${getMessage('contextmenu.move')}(M)`, - fn: () => moveObjectBatch(), - }, - { - id: 'dormerCopy', - shortcut: ['c', 'C'], - name: `${getMessage('contextmenu.copy')}(C)`, - fn: () => copyObject(), - }, - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, - { - id: 'dormerOffset', - name: getMessage('contextmenu.dormer.offset'), - component: , - }, - ], - ]) + if (selectedMenu === 'surface') { + setContextMenu([ + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , + }, + { + id: 'dormerRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.remove')}(D)`, + fn: () => deleteObject(), + }, + { + id: 'dormerMove', + shortcut: ['m', 'M'], + name: `${getMessage('contextmenu.move')}(M)`, + fn: () => moveObjectBatch(), + }, + { + id: 'dormerCopy', + shortcut: ['c', 'C'], + name: `${getMessage('contextmenu.copy')}(C)`, + fn: () => copyObject(), + }, + { + id: 'roofMaterialEdit', + name: getMessage('contextmenu.roof.material.edit'), + component: , + }, + { + id: 'dormerOffset', + name: getMessage('contextmenu.dormer.offset'), + component: , + }, + ], + ]) + } break case 'roof': - setContextMenu([ - [ - { - id: 'sizeEdit', - name: getMessage('contextmenu.size.edit'), - component: , - }, - { - id: 'roofMaterialRemove', - shortcut: ['d', 'D'], - name: `${getMessage('contextmenu.remove')}(D)`, - fn: () => deleteObject(), - }, - { - id: 'roofMaterialMove', - shortcut: ['m', 'M'], - name: `${getMessage('contextmenu.move')}(M)`, - fn: () => moveSurfaceShapeBatch(), - }, - { - id: 'roofMaterialCopy', - shortcut: ['c', 'C'], - name: `${getMessage('contextmenu.copy')}(C)`, - fn: () => copyObject(), - }, - ], - [ - { - id: 'roofMaterialEdit', - name: getMessage('contextmenu.roof.material.edit'), - component: , - }, - { - id: 'linePropertyEdit', - name: getMessage('contextmenu.line.property.edit'), - fn: () => { - if (+canvasSetting.roofSizeSet === 3) { - swalFire({ text: getMessage('contextmenu.line.property.edit.roof.size.3') }) - } else { - addPopup(popupId, 1, ) - } + case 'auxiliaryLine': + case 'hip': + case 'ridge': + if (selectedMenu === 'surface') { + setContextMenu([ + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , }, - // component: , - }, - { - id: 'flowDirectionEdit', - name: getMessage('contextmenu.flow.direction.edit'), - component: , - }, - ], - ]) + { + id: 'roofMaterialRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.remove')}(D)`, + fn: () => deleteObject(), + }, + { + id: 'roofMaterialMove', + shortcut: ['m', 'M'], + name: `${getMessage('contextmenu.move')}(M)`, + fn: () => moveSurfaceShapeBatch(), + }, + { + id: 'roofMaterialCopy', + shortcut: ['c', 'C'], + name: `${getMessage('contextmenu.copy')}(C)`, + fn: () => copyObject(), + }, + ], + [ + { + id: 'roofMaterialEdit', + name: getMessage('contextmenu.roof.material.edit'), + component: , + }, + { + id: 'linePropertyEdit', + name: getMessage('contextmenu.line.property.edit'), + fn: () => { + if (+canvasSetting.roofSizeSet === 3) { + swalFire({ text: getMessage('contextmenu.line.property.edit.roof.size.3') }) + } else { + addPopup(popupId, 1, ) + } + }, + // component: , + }, + { + id: 'flowDirectionEdit', + name: getMessage('contextmenu.flow.direction.edit'), + component: , + }, + ], + ]) + } else if (selectedMenu === 'outline') { + setContextMenu([ + [ + { + id: 'roofMaterialPlacement', + name: getMessage('contextmenu.roof.material.placement'), + component: , + }, + + { + id: 'roofMaterialRemoveAll', + name: getMessage('contextmenu.roof.material.remove.all'), + fn: () => removeAllRoofMaterial(), + }, + { + id: 'selectMove', + name: getMessage('contextmenu.select.move'), + fn: (currentMousePos) => { + moveRoofMaterial(currentMousePos) + }, + }, + { + id: 'wallLineRemove', + name: getMessage('contextmenu.wallline.remove'), + fn: (currentMousePos) => { + removeOuterLines(currentMousePos) + }, + }, + ], + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , + }, + { + id: 'auxiliaryMove', + name: `${getMessage('contextmenu.auxiliary.move')}(M)`, + shortcut: ['m', 'M'], + component: , + }, + { + id: 'auxiliaryCopy', + name: `${getMessage('contextmenu.auxiliary.copy')}(C)`, + shortcut: ['c', 'C'], + component: , + }, + { + id: 'auxiliaryRemove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.auxiliary.remove')}(D)`, + fn: () => { + if (!currentObject) return + const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0] + if (!roof) { + // 아직 innerLines로 세팅이 안되어있는 line인 경우 제거 + canvas.remove(currentObject) + canvas.discardActiveObject() + return + } + const innerLines = roof.innerLines?.filter((line) => currentObject.id !== line.id) + roof.innerLines = [...innerLines] + canvas.remove(currentObject) + canvas.discardActiveObject() + }, + }, + { + id: 'auxiliaryVerticalBisector', + name: getMessage('contextmenu.auxiliary.vertical.bisector'), + fn: () => { + if (!currentObject) return + const slope = (currentObject.y2 - currentObject.y1) / (currentObject.x2 - currentObject.x1) + const length = currentObject.length + + let startX, startY, endX, endY + if (slope === 0) { + startX = endX = (currentObject.x1 + currentObject.x2) / 2 + startY = currentObject.y2 - length / 2 + endY = currentObject.y2 + length / 2 + } else if (slope === Infinity) { + startX = currentObject.x1 - length / 2 + startY = endY = (currentObject.y1 + currentObject.y2) / 2 + endX = currentObject.x1 + length / 2 + } else { + const bisectorSlope = -1 / slope + const dx = length / 2 / Math.sqrt(1 + bisectorSlope * bisectorSlope) + const dy = bisectorSlope * dx + + startX = (currentObject.x1 + currentObject.x2) / 2 + dx + startY = (currentObject.y1 + currentObject.y2) / 2 + dy + endX = (currentObject.x1 + currentObject.x2) / 2 - dx + endY = (currentObject.y1 + currentObject.y2) / 2 - dy + } + + const line = addLine([startX, startY, endX, endY], { + stroke: 'red', + strokeWidth: 1, + selectable: true, + name: 'auxiliaryLine', + attributes: { ...currentObject.attributes }, + }) + + if (!currentObject.attributes.roofId) { + return + } + + canvas + .getObjects() + .filter((obj) => obj.id === currentObject.attributes.roofId)[0] + .innerLines.push(line) + }, + }, + { + id: 'auxiliaryRemoveAll', + name: getMessage('contextmenu.auxiliary.remove.all'), + fn: () => { + if (!currentObject) { + swalFire({ text: getMessage('roof.is.not.selected') }) + return + } + const innerLines = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]?.innerLines + if (innerLines) { + innerLines.forEach((line) => { + canvas.remove(line) + }) + innerLines.length = 0 + } + + // 확정되지 않은 보조선 + const notFixedAuxiliaryLines = canvas.getObjects().filter((obj) => obj.name === 'auxiliaryLine' && !obj.isAuxiliaryFixed) + + notFixedAuxiliaryLines.forEach((line) => { + canvas.remove(line) + }) + + canvas.renderAll() + }, + }, + ], + ]) + } + break case 'opening': setContextMenu([