@@ -359,17 +410,47 @@ export default function Estimate({ params }) {
{/* 견적 특이사항 코드영역시작 */}
-
+
+ {/* SpecialNoteList반복문 */}
+ {specialNoteList.map((row) => {
+ return (
+
{
+ settingShowContent(row.code, event)
+ }}
+ >
+
+ {
+ setSpecialNoteList((specialNote) =>
+ specialNote.map((temp) => (temp.code === row.code ? { ...temp, text: !temp.text } : temp)),
+ )
+ settingShowContent(row.code, event)
+ }}
+ />
+
+
+
+ )
+ })}
+
{/* 견적특이사항 선택한 내용?영역시작 */}
-
- - 제목11??
- - 제목1 비고
-
-
- - 제목22??
- - 제목2 비고
-
+ {specialNoteList.map((row) => {
+ if (row.code === showContentCode) {
+ return (
+
+ - {row.codeNm}
+ - {row.remarks}
+
+ )
+ }
+ })}
{/* 견적특이사항 선택한 내용?영역끝 */}
diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js
index 5d1bad29..44cbfb37 100644
--- a/src/components/fabric/QPolygon.js
+++ b/src/components/fabric/QPolygon.js
@@ -137,6 +137,22 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
})
})
+ this.on('polygonMoved', () => {
+ //폴리곤일때만 사용
+ let matrix = this.calcTransformMatrix()
+
+ let transformedPoints = this.get('points')
+ .map((p) => {
+ return new fabric.Point(p.x - this.pathOffset.x, p.y - this.pathOffset.y)
+ })
+ .map((p) => {
+ return fabric.util.transformPoint(p, matrix)
+ })
+ this.set('points', transformedPoints)
+ this.set('pathOffset', { x: this.left, y: this.top })
+ this.setCoords()
+ })
+
// polygon.fillCell({ width: 50, height: 30, padding: 10 })
},
@@ -211,6 +227,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
let points = this.getCurrentPoints()
+ this.texts = []
points.forEach((start, i) => {
const end = points[(i + 1) % points.length]
const dx = end.x - start.x
diff --git a/src/components/floor-plan/modal/object/DormerOffset.jsx b/src/components/floor-plan/modal/object/DormerOffset.jsx
index bc56e4b7..191a94ea 100644
--- a/src/components/floor-plan/modal/object/DormerOffset.jsx
+++ b/src/components/floor-plan/modal/object/DormerOffset.jsx
@@ -1,22 +1,49 @@
+import { useState, useEffect, useRef } from 'react'
import { useMessage } from '@/hooks/useMessage'
import WithDraggable from '@/components/common/draggable/WithDraggable'
import { useRecoilValue } from 'recoil'
import { contextPopupPositionState } from '@/store/popupAtom'
import { usePopup } from '@/hooks/usePopup'
-import { useState } from 'react'
+import { useObjectBatch } from '@/hooks/object/useObjectBatch'
+import { canvasState } from '@/store/canvasAtom'
export default function DormerOffset(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
- const { id, pos = contextPopupPosition } = props
+ const { id, pos = contextPopupPosition, title } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
const [arrow1, setArrow1] = useState(null)
const [arrow2, setArrow2] = useState(null)
+ const arrow1LengthRef = useRef()
+ const arrow2LengthRef = useRef()
+
+ const canvas = useRecoilValue(canvasState)
+ const { dormerOffsetKeyEvent, dormerOffset } = useObjectBatch({})
+
+ useEffect(() => {
+ if (canvas) {
+ dormerOffsetKeyEvent(setArrow1, setArrow2)
+ }
+ }, [])
+
+ const handleOffsetDormer = () => {
+ const length1 = arrow1LengthRef.current.value
+ const length2 = arrow2LengthRef.current.value
+
+ dormerOffset(arrow1, arrow2, length1, length2)
+
+ setArrow1(null)
+ setArrow2(null)
+ arrow1LengthRef.current.value = ''
+ arrow2LengthRef.current.value = ''
+
+ // closePopup(id)
+ }
return (
-
{getMessage('contextmenu.dormer.offset')}
+
{title}
@@ -29,44 +56,40 @@ export default function DormerOffset(props) {
{getMessage('length')}
-
+
diff --git a/src/components/floor-plan/modal/object/SizeSetting.jsx b/src/components/floor-plan/modal/object/SizeSetting.jsx
index 1b20b853..333150ea 100644
--- a/src/components/floor-plan/modal/object/SizeSetting.jsx
+++ b/src/components/floor-plan/modal/object/SizeSetting.jsx
@@ -8,6 +8,8 @@ import { contextPopupPositionState } from '@/store/popupAtom'
import { useRef, useState, useEffect } from 'react'
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
import { useEvent } from '@/hooks/useEvent'
+import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
+import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
export default function SizeSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState)
@@ -15,8 +17,8 @@ export default function SizeSetting(props) {
const { id, pos = contextPopupPosition, target } = props
const { getMessage } = useMessage()
const { closePopup } = usePopup()
- const { reSizeObjectBatch } = useObjectBatch({})
-
+ const { resizeObjectBatch } = useObjectBatch({})
+ const { reSizePolygon } = useSurfaceShapeBatch()
const widthRef = useRef(null)
const heightRef = useRef(null)
@@ -30,7 +32,15 @@ export default function SizeSetting(props) {
const width = widthRef.current.value
const height = heightRef.current.value
- reSizeObjectBatch(settingTarget, target, width, height)
+ if (
+ target.name === BATCH_TYPE.OPENING ||
+ target.name === BATCH_TYPE.SHADOW ||
+ target.name === BATCH_TYPE.TRIANGLE_DORMER ||
+ target.name === BATCH_TYPE.PENTAGON_DORMER ||
+ target.name === POLYGON_TYPE.ROOF
+ ) {
+ resizeObjectBatch(settingTarget, target, width, height)
+ }
}
return (
diff --git a/src/components/management/Stuff.jsx b/src/components/management/Stuff.jsx
index 05f62c28..2603cc04 100644
--- a/src/components/management/Stuff.jsx
+++ b/src/components/management/Stuff.jsx
@@ -167,68 +167,13 @@ export default function Stuff() {
}
}
- //그리드 체크박스 선택시 미사용
- // const getSelectedRowdata = (data) => {
- // setSelectedRowData(data)
- // setSelectedRowDataCount(data.length)
- // }
-
- //물건삭제
- // const fnDeleteRowData = (data) => {
- // if (data.length === 0) {
- // return alert('삭제할 데이터를 선택하세요')
- // }
- // let errCount = 0
- // data.forEach((cell) => {
- // if (!cell.objectNo) {
- // if (errCount === 0) {
- // alert('물건정보가 있는 행만 삭제 됩니다')
- // }
- // errCount++
- // }
- // })
- // }
-
- //행추가
- // let newCount = 0
- // const addRowItems = () => {
- // // console.log('girdRef::::::', gridRef.current.api)
- // const newItems = [
- // {
- // mission: newCount + 1,
- // successful: true,
- // },
- // ]
- // gridRef.current.api.applyTransaction({
- // add: newItems,
- // addIndex: newCount,
- // })
- // newCount++
- // }
-
- //행삭제
- // const removeRowItems = () => {
- // // console.log('selectedRowData::', selectedRowData)
- // let errCount = 0
- // selectedRowData.forEach((cell) => {
- // if (!cell.company) {
- // let newSelectedRowData = selectedRowData.filter((item) => item.company == null)
- // gridRef.current.api.applyTransaction({ remove: newSelectedRowData })
- // } else {
- // if (errCount === 0) {
- // alert('행추가로 추가 한 행만 삭제됩니다.')
- // }
- // errCount++
- // }
- // })
- // }
-
// 진입시 그리드 데이터 조회
useEffect(() => {
if (isObjectNotEmpty(session)) {
if (stuffSearchParams?.code === 'S') {
const params = {
- saleStoreId: stuffSearchParams.schSelSaleStoreId,
+ // saleStoreId: stuffSearchParams.schSelSaleStoreId,
+ saleStoreId: session.storeId,
schObjectNo: stuffSearchParams?.schObjectNo,
schAddress: stuffSearchParams?.schAddress,
schObjectName: stuffSearchParams?.schObjectName,
@@ -245,7 +190,6 @@ export default function Stuff() {
: stuffSearchParams.schSelSaleStoreId,
schSortType: stuffSearchParams.schSortType,
}
-
async function fetchData() {
const apiUrl = `/api/object/list?${queryStringFormatter(params)}`
await get({
@@ -297,10 +241,7 @@ export default function Stuff() {
//조회를 눌렀을때
async function fetchData() {
- let saleStoreId
- saleStoreId = stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : session?.storeId
- // const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
- const apiUrl = `/api/object/list?saleStoreId=${saleStoreId}&${queryStringFormatter(stuffSearchParams)}`
+ const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
await get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
@@ -331,10 +272,7 @@ export default function Stuff() {
})
setPageNo(1)
- let saleStoreId
- saleStoreId = stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : session?.storeId
- // const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
- const apiUrl = `/api/object/list?saleStoreId=${saleStoreId}&${queryStringFormatter(stuffSearchParams)}`
+ const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
@@ -366,10 +304,7 @@ export default function Stuff() {
})
setPageNo(1)
- let saleStoreId
- saleStoreId = stuffSearchParams?.schSelSaleStoreId ? stuffSearchParams.schSelSaleStoreId : session?.storeId
- // const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
- const apiUrl = `/api/object/list?saleStoreId=${saleStoreId}&${queryStringFormatter(stuffSearchParams)}`
+ const apiUrl = `/api/object/list?saleStoreId=${session?.storeId}&${queryStringFormatter(stuffSearchParams)}`
get({ url: apiUrl }).then((res) => {
if (!isEmptyArray(res)) {
setGridProps({ ...gridProps, gridData: res, count: res[0].totCnt })
diff --git a/src/components/management/StuffDetail.jsx b/src/components/management/StuffDetail.jsx
index 49fc92f8..9a455216 100644
--- a/src/components/management/StuffDetail.jsx
+++ b/src/components/management/StuffDetail.jsx
@@ -420,7 +420,6 @@ export default function StuffDetail() {
useEffect(() => {
if (isObjectNotEmpty(detailData)) {
- // console.log('상세데이타세팅:::::', detailData)
// 도도부현API
get({ url: '/api/object/prefecture/list' }).then((res) => {
if (!isEmptyArray(res)) {
@@ -434,23 +433,18 @@ export default function StuffDetail() {
let firstList
let otherList
let favList
- // if (sessionState?.storeId === 'T01') {
+
if (session?.storeId === 'T01') {
- // url = `/api/object/saleStore/${sessionState?.storeId}/firstList?userId=${sessionState?.userId}`
url = `/api/object/saleStore/${session?.storeId}/firstList?userId=${session?.userId}`
} else {
- // if (sessionState.storeLvl === '1') {
if (session.storeLvl === '1') {
- // url = `/api/object/saleStore/${sessionState?.storeId}/list?firstFlg=1&userId=${sessionState?.userId}`
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
} else {
- // url = `/api/object/saleStore/${sessionState?.storeId}/list?firstFlg=1&userId=${sessionState?.userId}`
url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=1&userId=${session?.userId}`
}
}
get({ url: url }).then((res) => {
if (!isEmptyArray(res)) {
- // if (sessionState?.storeId === 'T01') {
if (session?.storeId === 'T01') {
firstList = res.filter((row) => row.saleStoreLevel === '1')
firstList.sort((a, b) => (a.saleStoreId !== 'T01') - (b.saleStoreId !== 'T01') || a.saleStoreId - b.saleStoreId)
@@ -459,14 +453,19 @@ export default function StuffDetail() {
setFavoriteStoreList(favList)
setShowSaleStoreList(favList)
- form.setValue('saleStoreId', firstList[0].saleStoreId)
- form.setValue('saleStoreName', firstList[0].saleStoreName)
- form.setValue('saleStoreLevel', firstList[0].saleStoreLevel)
- setSelOptions(firstList[0].saleStoreId)
+ if (detailData.firstAgentId != null) {
+ form.setValue('saleStoreId', detailData.firstAgentId)
+ setSelOptions(detailData.firstAgentId)
+ } else {
+ form.setValue('saleStoreId', detailData.saleStoreId)
+ setSelOptions(detailData.saleStoreId)
+ }
//상세데이터의 1차점 아이디로 2차점 목록 조회하기
- // url = `/api/object/saleStore/${detailData?.saleStoreId}/list?firstFlg=0&userId=${sessionState?.userId}`
- url = `/api/object/saleStore/${detailData?.saleStoreId}/list?firstFlg=0&userId=${session?.userId}`
+
+ let data = detailData?.firstAgentId ? detailData.firstAgentId : detailData.saleStoreId
+ // url = `/api/object/saleStore/${session?.storeId}/list?firstFlg=0&userId=${session?.userId}`
+ url = `/api/object/saleStore/${data}/list?firstFlg=0&userId=${session?.userId}`
get({ url: url }).then((res) => {
if (!isEmptyArray(res)) {
@@ -482,7 +481,6 @@ export default function StuffDetail() {
})
} else {
//1차점 셀렉트박스
- // if (sessionState?.storeLvl === '1') {
if (session?.storeLvl === '1') {
firstList = res
favList = res.filter((row) => row.priority !== 'B')
@@ -572,7 +570,6 @@ export default function StuffDetail() {
form.setValue('remarks', detailData.remarks)
})
}
- // }, [detailData, sessionState])
}, [detailData, session])
//경칭선택 변경 이벤트
@@ -1931,7 +1928,6 @@ export default function StuffDetail() {
- {/* {sessionState?.storeId === 'T01' && ( */}
{session?.storeId === 'T01' && (
<>
@@ -1947,10 +1943,8 @@ export default function StuffDetail() {
onChange={onSelectionChange}
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
- // isClearable={sessionState?.storeLvl === '1' ? true : false}
- isClearable={session?.storeLvl === '1' ? true : false}
- // isDisabled={sessionState?.storeLvl !== '1' ? true : false}
- isDisabled={session?.storeLvl !== '1' ? true : false}
+ isClearable={detailData.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false}
+ isDisabled={detailData.tempFlg === '0' ? true : session?.storeLvl !== '1' ? true : false}
value={saleStoreList.filter(function (option) {
return option.saleStoreId === selOptions
})}
@@ -1967,7 +1961,6 @@ export default function StuffDetail() {
>
)}
- {/* {sessionState?.storeId !== 'T01' && sessionState?.storeLvl === '1' && ( */}
{session?.storeId !== 'T01' && session?.storeLvl === '1' && (
<>
@@ -1983,8 +1976,9 @@ export default function StuffDetail() {
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
isClearable={false}
- // isDisabled={sessionState?.storeLvl !== '1' ? true : sessionState?.storeId !== 'T01' ? true : false}
- isDisabled={session?.storeLvl !== '1' ? true : session?.storeId !== 'T01' ? true : false}
+ isDisabled={
+ detailData.tempFlg === '0' ? true : session?.storeLvl !== '1' ? true : session?.storeId !== 'T01' ? true : false
+ }
value={showSaleStoreList.filter(function (option) {
return option.saleStoreId === selOptions
})}
@@ -2001,7 +1995,6 @@ export default function StuffDetail() {
>
)}
- {/* {sessionState?.storeId !== 'T01' && sessionState?.storeLvl !== '1' && ( */}
{session?.storeId !== 'T01' && session?.storeLvl !== '1' && (
<>
@@ -2062,10 +2055,10 @@ export default function StuffDetail() {
onChange={onSelectionChange2}
getOptionLabel={(x) => x.saleStoreName}
getOptionValue={(x) => x.saleStoreId}
- // isDisabled={sessionState?.storeLvl === '1' && form.watch('saleStoreId') != '' ? false : true}
- isDisabled={session?.storeLvl === '1' && form.watch('saleStoreId') != '' ? false : true}
- // isClearable={sessionState?.storeLvl === '1' ? true : false}
- isClearable={session?.storeLvl === '1' ? true : false}
+ isDisabled={
+ detailData.tempFlg === '0' ? true : session?.storeLvl === '1' && form.watch('saleStoreId') != '' ? false : true
+ }
+ isClearable={detailData.tempFlg === '0' ? false : session?.storeLvl === '1' ? true : false}
value={otherSaleStoreList.filter(function (option) {
return option.saleStoreId === otherSelOptions
})}
diff --git a/src/hooks/common/useCanvasConfigInitialize.js b/src/hooks/common/useCanvasConfigInitialize.js
index 8d8eb38b..c4f137b0 100644
--- a/src/hooks/common/useCanvasConfigInitialize.js
+++ b/src/hooks/common/useCanvasConfigInitialize.js
@@ -100,8 +100,6 @@ export function useCanvasConfigInitialize() {
const groups = canvas.getObjects().filter((obj) => obj.groupYn && obj.name === 'dimensionGroup')
const groupIds = []
- console.log('groupDimensionInit', groups)
-
groups.forEach((group) => {
if (!groupIds.includes(group.id)) {
groupIds.push(group.id)
@@ -157,6 +155,7 @@ export function useCanvasConfigInitialize() {
//그룹아이디로 캔버스의 객체를 조회함
const groupObjects = canvas.getObjects().filter((obj) => obj.groupId === id || obj.id === id)
const objectsName = canvas.getObjects().filter((obj) => obj.groupId === id || obj.id === id)[0].groupName
+ const objectsParentId = canvas.getObjects().filter((obj) => obj.groupId === id || obj.id === id)[0].parentId
let objectArray = []
@@ -181,8 +180,14 @@ export function useCanvasConfigInitialize() {
lockMovementY: true,
originX: 'center',
originY: 'center',
+ parentId: objectsParentId,
})
canvas.add(group)
+
+ //그룹 객체 재그룹 완료
+ group.getObjects().forEach((obj) => {
+ obj.fire('modified')
+ })
})
}
diff --git a/src/hooks/object/useObjectBatch.js b/src/hooks/object/useObjectBatch.js
index 19cbadec..a16ce0f9 100644
--- a/src/hooks/object/useObjectBatch.js
+++ b/src/hooks/object/useObjectBatch.js
@@ -16,7 +16,7 @@ import { fontSelector } from '@/store/fontAtom'
export function useObjectBatch({ isHidden, setIsHidden }) {
const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState)
- const { addCanvasMouseEventListener, initEvent } = useEvent()
+ const { addCanvasMouseEventListener, initEvent, addDocumentEventListener } = useEvent()
const { swalFire } = useSwal()
const { drawDirectionArrow } = usePolygon()
const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
@@ -33,10 +33,16 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}, [])
const dbClickEvent = () => {
+ console.log('dbClickEvent 실행')
const dormerObject = canvas.getObjects().filter((obj) => obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER)
+ console.log('dormerObject', dormerObject)
+
if (dormerObject) {
+ canvas.off('mouse:dblclick')
canvas.on('mouse:dblclick', (e) => {
+ console.log('event', e)
+
if (e.target && e.target instanceof fabric.Group) {
const pointer = canvas.getPointer(e.e)
const objects = e.target._objects
@@ -71,7 +77,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
let rect, isDown, origX, origY
let selectedSurface
//프리입력
- console.log('useObjectBatch', isHidden)
+
if (selectedType === INPUT_TYPE.FREE) {
addCanvasMouseEventListener('mouse:down', (e) => {
isDown = true
@@ -160,7 +166,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}
isDown = false
- rect.set({ name: objName })
+ rect.set({ name: objName, parentId: selectedSurface.id })
rect.setCoords()
initEvent()
@@ -204,6 +210,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
lockRotation: true,
lockScalingX: true,
lockScalingY: true,
+ parentId: selectedSurface.id,
})
//개구냐 그림자냐에 따라 변경
@@ -241,7 +248,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
}
isDown = false
- rect.set({ name: objName })
+ rect.set({ name: objName, parentId: selectedSurface.id })
rect.setCoords()
initEvent()
if (setIsHidden) setIsHidden(false)
@@ -483,6 +490,9 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
subTargetCheck: true,
name: dormerName,
id: id,
+ parentId: selectedSurface.id,
+ originX: 'center',
+ originY: 'center',
})
canvas?.add(objectGroup)
@@ -693,6 +703,10 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
subTargetCheck: true,
name: dormerName,
id: id,
+ parentId: selectedSurface.id,
+ groupYn: true,
+ originX: 'center',
+ originY: 'center',
})
canvas?.add(objectGroup)
@@ -858,9 +872,7 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
return [leftPoints, rightPoints]
}
- const reSizeObjectBatch = (side, target, width, height) => {
- const targetObj = canvas.getActiveObject()
-
+ const resizeObjectBatch = (side, target, width, height) => {
const objectWidth = target.width
const objectHeight = target.height
const changeWidth = (width / 10 / objectWidth).toFixed(2)
@@ -884,7 +896,6 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
const newCoords = target.getPointByOrigin(sideX, sideY)
target.set({
- ...target,
originX: sideX,
originY: sideY,
left: newCoords.x,
@@ -894,8 +905,8 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
target.setCoords()
canvas?.renderAll() //변경 좌표를 한번 적용
- target.scaleX = changeWidth === 0 ? 1 : changeWidth
- target.scaleY = changeHeight === 0 ? 1 : changeHeight
+ target.scaleX = changeWidth || 1
+ target.scaleY = changeHeight || 1
//크기 변경후 좌표를 재 적용
const changedCoords = target.getPointByOrigin('center', 'center')
@@ -910,9 +921,12 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
if (target.name === 'roof') {
//얘는 일단 도머에 적용함
- target._objects.forEach((obj) => {
- setSurfaceShapePattern(obj)
- })
+ if (target.type === 'group') {
+ target._objects.forEach((obj) => setSurfaceShapePattern(obj))
+ } else {
+ setSurfaceShapePattern(target)
+ target.fire('modified')
+ }
}
// target.setCoords()
canvas.renderAll()
@@ -923,30 +937,34 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
const reGroupObject = (groupObj) => {
groupObj._restoreObjectsState() //이건 실행만 되도 그룹이 변경됨
const reGroupObjects = []
-
groupObj._objects.forEach((obj) => {
const newObj = new QPolygon(obj.getCurrentPoints(), {
...obj,
points: obj.getCurrentPoints(),
scaleX: 1,
scaleY: 1,
+ texts: [],
})
reGroupObjects.push(newObj)
canvas.remove(obj)
-
if (obj.direction) {
drawDirectionArrow(obj)
}
+ newObj.fire('modified')
})
-
const reGroup = new fabric.Group(reGroupObjects, {
subTargetCheck: true,
name: groupObj.name,
id: groupObj.id,
groupYn: true,
+ parentId: groupObj.parentId,
+ originX: 'center',
+ originY: 'center',
})
canvas?.add(reGroup)
canvas?.remove(groupObj)
+
+ return reGroup
}
const moveObjectBatch = () => {
@@ -965,17 +983,46 @@ export function useObjectBatch({ isHidden, setIsHidden }) {
})
initEvent()
obj.setCoords()
- reGroupObject(obj)
+ if (obj.type === 'group') reGroupObject(obj)
})
}
}
+ const dormerOffsetKeyEvent = (setArrow1, setArrow2) => {
+ addDocumentEventListener('keydown', document, (e) => {
+ if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {
+ const keyEvent = e.key === 'ArrowDown' ? 'down' : 'up'
+ setArrow1(keyEvent)
+ } else if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
+ const keyEvent = e.key === 'ArrowLeft' ? 'left' : 'right'
+ setArrow2(keyEvent)
+ }
+ })
+ }
+
+ const dormerOffset = (arrow1, arrow2, length1, length2) => {
+ length1 = parseInt(length1) / 10
+ length2 = parseInt(length2) / 10
+
+ const dormer = canvas.getActiveObject()
+ if (length1) dormer.top = arrow1 === 'down' ? dormer.top + length1 : dormer.top - length1
+ if (length2) dormer.left = arrow2 === 'left' ? dormer.left - length2 : dormer.left + length2
+
+ if (dormer.type === 'group') {
+ const newDormer = reGroupObject(dormer)
+ canvas?.setActiveObject(newDormer)
+ }
+ canvas.renderAll()
+ }
+
return {
applyOpeningAndShadow,
applyDormers,
splitDormerTriangle,
splitDormerPentagon,
- reSizeObjectBatch,
+ resizeObjectBatch,
moveObjectBatch,
+ dormerOffsetKeyEvent,
+ dormerOffset,
}
}
diff --git a/src/hooks/roofcover/useMovementSetting.js b/src/hooks/roofcover/useMovementSetting.js
index f09aee6b..34961ea0 100644
--- a/src/hooks/roofcover/useMovementSetting.js
+++ b/src/hooks/roofcover/useMovementSetting.js
@@ -1,10 +1,12 @@
import { useRecoilValue } from 'recoil'
-import { canvasState } from '@/store/canvasAtom'
+import { canvasState, currentObjectState } from '@/store/canvasAtom'
import { usePopup } from '@/hooks/usePopup'
import { useMessage } from '@/hooks/useMessage'
import { useEffect, useRef, useState } from 'react'
import { useEvent } from '@/hooks/useEvent'
import { POLYGON_TYPE } from '@/common/common'
+import { OUTER_LINE_TYPE } from '@/store/outerLineAtom'
+import { QLine } from '@/components/fabric/QLine'
//동선이동 형 올림 내림
export function useMovementSetting(id) {
@@ -16,6 +18,8 @@ export function useMovementSetting(id) {
const { initEvent, addCanvasMouseEventListener } = useEvent()
const { closePopup } = usePopup()
const { getMessage } = useMessage()
+ const currentObject = useRecoilValue(currentObjectState)
+ const selectedObject = useRef(null)
const buttonType = [
{ id: 1, name: getMessage('modal.movement.flow.line.move'), type: TYPE.FLOW_LINE },
{ id: 2, name: getMessage('modal.movement.flow.line.updown'), type: TYPE.UP_DOWN },
@@ -38,42 +42,231 @@ export function useMovementSetting(id) {
}
useEffect(() => {
+ removeFlowLine()
typeRef.current = type
+ const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true
+ outerLines.forEach((line) => {
+ line.set({ stroke: 'black' })
+ line.set({ visible: false })
+ })
+ canvas.getObjects().forEach((obj) => {
+ obj.set({ selectable: false })
+ })
+ const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // 기존 wallLine의 visible false
+ roofs.forEach((roof) => {
+ roof.innerLines.forEach((line) => {
+ line.bringToFront()
+ line.set({ selectable: false })
+ line.set({ strokeWidth: 1 })
+ })
+ })
+ if (type === TYPE.FLOW_LINE) {
+ roofs.forEach((roof) => {
+ roof.innerLines.forEach((line) => {
+ line.bringToFront()
+ line.set({ selectable: true })
+ line.set({ strokeWidth: 4 })
+ })
+ })
+ } else if (type === TYPE.UP_DOWN) {
+ const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true
+ outerLines.forEach((line) => {
+ line.set({ stroke: 'black' })
+ line.set({ visible: true })
+ line.bringToFront()
+ line.set({ selectable: true })
+ })
+ }
+ canvas.renderAll()
}, [type])
useEffect(() => {
- const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) // 기존 wallLine의 visible false
+ /*const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) // 기존 wallLine의 visible false
wallLines.forEach((line) => {
line.set({ visible: false })
- })
- const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true
- outerLines.forEach((line) => {
- line.bringToFront()
- line.set({ selectable: true })
- })
+ })*/
canvas.renderAll()
addCanvasMouseEventListener('mouse:move', mouseMoveEvent)
+ addCanvasMouseEventListener('mouse:down', mouseDownEvent)
return () => {
initEvent()
+ removeFlowLine()
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
wallLines.forEach((line) => {
line.set({ visible: true })
})
+
+ const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true
+ outerLines.forEach((line) => {
+ line.set({ stroke: 'black' })
+ line.set({ visible: false })
+ })
+
canvas.renderAll()
}
}, [])
- const mouseMoveEvent = (e) => {
- if (typeRef.current === TYPE.FLOW_LINE) {
- flowLineEvent(e)
- } else {
- updownEvent(e)
+ useEffect(() => {
+ const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true
+ outerLines.forEach((line) => {
+ line.set({ stroke: 'black' })
+ })
+ selectedObject.current = null
+
+ if (!currentObject) {
+ return
+ }
+
+ clearRef()
+ selectedObject.current = currentObject
+ if (currentObject.name === OUTER_LINE_TYPE.OUTER_LINE) {
+ currentObject.set({ stroke: '#EA10AC' })
+ currentObject.bringToFront()
+ }
+ canvas.renderAll()
+ }, [currentObject])
+
+ const clearRef = () => {
+ if (type === TYPE.FLOW_LINE) {
+ FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = ''
+ FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = ''
+ FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = false
+ FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = false
+ }
+ if (type === TYPE.UP_DOWN) {
+ UP_DOWN_REF.UP_INPUT_REF.current.value = ''
+ UP_DOWN_REF.DOWN_INPUT_REF.current.value = ''
+ UP_DOWN_REF.UP_RADIO_REF.current.checked = false
+ UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false
}
}
- const flowLineEvent = (e) => {}
- const updownEvent = (e) => {
+ const mouseDownEvent = (e) => {
+ if (typeRef.current === TYPE.FLOW_LINE) {
+ flowLineDownEvent(e)
+ } else {
+ updownDownEvent(e)
+ }
+ }
+
+ const removeFlowLine = () => {
+ const flowLine = canvas.getObjects().filter((obj) => obj.name === 'flowLine')
+ flowLine.forEach((line) => {
+ canvas.remove(line)
+ })
+ }
+
+ const mouseMoveEvent = (e) => {
+ if (typeRef.current === TYPE.FLOW_LINE) {
+ flowLineMoveEvent(e)
+ } else {
+ updownMoveEvent(e)
+ }
+ }
+ //동선 이동 마우스 클릭 이벤트
+ const flowLineDownEvent = (e) => {
+ const target = selectedObject.current
+ if (!target) {
+ return
+ }
+
+ const direction = target.direction
+
+ removeFlowLine()
+
+ let newPoint = []
+ if (direction === 'left' || direction === 'right') {
+ if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked) {
+ newPoint = [
+ target.x1,
+ target.y1 + Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10),
+ target.x2,
+ target.y2 + Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10),
+ ]
+ } else {
+ newPoint = [
+ target.x1,
+ target.y1 - Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10),
+ target.x2,
+ target.y2 - Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10),
+ ]
+ }
+ } else {
+ if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked) {
+ newPoint = [
+ target.x1 - Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10),
+ target.y1,
+ target.x2 - Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10),
+ target.y2,
+ ]
+ } else {
+ newPoint = [
+ target.x1 + Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10),
+ target.y1,
+ target.x2 + Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10),
+ target.y2,
+ ]
+ }
+ }
+
+ const cloned = new fabric.Line(newPoint, {
+ stroke: 'red',
+ strokeWidth: 4,
+ name: 'flowLine',
+ currentLine: target,
+ })
+
+ canvas.add(cloned)
+ canvas.renderAll()
+ canvas.discardActiveObject()
+ }
+
+ //형 올림내림 마우스 클릭 이벤트
+ const updownDownEvent = (e) => {
+ console.log('updownDownEvent')
+ }
+ const flowLineMoveEvent = (e) => {
+ const target = canvas.getActiveObject()
+ if (!target) {
+ return
+ }
+ const direction = target.direction
+ const { top: targetTop, left: targetLeft } = target
+ const currentX = canvas.getPointer(e.e).x
+ const currentY = Math.floor(canvas.getPointer(e.e).y)
+
+ if (direction === 'left' || direction === 'right') {
+ if (targetTop > currentY) {
+ console.log('targetTop > currentY')
+ FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = true
+ FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = ''
+
+ FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000)
+ } else {
+ FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true
+ FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = ''
+
+ FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000)
+ }
+ } else {
+ if (targetLeft > currentX) {
+ FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true
+ FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = ''
+
+ FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000)
+ } else {
+ FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = true
+ FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = ''
+
+ FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000)
+ }
+ }
+
+ canvas?.renderAll()
+ }
+
+ const updownMoveEvent = (e) => {
const target = canvas.getActiveObject()
if (!target) {
return
@@ -114,12 +307,24 @@ export function useMovementSetting(id) {
const handleSave = () => {
if (type === TYPE.FLOW_LINE) {
- // 동선이동
- if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked) {
- // 높이 변경: 아래, 왼쪽 체크
- } else {
- // 높이 변경: 위, 오른쪽 체크
+ const flowLine = canvas.getObjects().find((obj) => obj.name === 'flowLine')
+
+ const currentLine = flowLine.currentLine
+ if (!flowLine || !currentLine) {
+ return
}
+
+ currentLine.set({
+ x1: flowLine.x1,
+ y1: flowLine.y1,
+ x2: flowLine.x2,
+ y2: flowLine.y2,
+ })
+ currentLine.startPoint = { x: flowLine.x1, y: flowLine.y1 }
+ currentLine.endPoint = { x: flowLine.x2, y: flowLine.y2 }
+
+ canvas.remove(flowLine)
+ canvas.renderAll()
} else {
// 형 올림내림
if (UP_DOWN_REF.UP_RADIO_REF.current.checked) {
diff --git a/src/hooks/surface/useSurfaceShapeBatch.js b/src/hooks/surface/useSurfaceShapeBatch.js
index 2bfefb98..9457169c 100644
--- a/src/hooks/surface/useSurfaceShapeBatch.js
+++ b/src/hooks/surface/useSurfaceShapeBatch.js
@@ -12,10 +12,12 @@ import { useEvent } from '@/hooks/useEvent'
import { usePopup } from '@/hooks/usePopup'
import { roofDisplaySelector } from '@/store/settingAtom'
import { usePolygon } from '@/hooks/usePolygon'
+import { fontSelector } from '@/store/fontAtom'
export function useSurfaceShapeBatch() {
const { getMessage } = useMessage()
const { drawDirectionArrow } = usePolygon()
+ const lengthTextFont = useRecoilValue(fontSelector('lengthText'))
const canvas = useRecoilValue(canvasState)
const globalPitch = useRecoilValue(globalPitchState)
@@ -598,8 +600,214 @@ export function useSurfaceShapeBatch() {
})
}
+ const findAllChildren = (parentId) => {
+ let allChildren = []
+
+ // 직계 자식 객체들 찾기
+ const directChildren = canvas.getObjects().filter((obj) => obj.parentId === parentId)
+
+ directChildren.forEach((child) => {
+ allChildren.push(child) // 현재 자식 추가
+
+ // 자식이 그룹인 경우
+ if (child.type === 'group') {
+ // 그룹 내부의 객체들 추가
+ child.getObjects().forEach((groupItem) => {
+ allChildren.push(groupItem)
+ // 그룹 내부 객체의 자식들도 찾기
+ const nestedChildren = findAllChildren(groupItem.id)
+ allChildren.push(...nestedChildren)
+ })
+ }
+
+ // 현재 자식의 하위 자식들 찾기
+ const childrenOfChild = findAllChildren(child.id)
+ allChildren.push(...childrenOfChild)
+ })
+
+ // 중복 제거하여 반환
+ return [...new Set(allChildren)]
+ }
+
+ const findGroupObjects = (parentId) => {
+ let groupObjectsArray = []
+
+ // 직계 자식 객체들 찾기
+ const directChildren = canvas.getObjects().filter((obj) => obj.parentId === parentId)
+
+ // 각 자식 객체에 대해 처리
+ directChildren.forEach((child) => {
+ groupObjectsArray.push(child) // 현재 자식 추가
+
+ // 자식이 그룹인 경우 그룹 내부 객체들도 처리
+ if (child.type === 'group') {
+ child.getObjects().forEach((groupItem) => {
+ // 그룹 내부 각 아이템의 하위 객체들 찾기
+ const nestedObjects = findGroupObjects(groupItem.id)
+ groupObjectsArray.push(...nestedObjects)
+ })
+ }
+
+ // 일반 자식의 하위 객체들 찾기
+ const childObjects = findGroupObjects(child.id)
+ groupObjectsArray.push(...childObjects)
+ })
+
+ return groupObjectsArray
+ }
+
+ function getAllRelatedObjects(id) {
+ const result = []
+ const map = new Map()
+
+ // Create a map of objects by their id
+ canvas.getObjects().forEach((obj) => {
+ map.set(obj.id, obj)
+ })
+
+ // Helper function to recursively find all related objects
+ function findRelatedObjects(id) {
+ const obj = map.get(id)
+ if (obj) {
+ result.push(obj)
+ canvas.getObjects().forEach((o) => {
+ if (o.parentId === id) {
+ findRelatedObjects(o.id)
+ }
+ })
+ }
+ }
+
+ // Start the search with the given parentId
+ findRelatedObjects(id)
+
+ return result
+ }
+
+ const moveSurfaceShapeBatch = () => {
+ const roof = canvas.getActiveObject()
+
+ if (roof) {
+ let isDragging = false
+
+ const childrenObjects = canvas.getObjects().filter((obj) => obj.parentId === roof.id)
+
+ console.log('childrenObjects', childrenObjects)
+
+ // const groupObjects = canvas.getObjects().filter((obj) => obj.parentId === roof.id && obj.type === 'group')
+
+ // const ungroupObjects = [] // 그룹 해제된 객체들
+ // const groupChildObjects = []
+
+ // groupObjects.forEach((obj) => {
+ // obj._restoreObjectsState()
+ // obj.getObjects().forEach((o) => {
+ // o.set({
+ // ungroupYn: true,
+ // })
+ // canvas.add(o)
+ // ungroupObjects.push(o)
+ // })
+ // canvas.remove(obj)
+ // })
+
+ // const childObjects = findAllChildren(roof.id)
+ // groupObjects.forEach((obj) => {
+ // groupChildObjects.push(...obj.getObjects())
+ // })
+
+ // console.log('ungroupObjects', ungroupObjects)
+ // console.log('childObjects', childObjects)
+ // console.log('groupChildObjects', groupChildObjects)
+
+ // const children = canvas.getObjects().filter((obj) => obj.parentId === roof.id)
+ // let grandChildren = []
+
+ // children.forEach((child) => {
+ // if (child.type === 'group') {
+ // child.getObjects().forEach((grandChild) => {
+ // const groupObjects = canvas.getObjects().filter((obj) => obj.parentId === grandChild.id)
+ // grandChildren.push(...groupObjects)
+ // })
+ // } else {
+ // grandChildren.push(...canvas.getObjects().filter((obj) => obj.parentId === child.id))
+ // }
+ // })
+
+ const selectionArray = [roof, ...childrenObjects]
+
+ const selection = new fabric.ActiveSelection(selectionArray, {
+ canvas: canvas,
+ draggable: true,
+ lockMovementX: false, // X축 이동 허용
+ lockMovementY: false, // Y축 이동 허용
+ originX: 'center',
+ originY: 'center',
+ })
+
+ canvas.setActiveObject(selection)
+
+ addCanvasMouseEventListener('mouse:up', (e) => {
+ isDragging = false
+ canvas.selection = true
+
+ canvas.discardActiveObject() // 모든 선택 해제
+ canvas.requestRenderAll() // 화면 업데이트
+
+ selection.getObjects().forEach((obj) => {
+ obj.set({
+ lockMovementX: true,
+ lockMovementY: true,
+ })
+ obj.setCoords()
+
+ if (obj.type === 'group') {
+ reGroupObject(obj)
+ }
+ })
+
+ canvas.renderAll()
+ roof.fire('polygonMoved')
+ if (roof.type === 'group') reGroupObject(obj)
+ drawDirectionArrow(roof)
+ initEvent()
+ })
+ }
+ }
+
+ const reGroupObject = (groupObj) => {
+ groupObj._restoreObjectsState() //이건 실행만 되도 그룹이 변경됨
+ const reGroupObjects = []
+
+ groupObj._objects.forEach((obj) => {
+ const newObj = new QPolygon(obj.getCurrentPoints(), {
+ ...obj,
+ points: obj.getCurrentPoints(),
+ scaleX: 1,
+ scaleY: 1,
+ })
+ reGroupObjects.push(newObj)
+ canvas.remove(obj)
+
+ if (obj.direction) {
+ drawDirectionArrow(obj)
+ }
+ })
+
+ const reGroup = new fabric.Group(reGroupObjects, {
+ subTargetCheck: true,
+ name: groupObj.name,
+ id: groupObj.id,
+ groupYn: true,
+ parentId: groupObj.parentId,
+ })
+ canvas?.add(reGroup)
+ canvas?.remove(groupObj)
+ }
+
return {
applySurfaceShape,
deleteAllSurfacesAndObjects,
+ moveSurfaceShapeBatch,
}
}
diff --git a/src/hooks/useContextMenu.js b/src/hooks/useContextMenu.js
index f2ad1a65..64892dce 100644
--- a/src/hooks/useContextMenu.js
+++ b/src/hooks/useContextMenu.js
@@ -33,6 +33,7 @@ import RowRemove from '@/components/floor-plan/modal/module/row/RowRemove'
import RowInsert from '@/components/floor-plan/modal/module/row/RowInsert'
import CircuitNumberEdit from '@/components/floor-plan/modal/module/CircuitNumberEdit'
import { useObjectBatch } from '@/hooks/object/useObjectBatch'
+import { useSurfaceShapeBatch } from '@/hooks/surface/useSurfaceShapeBatch'
export function useContextMenu() {
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
@@ -50,7 +51,7 @@ export function useContextMenu() {
const [column, setColumn] = useState(null)
const { handleZoomClear } = useCanvasEvent()
const { moveObjectBatch } = useObjectBatch({})
-
+ const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
const currentMenuSetting = () => {
switch (currentMenu) {
case MENU.PLAN_DRAWING:
@@ -256,6 +257,7 @@ export function useContextMenu() {
}, [currentContextMenu])
useEffect(() => {
+ console.log('currentObject', currentObject)
if (currentObject?.name) {
switch (currentObject.name) {
case 'triangleDormer':
@@ -293,7 +295,7 @@ export function useContextMenu() {
{
id: 'dormerOffset',
name: getMessage('contextmenu.dormer.offset'),
- component: ,
+ component: ,
},
],
])
@@ -304,22 +306,25 @@ export function useContextMenu() {
{
id: 'sizeEdit',
name: '사이즈 변경',
- component: ,
+ 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(),
},
],
[
@@ -370,6 +375,7 @@ export function useContextMenu() {
{
id: 'openingOffset',
name: getMessage('contextmenu.opening.offset'),
+ component: ,
},
],
])
diff --git a/src/hooks/usePlan.js b/src/hooks/usePlan.js
index bddebc63..d1887f6f 100644
--- a/src/hooks/usePlan.js
+++ b/src/hooks/usePlan.js
@@ -77,11 +77,9 @@ export function usePlan() {
})
//디렉션이 있는 경우에만
- if (group.lineDirection) {
- obj.set({
- lineDirection: group.lineDirection,
- })
- }
+ if (group.lineDirection) obj.set({ lineDirection: group.lineDirection })
+ //부모객체가 있으면 (면형상 위에 도머등..)
+ if (group.parentId) obj.set({ parentId: group.parentId })
canvas?.add(obj)
obj.setCoords()
|