currentObject별 context메뉴에 선택 menu 분기 처리

This commit is contained in:
김민식 2025-03-04 13:14:03 +09:00
parent ff7eb36762
commit fad86d4585

View File

@ -118,145 +118,8 @@ export function useContextMenu() {
])
break
case 'outline':
setContextMenu([
[
{
id: 'roofMaterialPlacement',
name: getMessage('contextmenu.roof.material.placement'),
component: <RoofAllocationSetting id={popupId} />,
},
{
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: <AuxiliarySize id={popupId} />,
},
{
id: 'auxiliaryMove',
name: `${getMessage('contextmenu.auxiliary.move')}(M)`,
shortcut: ['m', 'M'],
component: <AuxiliaryEdit id={popupId} type={'move'} />,
},
{
id: 'auxiliaryCopy',
name: `${getMessage('contextmenu.auxiliary.copy')}(C)`,
shortcut: ['c', 'C'],
component: <AuxiliaryEdit id={popupId} type={'copy'} />,
},
{
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: <SizeSetting id={popupId} target={currentObject} />,
},
{
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: <RoofMaterialSetting id={popupId} />,
},
{
id: 'dormerOffset',
name: getMessage('contextmenu.dormer.offset'),
component: <DormerOffset id={popupId} title={getMessage('contextmenu.dormer.offset')} />,
},
],
])
if (selectedMenu === 'surface') {
setContextMenu([
[
{
id: 'sizeEdit',
name: getMessage('contextmenu.size.edit'),
component: <SizeSetting id={popupId} target={currentObject} />,
},
{
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: <RoofMaterialSetting id={popupId} />,
},
{
id: 'dormerOffset',
name: getMessage('contextmenu.dormer.offset'),
component: <DormerOffset id={popupId} title={getMessage('contextmenu.dormer.offset')} />,
},
],
])
}
break
case 'roof':
setContextMenu([
[
{
id: 'sizeEdit',
name: getMessage('contextmenu.size.edit'),
component: <SizeSetting id={popupId} target={currentObject} />,
},
{
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: <ContextRoofAllocationSetting id={popupId} />,
},
{
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, <PlacementSurfaceLineProperty id={popupId} roof={currentObject} />)
}
case 'auxiliaryLine':
case 'hip':
case 'ridge':
if (selectedMenu === 'surface') {
setContextMenu([
[
{
id: 'sizeEdit',
name: getMessage('contextmenu.size.edit'),
component: <SizeSetting id={popupId} target={currentObject} />,
},
// component: <LinePropertySetting id={popupId} target={currentObject} />,
},
{
id: 'flowDirectionEdit',
name: getMessage('contextmenu.flow.direction.edit'),
component: <FlowDirectionSetting id={popupId} target={currentObject} />,
},
],
])
{
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: <ContextRoofAllocationSetting id={popupId} />,
},
{
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, <PlacementSurfaceLineProperty id={popupId} roof={currentObject} />)
}
},
// component: <LinePropertySetting id={popupId} target={currentObject} />,
},
{
id: 'flowDirectionEdit',
name: getMessage('contextmenu.flow.direction.edit'),
component: <FlowDirectionSetting id={popupId} target={currentObject} />,
},
],
])
} else if (selectedMenu === 'outline') {
setContextMenu([
[
{
id: 'roofMaterialPlacement',
name: getMessage('contextmenu.roof.material.placement'),
component: <RoofAllocationSetting id={popupId} />,
},
{
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: <AuxiliarySize id={popupId} />,
},
{
id: 'auxiliaryMove',
name: `${getMessage('contextmenu.auxiliary.move')}(M)`,
shortcut: ['m', 'M'],
component: <AuxiliaryEdit id={popupId} type={'move'} />,
},
{
id: 'auxiliaryCopy',
name: `${getMessage('contextmenu.auxiliary.copy')}(C)`,
shortcut: ['c', 'C'],
component: <AuxiliaryEdit id={popupId} type={'copy'} />,
},
{
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([