From 8ed58b1618ef46f5685892963c34608178961d49 Mon Sep 17 00:00:00 2001 From: yjnoh Date: Mon, 11 Nov 2024 16:31:45 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EC=9D=B8=EC=86=8D=EC=84=B1=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/common.js | 33 +++-- src/components/auth/Login.jsx | 4 +- src/components/fabric/QPolygon.js | 1 + .../lineProperty/LinePropertySetting.jsx | 46 +++---- src/hooks/common/useCommonUtils.js | 2 +- src/hooks/surface/useSurfaceShapeBatch.js | 113 +++++++++++------- src/hooks/useCanvas.js | 11 ++ src/hooks/useContextMenu.js | 60 +++++++++- 8 files changed, 181 insertions(+), 89 deletions(-) diff --git a/src/common/common.js b/src/common/common.js index 8282f2f8..358852b5 100644 --- a/src/common/common.js +++ b/src/common/common.js @@ -61,6 +61,8 @@ export const LINE_TYPE = { DEFAULT: 'default', EAVES: 'eaves', GABLE: 'gable', + GABLE_LEFT: 'gableLeft', //케라바 왼쪽 + GABLE_RIGHT: 'gableRight', //케라바 오른쪽 WALL: 'wall', HIPANDGABLE: 'hipAndGable', JERKINHEAD: 'jerkinhead', @@ -76,28 +78,19 @@ export const LINE_TYPE = { GABLE: 'gable', VALLEY: 'valley', VERGE: 'verge', + ONESIDE_FLOW_RIDGE: 'onesideFlowRidge', //한쪽흐름 용마루 + YOSEMUNE: 'yosemune', //요세무네 + VALLEY: 'valley', //골짜기 + L_ABANDON_VALLEY: 'lAbandonValley', //l의버림계곡 + MANSARD: 'mansard', //맨사드 + WALL_COLLECTION: 'wallCollection', //벽취합 + WALL_COLLECTION_TYPE: 'wallCollectionType', //벽취합(형) + WALL_COLLECTION_FLOW: 'wallCollectionFlow', //벽취합(흐름) + WALL_COLLECTION_FLOW_LEFT: 'wallCollectionFlowLeft', //벽취합(흐름 왼쪽) + WALL_COLLECTION_FLOW_RIGHT: 'wallCollectionFlowRight', //벽취합(흐름 오른쪽) }, } -export const LineType = { - EAVES: 'eaves', // 처마 - RIDGE: 'ridge', // 용마루.... - YOSEMUNE: 'yosemune', //요세무네 - ONESIDE_FLOW_RIDGE: 'onesideFlowRidge', //한쪽흐름 용마루 - WALL_COLLECTION: 'wallCollection', //벽취합 - WALL_COLLECTION_TYPE: 'wallCollectionType', //벽취합(형) - WALL_COLLECTION_FLOW: 'wallCollectionFlow', //벽취합(흐름) - WALL_COLLECTION_FLOW_LEFT: 'wallCollectionFlowLeft', //벽취합(흐름 왼쪽) - WALL_COLLECTION_FLOW_RIGHT: 'wallCollectionFlowRight', //벽취합(흐름 오른쪽) - KERABA: 'keraba', //케라바 - KERABA_LEFT: 'kerabaLeft', //케라바 왼쪽 - KERABA_RIGHT: 'kerabaRight', //케라바 오른쪽 - VALLEY: 'valley', //골짜기 - L_ABANDON_VALLEY: 'lAbandonValley', //l의버림계곡 - MANSARD: 'mansard', //맨사드 - NO_SETTING: 'noSetting', //설정없음 -} - // 오브젝트 배치 > 개구배치, 그림자배치 export const BATCH_TYPE = { OPENING: 'opening', @@ -162,6 +155,8 @@ export const SAVE_KEY = [ 'planeSize', 'actualSize', 'surfaceId', + 'lines', + 'offset', 'arrow', ] diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx index 283d7d99..5418dec7 100644 --- a/src/components/auth/Login.jsx +++ b/src/components/auth/Login.jsx @@ -83,7 +83,7 @@ export default function Login() { /////////////////////////////////////////////////////////// // 임시 로그인 처리 setSession({ - userId: 'NEW016610', + userId: 'NEW0166102', saleStoreId: null, name: null, mail: null, @@ -101,7 +101,7 @@ export default function Login() { custCd: '100000', }) setSessionState({ - userId: 'NEW016610', + userId: 'NEW0166102', saleStoreId: null, name: null, mail: null, diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index 0663c6f5..ce4d93c7 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -191,6 +191,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { line.endPoint = nextPoint this.lines.push(line) }) + // } }, // 보조선 그리기 diff --git a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx index 5b4075f0..ed84751c 100644 --- a/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx +++ b/src/components/floor-plan/modal/lineProperty/LinePropertySetting.jsx @@ -6,48 +6,54 @@ import { usePopup } from '@/hooks/usePopup' import { useState, useEffect } from 'react' import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch' import { useEvent } from '@/hooks/useEvent' +import { LINE_TYPE } from '@/common/common' export default function LinePropertySetting(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition, target } = props const { getMessage } = useMessage() const { closePopup } = usePopup() - const { changeSurfaceLinePropertyEvent, changeSurfaceLineProperty } = useSurfaceShapeBatch() + const { changeSurfaceLinePropertyEvent, changeSurfaceLineProperty, changeSurfaceLinePropertyReset } = useSurfaceShapeBatch() const { initEvent } = useEvent() const properties = [ - { name: getMessage('eaves.line'), value: 'eaves' }, - { name: getMessage('ridge'), value: 'ridge' }, - { name: getMessage('oneside.flow.ridge'), value: 'onesideFlowRidge' }, - { name: getMessage('gable'), value: 'gable' }, - { name: getMessage('gable.left'), value: 'gableLeft' }, - { name: getMessage('gable.right'), value: 'gableRight' }, - { name: getMessage('yosemune'), value: 'yosemune' }, - { name: getMessage('valley'), value: 'valley' }, - { name: getMessage('l.abandon.valley'), value: 'lAbandonValley' }, - { name: getMessage('mansard'), value: 'mansard' }, - { name: getMessage('wall.merge'), value: 'wallCollection' }, - { name: getMessage('wall.merge.type'), value: 'wallCollectionType' }, - { name: getMessage('wall.merge.flow'), value: 'wallCollectionFlow' }, - { name: getMessage('wall.merge.flow.left'), value: 'wallCollectionFlowLeft' }, - { name: getMessage('wall.merge.flow.right'), value: 'wallCollectionFlowRight' }, - { name: getMessage('no.setting'), value: 'noSetting' }, + { name: getMessage('eaves.line'), value: LINE_TYPE.WALLLINE.EAVES }, + { name: getMessage('ridge'), value: LINE_TYPE.SUBLINE.RIDGE }, + { name: getMessage('oneside.flow.ridge'), value: LINE_TYPE.SUBLINE.ONESIDE_FLOW_RIDGE }, + { name: getMessage('gable'), value: LINE_TYPE.WALLLINE.GABLE }, + { name: getMessage('gable.left'), value: LINE_TYPE.WALLLINE.GABLE_LEFT }, + { name: getMessage('gable.right'), value: LINE_TYPE.WALLLINE.GABLE_RIGHT }, + { name: getMessage('yosemune'), value: LINE_TYPE.SUBLINE.YOSEMUNE }, + { name: getMessage('valley'), value: LINE_TYPE.SUBLINE.YOSEMUNE }, + { name: getMessage('l.abandon.valley'), value: LINE_TYPE.SUBLINE.L_ABANDON_VALLEY }, + { name: getMessage('mansard'), value: LINE_TYPE.SUBLINE.MANSARD }, + { name: getMessage('wall.merge'), value: LINE_TYPE.SUBLINE.WALL_COLLECTION }, + { name: getMessage('wall.merge.type'), value: LINE_TYPE.SUBLINE.WALL_COLLECTION_TYPE }, + { name: getMessage('wall.merge.flow'), value: LINE_TYPE.SUBLINE.WALL_COLLECTION_FLOW }, + { name: getMessage('wall.merge.flow.left'), value: LINE_TYPE.SUBLINE.WALL_COLLECTION_FLOW_LEFT }, + { name: getMessage('wall.merge.flow.right'), value: LINE_TYPE.SUBLINE.WALL_COLLECTION_FLOW_RIGHT }, + { name: getMessage('no.setting'), value: LINE_TYPE.WALLLINE.DEFAULT }, ] const [selectedProperty, setSelectedProperty] = useState(null) useEffect(() => { - changeSurfaceLinePropertyEvent(target) + changeSurfaceLinePropertyEvent() return () => { initEvent() } }, []) + const handleClosePopup = () => { + closePopup(id) + changeSurfaceLinePropertyReset(target) + } + return (

{getMessage('contextmenu.line.property.edit')}

-
@@ -79,7 +85,7 @@ export default function LinePropertySetting(props) {
-
diff --git a/src/hooks/common/useCommonUtils.js b/src/hooks/common/useCommonUtils.js index 2902e0c3..1a0fa519 100644 --- a/src/hooks/common/useCommonUtils.js +++ b/src/hooks/common/useCommonUtils.js @@ -710,7 +710,7 @@ export function useCommonUtils() { canvas?.remove(centerLine, ...extendLine, ...arrows, textObj) const reGroup = new fabric.Group(reGroupObj, { - name: 'dimensionLine', + name: 'dimensionGroup', selectable: true, lineDirection: originLineDirection, groupId: id, diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js index 189fb4df..2328b606 100644 --- a/src/hooks/surface/useSurfaceShapeBatch.js +++ b/src/hooks/surface/useSurfaceShapeBatch.js @@ -894,70 +894,75 @@ export function useSurfaceShapeBatch() { }) } - const changeSurfaceLinePropertyEvent = (roof) => { + const changeSurfaceLinePropertyEvent = () => { let tmpLines = [] - roof.set({ - selectable: false, - }) - canvas.discardActiveObject() - roof.lines.forEach((obj, index) => { - const tmpLine = new QLine([obj.x1, obj.y1, obj.x2, obj.y2], { - ...obj, - stroke: 'rgb(3, 255, 0)', - strokeWidth: 8, - selectable: true, - name: 'lineProperty', - index: index, + const roof = canvas.getActiveObject() + + if (roof) { + roof.set({ + selectable: false, }) - tmpLines.push(tmpLine) - canvas.add(tmpLine) - }) - - addCanvasMouseEventListener('mouse:down', (e) => { - const selectedLine = e.target - if (selectedLine) { - selectedLine.set({ - stroke: 'red', - name: 'selectedLineProperty', + roof.lines.forEach((obj, index) => { + const tmpLine = new QLine([obj.x1, obj.y1, obj.x2, obj.y2], { + ...obj, + stroke: 'rgb(3, 255, 0)', + strokeWidth: 8, + selectable: true, + name: 'lineProperty', + lineIndex: index, }) - tmpLines.forEach((line) => { - if (line.index !== selectedLine.index) { + + tmpLines.push(tmpLine) + canvas.add(tmpLine) + }) + + addCanvasMouseEventListener('mouse:down', (e) => { + const selectedLine = e.target + if (selectedLine && selectedLine.name !== 'roof') { + tmpLines.forEach((line) => { line.set({ stroke: 'rgb(3, 255, 0)', name: 'lineProperty', }) - } - }) - } else { - tmpLines.forEach((line) => { - line.set({ - stroke: 'rgb(3, 255, 0)', - name: 'lineProperty', }) - }) - } - }) + selectedLine.set({ + stroke: 'red', + name: 'selectedLineProperty', + }) + } else { + tmpLines.forEach((line) => { + line.set({ + stroke: 'rgb(3, 255, 0)', + name: 'lineProperty', + }) + }) + } + }) - canvas.renderAll() + canvas.renderAll() + } + canvas.discardActiveObject() } - const changeSurfaceLineProperty = (property) => { - console.log(property) + const changeSurfaceLineProperty = (property, roof) => { if (!property) { swalFire({ text: getMessage('modal.line.property.change'), icon: 'error' }) return } - const selectedLine = canvas.getActiveObjects() - if (selectedLine && selectedLine[0].name === 'selectedLineProperty') { + const selectedLine = canvas.getActiveObjects()[0] //배열로 떨어짐 한개만 선택가능 + if (selectedLine && selectedLine.name === 'selectedLineProperty') { swalFire({ text: getMessage('modal.line.property.change.confirm'), type: 'confirm', confirmFn: () => { - selectedLine.set({ + const lineIndex = selectedLine.lineIndex + roof.lines[lineIndex].attributes = { + ...roof.lines[lineIndex].attributes, type: property.value, - }) + } + canvas.renderAll() }, }) } else { @@ -965,6 +970,29 @@ export function useSurfaceShapeBatch() { } } + const changeSurfaceLinePropertyReset = (roof) => { + const lines = canvas.getObjects().filter((obj) => obj.name === 'lineProperty' || obj.name === 'selectedLineProperty') + + lines.forEach((line) => { + canvas.remove(line) + }) + + if (roof) { + roof.set({ + selectable: true, + }) + } + canvas?.renderAll() + } + + const changeSurfaceFlowDirection = (roof, direction, orientation) => { + roof.set({ + direction: direction, + }) + drawDirectionArrow(roof) + canvas?.renderAll() + } + return { applySurfaceShape, deleteAllSurfacesAndObjects, @@ -973,5 +1001,6 @@ export function useSurfaceShapeBatch() { surfaceShapeActualSize, changeSurfaceLinePropertyEvent, changeSurfaceLineProperty, + changeSurfaceLinePropertyReset, } } diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index 6ffb03fc..c1bc760f 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -109,11 +109,22 @@ export function useCanvas(id) { OBJECT_PROTOTYPE.forEach((type) => { type.toObject = function (propertiesToInclude) { let source = {} + for (let key in this) { if (typeof this[key] !== 'function' && SAVE_KEY.includes(key)) { source.key = this[key] } } + + //QLine에 커스텀 어트리뷰트 넣기 + if (this.type === 'QLine') { + this.attributes.type = this.attributes.type || 'default' + source.attributes = { + ...this.attributes, + type: this.attributes.type, + } + } + return fabric.util.object.extend(this.callSuper('toObject', propertiesToInclude), source) } }) diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js index d7edb496..f10f3d39 100644 --- a/src/hooks/useContextMenu.js +++ b/src/hooks/useContextMenu.js @@ -165,6 +165,59 @@ export function useContextMenu() { ], ]) break + case MENU.BATCH_CANVAS.SLOPE_SETTING: + case MENU.BATCH_CANVAS.BATCH_DRAWING: + case MENU.BATCH_CANVAS.SURFACE_SHAPE_BATCH: + case MENU.BATCH_CANVAS.OBJECT_BATCH: + case MENU.BATCH_CANVAS.ALL_REMOVE: + case MENU.BATCH_CANVAS.DEFAULT: + setContextMenu([ + [ + { + id: 'sizeEdit', + name: getMessage('contextmenu.size.edit'), + component: , + }, + { + id: 'remove', + shortcut: ['d', 'D'], + name: `${getMessage('contextmenu.remove')}(D)`, + }, + { + id: 'move', + shortcut: ['m', 'M'], + name: `${getMessage('contextmenu.move')}(M)`, + }, + { + id: 'copy', + shortcut: ['c', 'C'], + name: `${getMessage('contextmenu.copy')}(C)`, + }, + { + id: 'imageSizeEdit', + name: getMessage('modal.image.size.setting'), + component: , + }, + ], + [ + { + id: 'roofMaterialEdit', + name: getMessage('contextmenu.roof.material.edit'), + component: , + }, + { + id: 'linePropertyEdit', + name: getMessage('contextmenu.line.property.edit'), + component: , + }, + { + id: 'flowDirectionEdit', + name: getMessage('contextmenu.flow.direction.edit'), + component: , + }, + ], + ]) + break default: setContextMenu([]) break @@ -207,6 +260,8 @@ export function useContextMenu() { }, [currentContextMenu]) useEffect(() => { + console.log(currentObject) + if (currentObject?.name) { switch (currentObject.name) { case 'triangleDormer': @@ -252,11 +307,6 @@ export function useContextMenu() { case 'roof': setContextMenu([ [ - { - id: 'surfaceShapeActualSize', - name: '면형상 실측', - fn: () => surfaceShapeActualSize(), - }, { id: 'sizeEdit', name: '사이즈 변경',