Merge branch 'dev' into dev-yj
# Conflicts: # src/components/floor-plan/modal/module/PanelEdit.jsx
This commit is contained in:
commit
b0dbdda29b
File diff suppressed because one or more lines are too long
@ -1,32 +1,28 @@
|
||||
'use client'
|
||||
|
||||
import { useRef, useState, useEffect, useContext } from 'react'
|
||||
import Image from 'next/image'
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { FaAnglesUp } from 'react-icons/fa6'
|
||||
import { FaAnglesDown } from 'react-icons/fa6'
|
||||
import { Button } from '@nextui-org/react'
|
||||
import ColorPicker from './common/color-picker/ColorPicker'
|
||||
import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom'
|
||||
|
||||
import { useAxios } from '@/hooks/useAxios'
|
||||
import { useMessage } from '@/hooks/useMessage'
|
||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||
import { convertDwgToPng } from '@/lib/cadAction'
|
||||
import { cadFileNameState, googleMapFileNameState, useCadFileState, useGoogleMapFileState } from '@/store/canvasAtom'
|
||||
|
||||
import { Button } from '@nextui-org/react'
|
||||
import ColorPicker from './common/color-picker/ColorPicker'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
|
||||
import styles from './playground.module.css'
|
||||
import Image from 'next/image'
|
||||
|
||||
import { convertDwgToPng } from '@/lib/cadAction'
|
||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||
import QInput from './common/input/Qinput'
|
||||
import QSelect from './common/select/QSelect'
|
||||
import QPagination from './common/pagination/QPagination'
|
||||
|
||||
import { trestleRequestModels, constructionRequestModels, trestleDetailRequestModels } from '@/models/apiModels'
|
||||
import QSelectBox from './common/select/QSelectBox'
|
||||
import SampleReducer from './sample/SampleReducer'
|
||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||
|
||||
import styles from './playground.module.css'
|
||||
|
||||
export default function Playground() {
|
||||
const [useCadFile, setUseCadFile] = useRecoilState(useCadFileState)
|
||||
|
||||
@ -66,7 +66,7 @@ export default function ColorPickerModal(props) {
|
||||
|
||||
//치수선색설정 아닐 때만 바로 저장 실행
|
||||
if (name !== 'DimensionLineColor')
|
||||
setSettingsData({
|
||||
setSettingsDataSave({
|
||||
...settingsData,
|
||||
color: originColor,
|
||||
})
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
'use client'
|
||||
import { Fragment } from 'react'
|
||||
import { useRecoilValue } from 'recoil'
|
||||
import { popupState } from '@/store/popupAtom'
|
||||
import { Fragment } from 'react'
|
||||
|
||||
/**
|
||||
* 팝업 관리자
|
||||
*/
|
||||
export default function PopupManager() {
|
||||
const popup = useRecoilValue(popupState)
|
||||
|
||||
|
||||
@ -40,100 +40,44 @@ export default function PanelEdit(props) {
|
||||
|
||||
//모듈 이동 적용
|
||||
const handleApply = () => {
|
||||
// const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
||||
if (type === PANEL_EDIT_TYPE.MOVE) {
|
||||
moduleMove(length, direction)
|
||||
} else if (type === PANEL_EDIT_TYPE.COPY) {
|
||||
moduleCopy(length, direction)
|
||||
} else if (type === PANEL_EDIT_TYPE.COLUMN_MOVE) {
|
||||
moduleMultiMove('column', length, direction)
|
||||
} else if (type === PANEL_EDIT_TYPE.COLUMN_COPY) {
|
||||
moduleMultiCopy('column', length, direction)
|
||||
} else if (type === PANEL_EDIT_TYPE.ROW_MOVE) {
|
||||
moduleMultiMove('row', length, direction)
|
||||
} else if (type === PANEL_EDIT_TYPE.ROW_COPY) {
|
||||
moduleMultiCopy('row', length, direction)
|
||||
switch (type) {
|
||||
case PANEL_EDIT_TYPE.MOVE:
|
||||
moduleMove(length, direction)
|
||||
break
|
||||
case PANEL_EDIT_TYPE.COPY:
|
||||
moduleCopy(length, direction)
|
||||
break
|
||||
case PANEL_EDIT_TYPE.COLUMN_MOVE:
|
||||
moduleMultiMove('column', length, direction)
|
||||
break
|
||||
case PANEL_EDIT_TYPE.COLUMN_COPY:
|
||||
moduleMultiCopy('column', length, direction)
|
||||
break
|
||||
case PANEL_EDIT_TYPE.ROW_MOVE:
|
||||
moduleMultiMove('row', length, direction)
|
||||
break
|
||||
case PANEL_EDIT_TYPE.ROW_COPY:
|
||||
moduleMultiCopy('row', length, direction)
|
||||
break
|
||||
}
|
||||
closePopup(id)
|
||||
}
|
||||
|
||||
const contextModuleMove = (length, direction) => {
|
||||
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||
|
||||
canvas.discardActiveObject() //선택해제
|
||||
|
||||
const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module' && !selectedIds.includes(obj.id)) // selectedObj에 없는 객체만 필터링
|
||||
const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
|
||||
const setupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0]
|
||||
const isOverlapArray = []
|
||||
const isInSurfaceArray = []
|
||||
|
||||
if (selectedModules) {
|
||||
canvas.remove(...selectedModules) //지워야 겹치는지 확인 가능
|
||||
|
||||
selectedModules.forEach((module) => {
|
||||
module.set({
|
||||
originCoords: {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
},
|
||||
})
|
||||
|
||||
if (direction === 'up') {
|
||||
module.set({ ...module, top: module.top - Number(length) })
|
||||
} else if (direction === 'down') {
|
||||
module.set({ ...module, top: module.top + Number(length) })
|
||||
} else if (direction === 'left') {
|
||||
module.set({ ...module, left: module.left - Number(length) })
|
||||
} else if (direction === 'right') {
|
||||
module.set({ ...module, left: module.left + Number(length) })
|
||||
}
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
|
||||
//다른 모듈과 겹치는지 확인하는 로직
|
||||
const isOverlap = isSetupModules.some((isSetupModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(isSetupModule, true)),
|
||||
)
|
||||
isOverlapArray.push(isOverlap)
|
||||
|
||||
//나갔는지 확인하는 로직
|
||||
const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
|
||||
const turfModule = polygonToTurfPolygon(module, true)
|
||||
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
|
||||
isInSurfaceArray.push(isInSurface)
|
||||
})
|
||||
|
||||
const isNotOverlap = isOverlapArray.some((isOverlap) => isOverlap) // true면 겹침
|
||||
const isNotOutSurface = isInSurfaceArray.every((isOutSurface) => isOutSurface) //false면 밖으로 나감
|
||||
|
||||
//안겹치고 안나갔으면 이동시킨다 아니면 원래 위치로 돌려놓는다
|
||||
if (isNotOverlap || !isNotOutSurface) {
|
||||
selectedModules.forEach((module) => {
|
||||
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
||||
module.setCoords()
|
||||
})
|
||||
}
|
||||
|
||||
canvas.add(...selectedModules)
|
||||
canvas.renderAll()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<WithDraggable isShow={true} pos={pos}>
|
||||
<div className={`modal-pop-wrap xm mount`}>
|
||||
<div className="modal-head">
|
||||
<h1 className="title">{getMessage(type === 'move' ? 'modal.move.setting' : 'modal.copy.setting')} </h1>
|
||||
<h1 className="title">
|
||||
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting' : 'modal.copy.setting')}{' '}
|
||||
</h1>
|
||||
<button className="modal-close" onClick={() => closePopup(id)}>
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
<div className="modal-body">
|
||||
<div className="grid-option-tit">{getMessage(type === 'move' ? 'modal.move.setting.info' : 'modal.copy.setting.info')}</div>
|
||||
<div className="grid-option-tit">
|
||||
{getMessage([PANEL_EDIT_TYPE.MOVE, PANEL_EDIT_TYPE.COLUMN_MOVE].includes(type) ? 'modal.move.setting.info' : 'modal.copy.setting.info')}
|
||||
</div>
|
||||
<div className="grid-option-wrap">
|
||||
<div className="grid-option-box">
|
||||
<div className="grid-input-form">
|
||||
|
||||
@ -30,7 +30,8 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
const globalLocale = useRecoilValue(globalLocaleStore)
|
||||
const { basicSetting, setBasicSettings, fetchBasicSettings, basicSettingSave, addedRoofs, setAddedRoofs } = useCanvasSetting()
|
||||
const { findCommonCode } = useCommonCode()
|
||||
const [raftCodes, setRaftCodes] = useState([]) //서까래 정보
|
||||
const [raftCodes, setRaftCodes] = useState([]) // 서까래 정보
|
||||
const [currentRoof, setCurrentRoof] = useState(addedRoofs[0]) // 현재 선택된 지붕재 정보
|
||||
|
||||
const roofRef = {
|
||||
roofCd: useRef(null),
|
||||
@ -42,70 +43,61 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
|
||||
// 데이터를 최초 한 번만 조회
|
||||
useEffect(() => {
|
||||
fetchBasicSettings()
|
||||
//fetchBasicSettings()
|
||||
const raftCodeList = findCommonCode('203800')
|
||||
setRaftCodes(raftCodeList)
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (addedRoofs.length > 0) {
|
||||
if (currentRoof.roofMatlCd.length > 0) {
|
||||
setBasicSettings({
|
||||
...basicSetting,
|
||||
roofsData: {
|
||||
roofApply: true,
|
||||
roofSeq: 0,
|
||||
roofMatlCd: addedRoofs[0].roofMatlCd,
|
||||
roofWidth: addedRoofs[0].width,
|
||||
roofHeight: addedRoofs[0].length,
|
||||
roofHajebichi: addedRoofs[0].hajebichi,
|
||||
roofGap: addedRoofs[0].raft,
|
||||
roofLayout: addedRoofs[0].layout,
|
||||
roofMatlCd: currentRoof.roofMatlCd,
|
||||
roofWidth: currentRoof.width,
|
||||
roofHeight: currentRoof.length,
|
||||
roofHajebichi: currentRoof.hajebichi,
|
||||
roofGap: currentRoof.raft,
|
||||
roofLayout: currentRoof.layout,
|
||||
},
|
||||
})
|
||||
}
|
||||
}, [basicSetting.roofSizeSet, basicSetting.roofAngleSet, addedRoofs])
|
||||
|
||||
const changeInput = (value, e) => {
|
||||
const { name } = e.target
|
||||
setAddedRoofs(addedRoofs.map((roof) => ({
|
||||
...roof,
|
||||
[name]: Number(value),
|
||||
})))
|
||||
}
|
||||
}, [basicSetting.roofSizeSet, basicSetting.roofAngleSet, currentRoof])
|
||||
|
||||
// Function to update the roofType and corresponding values
|
||||
const handleRoofTypeChange = (value) => {
|
||||
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value)
|
||||
setAddedRoofs([selectedRoofMaterial])
|
||||
setCurrentRoof({...selectedRoofMaterial, index: 0})
|
||||
}
|
||||
|
||||
const changeInput = (value, e) => {
|
||||
const { name } = e.target
|
||||
setCurrentRoof({...currentRoof, [name]: Number(value)})
|
||||
}
|
||||
|
||||
const handleRafterChange = (value) => {
|
||||
setAddedRoofs(addedRoofs.map((roof) => ({
|
||||
...roof,
|
||||
raft: value,
|
||||
})))
|
||||
setCurrentRoof({...currentRoof, raft: value})
|
||||
}
|
||||
|
||||
const handleRoofLayoutChange = (value) => {
|
||||
setAddedRoofs(addedRoofs.map((roof) => ({
|
||||
...roof,
|
||||
layout: value,
|
||||
})))
|
||||
setCurrentRoof({...currentRoof, layout: value})
|
||||
}
|
||||
|
||||
const handleSaveBtn = () => {
|
||||
const roofInfo = {
|
||||
...addedRoofs,
|
||||
...currentRoof,
|
||||
roofCd: roofRef.roofCd.current?.value,
|
||||
width: roofRef.width.current?.value,
|
||||
length: roofRef.length.current?.value,
|
||||
hajebichi: roofRef.hajebichi.current?.value,
|
||||
//raft: roofRef.rafter.current?.value,
|
||||
raft: roofRef.rafter.current?.value,
|
||||
selected: true,
|
||||
layout: addedRoofs[0].layout,
|
||||
layout: currentRoof.layout,
|
||||
index: 0,
|
||||
}
|
||||
|
||||
|
||||
const newAddedRoofs = [...addedRoofs]
|
||||
if (addedRoofs.length === 1) {
|
||||
newAddedRoofs[0] = { ...roofInfo }
|
||||
@ -130,12 +122,12 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
roofsData: {
|
||||
roofApply: true,
|
||||
roofSeq: 0,
|
||||
roofMatlCd: addedRoofs[0].roofMatlCd,
|
||||
roofWidth: addedRoofs[0].width,
|
||||
roofHeight: addedRoofs[0].length,
|
||||
roofHajebichi: addedRoofs[0].hajebichi,
|
||||
roofGap: addedRoofs[0].raft,
|
||||
roofLayout: addedRoofs[0].layout,
|
||||
roofMatlCd: currentRoof.roofMatlCd,
|
||||
roofWidth: currentRoof.width,
|
||||
roofHeight: currentRoof.length,
|
||||
roofHajebichi: currentRoof.hajebichi,
|
||||
roofGap: currentRoof.raft,
|
||||
roofLayout: currentRoof.layout,
|
||||
},
|
||||
})
|
||||
|
||||
@ -248,14 +240,14 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
<div className="placement-option">
|
||||
<div className="grid-select no-flx" style={{ width: '171px' }}>
|
||||
<QSelectBox
|
||||
title={basicSetting.roofSizeSet == 3 ? getMessage('modal.placement.initial.setting.size.none.pitch') : addedRoofs[0]?.roofMatlNm}
|
||||
title={basicSetting.roofSizeSet == 3 ? getMessage('modal.placement.initial.setting.size.none.pitch') : currentRoof.roofMatlNm}
|
||||
ref={roofRef.roofCd}
|
||||
options={roofMaterials.map((roof, index) => {
|
||||
return { ...roof, name: globalLocale === 'ko' ? roof.roofMatlNm : roof.roofMatlNmJp }
|
||||
})}
|
||||
//value={roofMaterials.find((r) => r.roofMatlCd === basicSetting.roofs[0]?.roofMatlCd)}
|
||||
//title={basicSetting.roofs[0]?.roofMatlNm}
|
||||
value={basicSetting.roofSizeSet == 3 ? null : addedRoofs[0]?.roofMatlCd}
|
||||
value={basicSetting.roofSizeSet == 3 ? null : currentRoof.roofMatlCd}
|
||||
onChange={(e) => handleRoofTypeChange(e.roofMatlCd)}
|
||||
//sourceKey="id"
|
||||
//targetKey="id"
|
||||
@ -280,7 +272,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
})}
|
||||
</select> */}
|
||||
</div>
|
||||
{basicSetting && ['R', 'C'].includes(addedRoofs[0]?.widAuth) && (
|
||||
{basicSetting && ['R', 'C'].includes(currentRoof.widAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>W</span>
|
||||
<div className="input-grid" style={{ width: '84px' }}>
|
||||
@ -289,9 +281,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
className="input-origin block"
|
||||
name={`width`}
|
||||
ref={roofRef.width}
|
||||
value={parseInt(addedRoofs[0]?.width)}
|
||||
value={parseInt(currentRoof.width)}
|
||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||
readOnly={addedRoofs[0]?.widAuth === 'R'}
|
||||
readOnly={currentRoof.widAuth === 'R'}
|
||||
disabled={basicSetting.roofSizeSet == 3}
|
||||
/>
|
||||
</div>
|
||||
@ -305,7 +297,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
</div> */}
|
||||
</div>
|
||||
)}
|
||||
{basicSetting && ['R', 'C'].includes(addedRoofs[0]?.lenAuth) && (
|
||||
{basicSetting && ['R', 'C'].includes(currentRoof.lenAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>L</span>
|
||||
<div className="input-grid" style={{ width: '84px' }}>
|
||||
@ -314,9 +306,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
className="input-origin block"
|
||||
name={`length`}
|
||||
ref={roofRef.length}
|
||||
value={parseInt(addedRoofs[0]?.length)}
|
||||
value={parseInt(currentRoof.length)}
|
||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||
readOnly={addedRoofs[0]?.lenAuth === 'R'}
|
||||
readOnly={currentRoof.lenAuth === 'R'}
|
||||
disabled={basicSetting.roofSizeSet == 3}
|
||||
/>
|
||||
</div>
|
||||
@ -330,18 +322,19 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
</div> */}
|
||||
</div>
|
||||
)}
|
||||
{basicSetting && ['C', 'R'].includes(addedRoofs[0]?.raftAuth) && (
|
||||
{basicSetting && ['C', 'R'].includes(currentRoof.raftAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('modal.placement.initial.setting.rafter')}</span>
|
||||
{raftCodes.length > 0 && (
|
||||
<div className="select-wrap" style={{ width: '160px' }}>
|
||||
<QSelectBox
|
||||
options={raftCodes}
|
||||
title={raftCodes.find((r) => r.clCode === (addedRoofs[0]?.raft === undefined ? addedRoofs[0]?.raftBaseCd : addedRoofs[0]?.raft))?.clCodeNm}
|
||||
value={addedRoofs[0]?.raft === undefined ? addedRoofs[0]?.raftBaseCd : addedRoofs[0]?.raft}
|
||||
options={raftCodes}
|
||||
ref={roofRef.rafter}
|
||||
title={raftCodes.find((r) => r.clCode === (currentRoof.raft === undefined ? currentRoof.raftBaseCd : currentRoof.raft)).clCodeNm}
|
||||
value={currentRoof.raft === undefined ? currentRoof.raftBaseCd : currentRoof.raft}
|
||||
onChange={(e) => handleRafterChange(e.clCode)}
|
||||
sourceKey="clCode"
|
||||
targetKey={addedRoofs[0]?.raft ? 'raft' : 'raftBaseCd'}
|
||||
targetKey={currentRoof.raft ? 'raft' : 'raftBaseCd'}
|
||||
showKey="clCodeNm"
|
||||
disabled={basicSetting.roofSizeSet == 3}
|
||||
/>
|
||||
@ -358,7 +351,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{basicSetting && ['C', 'R'].includes(addedRoofs[0]?.roofPchAuth) && (
|
||||
{basicSetting && ['C', 'R'].includes(currentRoof.roofPchAuth) && (
|
||||
<div className="flex-ment">
|
||||
<span>{getMessage('hajebichi')}</span>
|
||||
<div className="input-grid" style={{ width: '84px' }}>
|
||||
@ -367,9 +360,9 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
className="input-origin block"
|
||||
name={`hajebichi`}
|
||||
ref={roofRef.hajebichi}
|
||||
value={parseInt(addedRoofs[0]?.hajebichi)}
|
||||
value={parseInt(currentRoof.hajebichi)}
|
||||
onChange={(e) => onlyNumberInputChange(e, changeInput)}
|
||||
readOnly={addedRoofs[0]?.roofPchAuth === 'R'}
|
||||
readOnly={currentRoof.roofPchAuth === 'R'}
|
||||
disabled={basicSetting.roofSizeSet == 3}
|
||||
/>
|
||||
</div>
|
||||
@ -379,7 +372,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
<div className="placement-roof-btn-wrap">
|
||||
<div className="icon-btn-wrap mt10">
|
||||
<button
|
||||
className={`${addedRoofs[0]?.layout === ROOF_MATERIAL_LAYOUT.PARALLEL && 'act'}`}
|
||||
className={`${currentRoof.layout === ROOF_MATERIAL_LAYOUT.PARALLEL && 'act'}`}
|
||||
value={ROOF_MATERIAL_LAYOUT.PARALLEL}
|
||||
onClick={() => handleRoofLayoutChange(ROOF_MATERIAL_LAYOUT.PARALLEL)}
|
||||
>
|
||||
@ -387,7 +380,7 @@ export default function PlacementShapeSetting({ id, pos = { x: 50, y: 180 }, set
|
||||
<i className="allocation01"></i>
|
||||
</button>
|
||||
<button
|
||||
className={`${addedRoofs[0]?.layout === ROOF_MATERIAL_LAYOUT.STAIRS && 'act'}`}
|
||||
className={`${currentRoof.layout === ROOF_MATERIAL_LAYOUT.STAIRS && 'act'}`}
|
||||
value={ROOF_MATERIAL_LAYOUT.STAIRS}
|
||||
onClick={() => handleRoofLayoutChange(ROOF_MATERIAL_LAYOUT.STAIRS)}
|
||||
>
|
||||
|
||||
@ -28,11 +28,7 @@ export function useGrid() {
|
||||
// 1. 점.선 그리드 설정으로 만들어진 기존 오브젝트 제거
|
||||
canvas
|
||||
?.getObjects()
|
||||
.filter((obj) => obj.name === 'lineGrid')
|
||||
.forEach((obj) => canvas?.remove(obj))
|
||||
canvas
|
||||
?.getObjects()
|
||||
.filter((obj) => obj.name === 'dotGrid')
|
||||
.filter((obj) => ['lineGrid', 'dotGrid'].includes(obj.name))
|
||||
.forEach((obj) => canvas?.remove(obj))
|
||||
|
||||
//const horizontalInterval = interval.horizontalInterval
|
||||
@ -181,8 +177,17 @@ export function useGrid() {
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const removeGrid = () => {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => ['lineGrid', 'dotGrid', 'tempGrid'].includes(obj.name))
|
||||
.forEach((obj) => canvas.remove(obj))
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
return {
|
||||
move,
|
||||
copy,
|
||||
removeGrid,
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,8 @@ import { useRecoilValue } from 'recoil'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import * as turf from '@turf/turf'
|
||||
import { useSwal } from '../useSwal'
|
||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
||||
import { useMessage } from '../useMessage'
|
||||
|
||||
export const MODULE_REMOVE_TYPE = {
|
||||
LEFT: 'left',
|
||||
@ -25,92 +25,62 @@ export const MODULE_INSERT_TYPE = {
|
||||
BOTTOM: 'down',
|
||||
}
|
||||
|
||||
export const MODULE_ALIGN_TYPE = {
|
||||
TOP: 'top',
|
||||
}
|
||||
|
||||
export function useModule() {
|
||||
const canvas = useRecoilValue(canvasState)
|
||||
const { swalFire } = useSwal()
|
||||
const { getMessage } = useMessage()
|
||||
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
||||
|
||||
const moduleMove = (length, direction) => {
|
||||
const checkModuleDisjointSurface = (squarePolygon, turfModuleSetupSurface) => {
|
||||
return turf.booleanContains(turfModuleSetupSurface, squarePolygon) || turf.booleanWithin(squarePolygon, turfModuleSetupSurface)
|
||||
}
|
||||
|
||||
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
||||
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
||||
|
||||
canvas.discardActiveObject() //선택해제
|
||||
|
||||
const isSetupModules = canvas.getObjects().filter((obj) => obj.name === 'module' && !selectedIds.includes(obj.id)) // selectedObj에 없는 객체만 필터링
|
||||
const isSetupModules = getOtherModules(selectedObj)
|
||||
const selectedModules = canvas.getObjects().filter((obj) => selectedIds.includes(obj.id) && obj.name === 'module') //선택했던 객체들만 가져옴
|
||||
const setupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === selectedModules[0].surfaceId)[0]
|
||||
const isOverlapArray = []
|
||||
const isInSurfaceArray = []
|
||||
const isOverlapObjects = []
|
||||
let isWarning = false
|
||||
const objects = getObjects()
|
||||
|
||||
if (selectedModules) {
|
||||
canvas.remove(...selectedModules)
|
||||
selectedModules.forEach((module) => {
|
||||
module.set({
|
||||
originCoords: {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
},
|
||||
})
|
||||
|
||||
if (direction === 'up') {
|
||||
module.set({ ...module, top: module.top - Number(length) })
|
||||
} else if (direction === 'down') {
|
||||
module.set({ ...module, top: module.top + Number(length) })
|
||||
} else if (direction === 'left') {
|
||||
module.set({ ...module, left: module.left - Number(length) })
|
||||
} else if (direction === 'right') {
|
||||
module.set({ ...module, left: module.left + Number(length) })
|
||||
const { top, left } = getPosotion(module, direction, length, false)
|
||||
module.originCoords = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
module.set({ top, left })
|
||||
module.setCoords()
|
||||
|
||||
if (isOverlapOtherModules(module, isSetupModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, setupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
canvas.renderAll()
|
||||
|
||||
//다른 모듈과 겹치는지 확인하는 로직
|
||||
const isOverlap = isSetupModules.some((isSetupModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(isSetupModule, true)),
|
||||
)
|
||||
isOverlapArray.push(isOverlap)
|
||||
|
||||
const turfModuleSetupSurface = polygonToTurfPolygon(setupSurface, true)
|
||||
const turfModule = polygonToTurfPolygon(module, true)
|
||||
|
||||
//나갔는지 확인하는 로직
|
||||
const isInSurface = turf.booleanContains(turfModuleSetupSurface, turfModule) || turf.booleanWithin(turfModule, turfModuleSetupSurface)
|
||||
isInSurfaceArray.push(isInSurface)
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
})
|
||||
|
||||
const isNotOverlap = isOverlapArray.some((isOverlap) => isOverlap) // true면 겹침
|
||||
const isNotOutSurface = isInSurfaceArray.every((isOutSurface) => isOutSurface) //false면 밖으로 나감
|
||||
|
||||
//안겹치고 안나갔으면 이동시킨다 아니면 원래 위치로 돌려놓는다
|
||||
if (isNotOverlap || !isNotOutSurface || isOverlapObjects.some((isOverlap) => isOverlap)) {
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isNotOverlap
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.move.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
selectedModules.forEach((module) => {
|
||||
module.set({ ...module, left: module.originCoords.left, top: module.originCoords.top })
|
||||
module.set({ left: module.originCoords.left, top: module.originCoords.top, fill: module.originCoords.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
canvas.add(...selectedModules)
|
||||
canvas.renderAll()
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,47 +93,55 @@ export function useModule() {
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
let copyModules = []
|
||||
let copyModule = null
|
||||
canvas.discardActiveObject() //선택해제
|
||||
modules.forEach((module) => {
|
||||
const { top, left } = getPosotion(module, direction, length, true)
|
||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||
const rect = new QPolygon(module.points, moduleOptions)
|
||||
canvas.add(rect)
|
||||
rect.setCoords()
|
||||
canvas.renderAll()
|
||||
|
||||
isOverlapOtherModules.push(
|
||||
otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
||||
),
|
||||
)
|
||||
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(rect, true), objects))
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
module.clone((obj) => {
|
||||
obj.set({
|
||||
parentId: module.parentId,
|
||||
initOptions: module.initOptions,
|
||||
direction: module.direction,
|
||||
arrow: module.arrow,
|
||||
name: module.name,
|
||||
type: module.type,
|
||||
length: module.length,
|
||||
points: module.points,
|
||||
surfaceId: module.surfaceId,
|
||||
left,
|
||||
top,
|
||||
id: uuidv4(),
|
||||
})
|
||||
copyModules.push(obj)
|
||||
copyModule = obj
|
||||
canvas.add(obj)
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
if (
|
||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
isOverlapOtherModules(copyModule, otherModules) ||
|
||||
isOverlapObjects(copyModule, objects) ||
|
||||
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||
) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules ? '겹치는 모듈이 있습니다.' : isOutsideSurface ? '모듈이 오브젝트와 겹칩니다.' : '영역 밖',
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
confirmFn: () => {
|
||||
canvas.remove(rect)
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
isWarning = true
|
||||
copyModule.set({ fill: 'red' })
|
||||
canvas.renderAll()
|
||||
}
|
||||
})
|
||||
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: getMessage('can.not.copy.module'),
|
||||
icon: 'error',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
canvas.remove(...copyModules)
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const moduleMultiMove = (type, length, direction) => {
|
||||
@ -181,18 +159,17 @@ export function useModule() {
|
||||
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||
const otherModules = getOtherModules(modules)
|
||||
const objects = getObjects()
|
||||
console.log('🚀 ~ moduleMultiMove ~ objects:', objects)
|
||||
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
|
||||
modules.forEach((module) => {
|
||||
const { top, left } = getPosotion(module, direction, length, false)
|
||||
module.originPos = {
|
||||
top: module.top,
|
||||
left: module.left,
|
||||
fill: module.fill,
|
||||
}
|
||||
|
||||
module.set({ top, left })
|
||||
@ -200,41 +177,22 @@ export function useModule() {
|
||||
canvas.renderAll()
|
||||
|
||||
if (otherModules.length > 0) {
|
||||
isOverlapOtherModules.push(
|
||||
otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||
),
|
||||
)
|
||||
if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
}
|
||||
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
})
|
||||
|
||||
if (
|
||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)
|
||||
) {
|
||||
canvas.renderAll()
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.move.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
modules.forEach((module) => {
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
@ -258,11 +216,12 @@ export function useModule() {
|
||||
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
||||
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
||||
const objects = getObjects()
|
||||
const copyRects = []
|
||||
const copyModules = []
|
||||
let copyModule = null
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
let moduleLength = 0
|
||||
if (['up', 'down'].includes(direction)) {
|
||||
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
||||
@ -272,52 +231,47 @@ export function useModule() {
|
||||
|
||||
modules.forEach((module) => {
|
||||
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||
const rect = new QPolygon(module.getCurrentPoints(), moduleOptions)
|
||||
canvas.add(rect)
|
||||
copyRects.push(rect)
|
||||
module.setCoords()
|
||||
|
||||
if (otherModules.length > 0) {
|
||||
isOverlapOtherModules.push(
|
||||
otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(otherModule, true)),
|
||||
),
|
||||
)
|
||||
module.clone((obj) => {
|
||||
obj.set({
|
||||
parentId: module.parentId,
|
||||
initOptions: module.initOptions,
|
||||
direction: module.direction,
|
||||
arrow: module.arrow,
|
||||
name: module.name,
|
||||
type: module.type,
|
||||
length: module.length,
|
||||
points: module.points,
|
||||
surfaceId: module.surfaceId,
|
||||
left,
|
||||
top,
|
||||
id: uuidv4(),
|
||||
})
|
||||
copyModule = obj
|
||||
canvas.add(obj)
|
||||
copyModules.push(obj)
|
||||
obj.setCoords()
|
||||
})
|
||||
if (
|
||||
isOverlapOtherModules(copyModule, otherModules) ||
|
||||
isOverlapObjects(copyModule, objects) ||
|
||||
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||
) {
|
||||
isWarning = true
|
||||
copyModule.set({ fill: 'red' })
|
||||
}
|
||||
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(rect, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(rect, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
if (
|
||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)
|
||||
) {
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.copy.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
canvas.remove(...copyRects)
|
||||
canvas.remove(...copyModules)
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
} else {
|
||||
canvas.renderAll()
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +287,7 @@ export function useModule() {
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
canvas.discardActiveObject()
|
||||
canvas.remove(...columnModules)
|
||||
canvas.renderAll()
|
||||
@ -343,30 +297,36 @@ export function useModule() {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (width === -1) width = module.left - activeModule.left
|
||||
module.set({ left: module.left - width })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, leftModules))
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
if (isOverlapOtherModules(module, leftModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
module.set({ fill: 'red' })
|
||||
isWarning = true
|
||||
}
|
||||
})
|
||||
canvas.renderAll()
|
||||
targetModules = rightModules
|
||||
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
||||
leftModules.forEach((module) => {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (width === -1) width = activeModule.left - module.left
|
||||
module.set({ left: module.left + width })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, rightModules))
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
if (isOverlapOtherModules(module, rightModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
module.set({ fill: 'red' })
|
||||
isWarning = true
|
||||
}
|
||||
})
|
||||
canvas.renderAll()
|
||||
targetModules = leftModules
|
||||
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
||||
const sideModules = [...leftModules, ...rightModules]
|
||||
@ -374,6 +334,7 @@ export function useModule() {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (width === -1) width = activeModule.left - module.left
|
||||
module.set({ left: module.left + width / 2 })
|
||||
@ -385,50 +346,46 @@ export function useModule() {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (width === -1) width = module.left - activeModule.left
|
||||
module.set({ left: module.left - width / 2 })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
})
|
||||
canvas.renderAll()
|
||||
|
||||
sideModules.forEach((module) => {
|
||||
isOverlapOtherModules.push(
|
||||
getIsOverlapOtherModules(
|
||||
if (
|
||||
isOverlapOtherModules(
|
||||
module,
|
||||
sideModules.filter((m) => m.id !== module.id),
|
||||
),
|
||||
)
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
) ||
|
||||
isOverlapObjects(module, objects) ||
|
||||
isOutsideSurface(module, moduleSetupSurface)
|
||||
) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
})
|
||||
|
||||
targetModules = sideModules
|
||||
}
|
||||
if (
|
||||
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)) &&
|
||||
type !== MODULE_REMOVE_TYPE.NONE
|
||||
) {
|
||||
canvas.renderAll()
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.remove.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
canvas.add(...columnModules)
|
||||
targetModules.forEach((module) => {
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
}
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const moduleRowRemove = (type) => {
|
||||
@ -443,7 +400,7 @@ export function useModule() {
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
|
||||
canvas.discardActiveObject()
|
||||
canvas.remove(...rowModules)
|
||||
@ -454,29 +411,34 @@ export function useModule() {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (height === -1) height = module.top - activeModule.top
|
||||
module.set({ top: module.top - height })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, topModules))
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
if (isOverlapOtherModules(module, topModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
})
|
||||
canvas.renderAll()
|
||||
targetModules = bottomModules
|
||||
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
||||
topModules.forEach((module) => {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (height === -1) height = activeModule.top - module.top
|
||||
module.set({ top: module.top + height })
|
||||
module.set({ top: module.top + activeModule.height })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
isOverlapOtherModules.push(getIsOverlapOtherModules(module, bottomModules))
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
if (isOverlapOtherModules(module, bottomModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
})
|
||||
targetModules = topModules
|
||||
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
||||
@ -484,63 +446,60 @@ export function useModule() {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (height === -1) height = activeModule.top - module.top
|
||||
// if (height === -1) height = activeModule.top - module.top
|
||||
if (height === -1) height = activeModule.height
|
||||
module.set({ top: module.top + height / 2 })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
bottomModules.forEach((module) => {
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
if (height === -1) height = module.top - activeModule.top
|
||||
// if (height === -1) height = module.top - activeModule.top
|
||||
if (height === -1) height = activeModule.height
|
||||
module.set({ top: module.top - height / 2 })
|
||||
module.setCoords()
|
||||
canvas.renderAll()
|
||||
})
|
||||
|
||||
const sideModules = [...topModules, ...bottomModules]
|
||||
canvas.renderAll()
|
||||
const sideModules = [...topModules, ...bottomModules]
|
||||
sideModules.forEach((module) => {
|
||||
isOverlapOtherModules.push(
|
||||
getIsOverlapOtherModules(
|
||||
if (
|
||||
isOverlapOtherModules(
|
||||
module,
|
||||
sideModules.filter((m) => m.id !== module.id),
|
||||
),
|
||||
)
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
isOutsideSurface.push(getIsOutsideSurface(module, moduleSetupSurface))
|
||||
) ||
|
||||
isOverlapObjects(module, objects) ||
|
||||
isOutsideSurface(module, moduleSetupSurface)
|
||||
) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
})
|
||||
targetModules = sideModules
|
||||
}
|
||||
|
||||
if (
|
||||
(isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)) &&
|
||||
type !== MODULE_REMOVE_TYPE.NONE
|
||||
) {
|
||||
canvas.renderAll()
|
||||
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
||||
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.remove.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
canvas.add(...rowModules)
|
||||
targetModules.forEach((module) => {
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
}
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const moduleColumnInsert = (type) => {
|
||||
@ -550,14 +509,14 @@ export function useModule() {
|
||||
const targetModules =
|
||||
type === MODULE_INSERT_TYPE.LEFT
|
||||
? otherModules.filter((module) => module.left < activeModule.left).sort((a, b) => a.left - b.left)
|
||||
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => b.left - a.left)
|
||||
: otherModules.filter((module) => module.left > activeModule.left).sort((a, b) => a.left - b.left)
|
||||
const objects = getObjects()
|
||||
const copyModules = []
|
||||
const moduleSetupSurface = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||
let width = -1
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
if (targetModules.length === 0) {
|
||||
swalFire({
|
||||
title: '마지막 모듈입니다.',
|
||||
@ -570,75 +529,68 @@ export function useModule() {
|
||||
targetModules.forEach((module) => {
|
||||
if (width === -1)
|
||||
width = type === MODULE_INSERT_TYPE.LEFT ? Number(activeModule.left) - Number(module.left) : Number(module.left) - Number(activeModule.left)
|
||||
const { top, left } = getPosotion(module, type, width, false)
|
||||
const { top, left } = getPosotion(module, type, module.width, false)
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
module.set({ left, top })
|
||||
canvas.renderAll()
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
otherModules = getOtherModules(columnModules)
|
||||
columnModules.forEach((module) => {
|
||||
const { top, left } = getPosotion(module, type, width, false)
|
||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||
const copyModule = new QPolygon(module.points, moduleOptions)
|
||||
canvas.add(copyModule)
|
||||
copyModules.push(copyModule)
|
||||
const { top, left } = getPosotion(module, type, module.width, false)
|
||||
let copyModule = null
|
||||
module.clone((obj) => {
|
||||
obj.set({
|
||||
parentId: module.parentId,
|
||||
initOptions: module.initOptions,
|
||||
direction: module.direction,
|
||||
arrow: module.arrow,
|
||||
name: module.name,
|
||||
type: module.type,
|
||||
length: module.length,
|
||||
points: module.points,
|
||||
surfaceId: module.surfaceId,
|
||||
left,
|
||||
top,
|
||||
id: uuidv4(),
|
||||
})
|
||||
copyModule = obj
|
||||
canvas.add(obj)
|
||||
copyModules.push(obj)
|
||||
obj.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
|
||||
if (otherModules.length > 0) {
|
||||
isOverlapOtherModules.push(
|
||||
otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
||||
),
|
||||
)
|
||||
if (
|
||||
isOverlapOtherModules(copyModule, otherModules) ||
|
||||
isOverlapObjects(copyModule, objects) ||
|
||||
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||
) {
|
||||
isWarning = true
|
||||
}
|
||||
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
module.setCoords()
|
||||
})
|
||||
|
||||
if (
|
||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)
|
||||
) {
|
||||
canvas.renderAll()
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.insert.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
targetModules.forEach((module) => {
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
copyModules.forEach((module) => {
|
||||
canvas.remove(module)
|
||||
})
|
||||
canvas.remove(...copyModules)
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
@ -646,16 +598,13 @@ export function useModule() {
|
||||
}
|
||||
|
||||
const muduleRowInsert = (type) => {
|
||||
console.log('🚀 ~ muduleRowInsert ~ type:', type)
|
||||
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
||||
const rowModules = getRowModules(activeModule)
|
||||
console.log('🚀 ~ muduleRowInsert ~ rowModules:', rowModules)
|
||||
let otherModules = getOtherModules(rowModules)
|
||||
const targetModules =
|
||||
type === MODULE_INSERT_TYPE.TOP
|
||||
? otherModules.filter((module) => module.top < activeModule.top).sort((a, b) => b.top - a.top)
|
||||
? otherModules.filter((module) => module.top < activeModule.top).sort((a, b) => a.top - b.top)
|
||||
: otherModules.filter((module) => module.top > activeModule.top).sort((a, b) => a.top - b.top)
|
||||
console.log('🚀 ~ muduleRowInsert ~ targetModules:', targetModules)
|
||||
if (targetModules.length === 0) {
|
||||
swalFire({
|
||||
title: '마지막 모듈입니다.',
|
||||
@ -670,86 +619,102 @@ export function useModule() {
|
||||
.getObjects()
|
||||
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
||||
let height = -1
|
||||
let [isOverlapOtherModules, isOverlapObjects, isOutsideSurface] = [[], [], []]
|
||||
let isWarning = false
|
||||
canvas.discardActiveObject()
|
||||
targetModules.forEach((module) => {
|
||||
if (height === -1)
|
||||
height = type === MODULE_INSERT_TYPE.TOP ? Number(activeModule.top) - Number(module.top) : Number(module.top) - Number(activeModule.top)
|
||||
const { top, left } = getPosotion(module, type, height, false)
|
||||
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||
module.originPos = {
|
||||
left: module.left,
|
||||
top: module.top,
|
||||
fill: module.fill,
|
||||
}
|
||||
module.set({ left, top })
|
||||
canvas.renderAll()
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||
isWarning = true
|
||||
module.set({ fill: 'red' })
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
otherModules = getOtherModules(rowModules)
|
||||
rowModules.forEach((module) => {
|
||||
const { top, left } = getPosotion(module, type, height, false)
|
||||
const moduleOptions = { ...module, left, top, id: uuidv4() }
|
||||
const copyModule = new QPolygon(module.points, moduleOptions)
|
||||
canvas.add(copyModule)
|
||||
copyModules.push(copyModule)
|
||||
const { top, left } = getPosotion(module, type, activeModule.height, false)
|
||||
let copyModule = null
|
||||
module.clone((obj) => {
|
||||
obj.set({
|
||||
parentId: module.parentId,
|
||||
initOptions: module.initOptions,
|
||||
direction: module.direction,
|
||||
arrow: module.arrow,
|
||||
name: module.name,
|
||||
type: module.type,
|
||||
length: module.length,
|
||||
points: module.points,
|
||||
surfaceId: module.surfaceId,
|
||||
fill: module.fill,
|
||||
left,
|
||||
top,
|
||||
id: uuidv4(),
|
||||
})
|
||||
copyModule = obj
|
||||
canvas.add(obj)
|
||||
copyModules.push(obj)
|
||||
obj.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
|
||||
if (otherModules.length > 0) {
|
||||
isOverlapOtherModules.push(
|
||||
otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(otherModule, true)),
|
||||
),
|
||||
)
|
||||
if (
|
||||
isOverlapOtherModules(copyModule, otherModules) ||
|
||||
isOverlapObjects(copyModule, objects) ||
|
||||
isOutsideSurface(copyModule, moduleSetupSurface)
|
||||
) {
|
||||
isWarning = true
|
||||
copyModule.set({ fill: 'red' })
|
||||
}
|
||||
|
||||
if (objects.length > 0) {
|
||||
isOverlapObjects.push(!checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects))
|
||||
}
|
||||
|
||||
isOutsideSurface.push(
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(copyModule, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(copyModule, true), polygonToTurfPolygon(moduleSetupSurface, true)),
|
||||
)
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
|
||||
if (
|
||||
isOverlapOtherModules.some((isOverlap) => isOverlap) ||
|
||||
isOverlapObjects.some((isOverlap) => isOverlap) ||
|
||||
isOutsideSurface.some((isOutside) => isOutside)
|
||||
) {
|
||||
if (isWarning) {
|
||||
swalFire({
|
||||
title: isOverlapOtherModules.some((isOverlap) => isOverlap)
|
||||
? '겹치는 모듈이 있습니다.'
|
||||
: isOverlapObjects.some((isOverlap) => isOverlap)
|
||||
? '모듈이 오브젝트와 겹칩니다.'
|
||||
: '영역 밖',
|
||||
title: getMessage('can.not.insert.module'),
|
||||
icon: 'error',
|
||||
type: 'confirm',
|
||||
type: 'alert',
|
||||
confirmFn: () => {
|
||||
targetModules.forEach((module) => {
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left })
|
||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||
module.setCoords()
|
||||
})
|
||||
canvas.renderAll()
|
||||
copyModules.forEach((module) => {
|
||||
canvas.remove(module)
|
||||
})
|
||||
canvas.remove(...copyModules)
|
||||
canvas.renderAll()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const alignModule = (type) => {}
|
||||
|
||||
const isOverlapOtherModules = (module, otherModules) => {
|
||||
return otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||
)
|
||||
}
|
||||
|
||||
const isOverlapObjects = (module, objects) => {
|
||||
return !checkModuleDisjointObjects(polygonToTurfPolygon(module, true), objects)
|
||||
}
|
||||
|
||||
const isOutsideSurface = (module, moduleSetupSurface) => {
|
||||
return (
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
|
||||
)
|
||||
}
|
||||
|
||||
const getRowModules = (target) => {
|
||||
return canvas
|
||||
.getObjects()
|
||||
@ -797,29 +762,6 @@ export function useModule() {
|
||||
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
|
||||
}
|
||||
|
||||
const getIsOverlapOtherModules = (module, otherModules) => {
|
||||
return otherModules.some(
|
||||
(otherModule) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(otherModule, true)),
|
||||
)
|
||||
}
|
||||
|
||||
const getIsOverlapObjects = (module, objects) => {
|
||||
return !objects.some(
|
||||
(object) =>
|
||||
turf.booleanOverlap(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)) ||
|
||||
turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(object, true)),
|
||||
)
|
||||
}
|
||||
|
||||
const getIsOutsideSurface = (module, moduleSetupSurface) => {
|
||||
return (
|
||||
!turf.booleanContains(polygonToTurfPolygon(moduleSetupSurface, true), polygonToTurfPolygon(module, true)) ||
|
||||
!turf.booleanWithin(polygonToTurfPolygon(module, true), polygonToTurfPolygon(moduleSetupSurface, true))
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
moduleMove,
|
||||
moduleMultiMove,
|
||||
|
||||
@ -111,7 +111,7 @@ export function useCanvasSetting() {
|
||||
if (roofMaterials.length !== 0) {
|
||||
return
|
||||
}
|
||||
addRoofMaterials()
|
||||
addRoofMaterials()
|
||||
}, [])
|
||||
|
||||
//지붕재 초기세팅
|
||||
@ -145,6 +145,12 @@ export function useCanvasSetting() {
|
||||
setBasicSettings({ ...basicSetting, selectedRoofMaterial: selectedRoofMaterial })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (roofMaterials) {
|
||||
fetchBasicSettings()
|
||||
}
|
||||
}, [roofMaterials])
|
||||
|
||||
useEffect(() => {
|
||||
if (!canvas) {
|
||||
return
|
||||
@ -255,9 +261,7 @@ export function useCanvasSetting() {
|
||||
const fetchBasicSettings = async () => {
|
||||
try {
|
||||
await get({ url: `/api/canvas-management/canvas-basic-settings/by-object/${correntObjectNo}` }).then((res) => {
|
||||
console.log('fetchBasicSettings res ', res)
|
||||
//if (res.length == 0) return
|
||||
|
||||
|
||||
let roofsRow = {}
|
||||
let roofsArray = {}
|
||||
|
||||
@ -309,14 +313,12 @@ export function useCanvasSetting() {
|
||||
roofs: roofsArray, // 만들어진 roofs 배열
|
||||
}
|
||||
|
||||
console.log('fetchBasicSettings patternData', patternData)
|
||||
//console.log('fetchBasicSettings patternData', patternData)
|
||||
|
||||
// 데이터 설정
|
||||
//setBasicSettings({ ...basicSetting, roofSizeSet: roofsRow[0].roofSizeSet, roofAngleSet: roofsRow[0].roofAngleSet, roofsData: roofsArray})
|
||||
const addRoofs = []
|
||||
roofMaterials.map((material) => {
|
||||
if (material.id === roofsArray[0].roofMatlCd) {
|
||||
//setRoofMaterials({ ...roofMaterials, layout: roofsArray[0].roofLayout })
|
||||
roofMaterials?.map((material) => {
|
||||
if (material.roofMatlCd === roofsArray[0].roofMatlCd) {
|
||||
addRoofs.push({ ...material, selected: true
|
||||
, index: 0
|
||||
, width: roofsArray[0].roofWidth
|
||||
@ -325,7 +327,7 @@ export function useCanvasSetting() {
|
||||
, raft: roofsArray[0].roofGap
|
||||
, layout: roofsArray[0].roofLayout
|
||||
})
|
||||
|
||||
|
||||
setAddedRoofs(addRoofs)
|
||||
setBasicSettings({ ...basicSetting, roofMaterials: addRoofs[0]
|
||||
, roofSizeSet: roofsRow[0].roofSizeSet
|
||||
@ -334,7 +336,6 @@ export function useCanvasSetting() {
|
||||
, selectedRoofMaterial: addRoofs[0] })
|
||||
}
|
||||
})
|
||||
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Data fetching error:', error)
|
||||
@ -375,6 +376,7 @@ export function useCanvasSetting() {
|
||||
|
||||
//Recoil 설정
|
||||
setCanvasSetting({ ...basicSetting })
|
||||
fetchBasicSettings()
|
||||
} catch (error) {
|
||||
swalFire({ text: getMessage(res.returnMessage), icon: 'error' })
|
||||
}
|
||||
|
||||
@ -36,11 +36,20 @@ export function useAdsorptionPoint() {
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
const removeAdsorptionPoint = () => {
|
||||
const adsorptionPoints = getAdsorptionPoints()
|
||||
adsorptionPoints.forEach((adsorptionPoint) => {
|
||||
canvas.remove(adsorptionPoint)
|
||||
})
|
||||
canvas.renderAll()
|
||||
}
|
||||
|
||||
return {
|
||||
adsorptionPointAddMode,
|
||||
adsorptionPointMode,
|
||||
adsorptionRange,
|
||||
getAdsorptionPoints,
|
||||
adsorptionPointAddModeStateEvent,
|
||||
removeAdsorptionPoint,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,9 @@ import { fontSelector, globalFontAtom } from '@/store/fontAtom'
|
||||
import { useLine } from '@/hooks/useLine'
|
||||
import { useSwal } from '@/hooks/useSwal'
|
||||
import ContextRoofAllocationSetting from '@/components/floor-plan/modal/roofAllocation/ContextRoofAllocationSetting'
|
||||
import { useCanvasSetting } from './option/useCanvasSetting'
|
||||
import { useGrid } from './common/useGrid'
|
||||
import { useAdsorptionPoint } from './useAdsorptionPoint'
|
||||
import { useRoofFn } from '@/hooks/common/useRoofFn'
|
||||
|
||||
export function useContextMenu() {
|
||||
@ -58,7 +61,10 @@ export function useContextMenu() {
|
||||
const { moveSurfaceShapeBatch } = useSurfaceShapeBatch()
|
||||
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
|
||||
const { addLine, removeLine } = useLine()
|
||||
const { removeGrid } = useGrid()
|
||||
const { removeAdsorptionPoint } = useAdsorptionPoint()
|
||||
const commonTextFont = useRecoilValue(fontSelector('commonText'))
|
||||
const { settingsData, setSettingsDataSave } = useCanvasSetting()
|
||||
const { swalFire } = useSwal()
|
||||
const { removeRoofMaterial, removeAllRoofMaterial } = useRoofFn()
|
||||
|
||||
@ -80,7 +86,15 @@ export function useContextMenu() {
|
||||
{
|
||||
id: 'gridColorEdit',
|
||||
name: getMessage('modal.grid.color.edit'),
|
||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
||||
component: (
|
||||
<ColorPickerModal
|
||||
id={popupId}
|
||||
color={gridColor}
|
||||
setColor={setGridColor}
|
||||
settingsData={settingsData}
|
||||
setSettingsDataSave={setSettingsDataSave}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'remove',
|
||||
@ -89,6 +103,10 @@ export function useContextMenu() {
|
||||
{
|
||||
id: 'removeAll',
|
||||
name: getMessage('delete.all'),
|
||||
fn: () => {
|
||||
removeGrid()
|
||||
removeAdsorptionPoint()
|
||||
},
|
||||
},
|
||||
],
|
||||
])
|
||||
@ -522,7 +540,15 @@ export function useContextMenu() {
|
||||
{
|
||||
id: 'gridColorEdit',
|
||||
name: getMessage('contextmenu.grid.color.edit'),
|
||||
component: <ColorPickerModal id={popupId} color={gridColor} setColor={setGridColor} />,
|
||||
component: (
|
||||
<ColorPickerModal
|
||||
id={popupId}
|
||||
color={gridColor}
|
||||
setColor={setGridColor}
|
||||
settingsData={settingsData}
|
||||
setSettingsDataSave={setSettingsDataSave}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'remove',
|
||||
@ -536,12 +562,8 @@ export function useContextMenu() {
|
||||
id: 'removeAll',
|
||||
name: getMessage('contextmenu.remove.all'),
|
||||
fn: () => {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => ['tempGrid', 'lineGrid', 'dotGrid'].includes(obj.name))
|
||||
.forEach((grid) => {
|
||||
canvas.remove(grid)
|
||||
})
|
||||
removeGrid()
|
||||
removeAdsorptionPoint()
|
||||
canvas.discardActiveObject()
|
||||
},
|
||||
},
|
||||
|
||||
@ -1,10 +1,21 @@
|
||||
import { useRecoilState } from 'recoil'
|
||||
import { contextPopupState, popupState } from '@/store/popupAtom'
|
||||
|
||||
/**
|
||||
* 팝업 관리 훅
|
||||
* @returns
|
||||
*/
|
||||
export function usePopup() {
|
||||
const [popup, setPopup] = useRecoilState(popupState)
|
||||
const [contextMenuPopup, setContextMenuPopup] = useRecoilState(contextPopupState)
|
||||
|
||||
/**
|
||||
* 팝업 추가
|
||||
* @param {*} id 팝업 아이디
|
||||
* @param {*} depth 팝업 깊이
|
||||
* @param {*} component 팝업 컴포넌트
|
||||
* @param {*} isConfig 팝업 타입
|
||||
*/
|
||||
const addPopup = (id, depth, component, isConfig = false) => {
|
||||
setPopup({
|
||||
config: isConfig ? [...filterDepth(depth, isConfig), { id, depth, component, isConfig }] : [...popup.config],
|
||||
@ -12,6 +23,11 @@ export function usePopup() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 닫기
|
||||
* @param {*} id 팝업 아이디
|
||||
* @param {*} isConfig 팝업 타입
|
||||
*/
|
||||
const closePopup = (id, isConfig = false) => {
|
||||
if (contextMenuPopup) setContextMenuPopup(null)
|
||||
if (isConfig) {
|
||||
@ -27,6 +43,10 @@ export function usePopup() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 필터
|
||||
* @param {*} depth 팝업 깊이
|
||||
*/
|
||||
const filterPopup = (depth) => {
|
||||
setPopup({
|
||||
config: [...filterDepth(depth)],
|
||||
@ -34,6 +54,12 @@ export function usePopup() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 자식 필터
|
||||
* @param {*} id 팝업 아이디
|
||||
* @param {*} isConfig 팝업 타입
|
||||
* @returns
|
||||
*/
|
||||
const filterChildrenPopup = (id, isConfig) => {
|
||||
let target = []
|
||||
if (isConfig) {
|
||||
@ -57,6 +83,10 @@ export function usePopup() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 여러개 닫기
|
||||
* @param {*} ids 팝업 아이디 배열
|
||||
*/
|
||||
const closePopups = (ids) => {
|
||||
setPopup({
|
||||
config: [...popup?.config.filter((child) => !ids.includes(child.id))],
|
||||
@ -64,6 +94,9 @@ export function usePopup() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 전체 닫기
|
||||
*/
|
||||
const closeAll = () => {
|
||||
setPopup({
|
||||
other: [],
|
||||
@ -71,6 +104,9 @@ export function usePopup() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 이전 팝업 닫기
|
||||
*/
|
||||
const closePrevPopup = () => {
|
||||
setPopup({
|
||||
config: [...popup?.slice(popup?.length - 1)],
|
||||
@ -78,6 +114,12 @@ export function usePopup() {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 팝업 깊이 필터
|
||||
* @param {*} depth 팝업 깊이
|
||||
* @param {*} isConfig 팝업 타입
|
||||
* @returns
|
||||
*/
|
||||
const filterDepth = (depth, isConfig) => {
|
||||
if (isConfig) {
|
||||
return [...popup?.config.filter((child) => child.depth < depth)]
|
||||
|
||||
@ -933,5 +933,9 @@
|
||||
"simulator.table.sub9": "予測発電量 (kWh)",
|
||||
"simulator.notice.sub1": "Hanwha Japan 年間発電量",
|
||||
"simulator.notice.sub2": "シミュレーション案内事項",
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||
"can.not.move.module": "모듈을 이동할 수 없습니다.(JA)",
|
||||
"can.not.copy.module": "모듈을 복사할 수 없습니다.(JA)",
|
||||
"can.not.remove.module": "모듈을 삭제할 수 없습니다.(JA)",
|
||||
"can.not.insert.module": "모듈을 삽입할 수 없습니다.(JA)"
|
||||
}
|
||||
|
||||
@ -943,5 +943,9 @@
|
||||
"simulator.table.sub9": "예측발전량 (kWh)",
|
||||
"simulator.notice.sub1": "Hanwha Japan 연간 발전량",
|
||||
"simulator.notice.sub2": "시뮬레이션 안내사항",
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요."
|
||||
"master.moduletypeitem.message.error": "지붕재 코드를 입력하세요.",
|
||||
"can.not.move.module": "모듈을 이동할 수 없습니다.",
|
||||
"can.not.copy.module": "모듈을 복사할 수 없습니다.",
|
||||
"can.not.remove.module": "모듈을 삭제할 수 없습니다.",
|
||||
"can.not.insert.module": "모듈을 삽입할 수 없습니다."
|
||||
}
|
||||
|
||||
@ -94,6 +94,11 @@ export const inputNumberCheck = (e) => {
|
||||
}
|
||||
}
|
||||
|
||||
// 값이 숫자인지 확인
|
||||
export const numberCheck = (value) => {
|
||||
return !isNaN(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 파이프함수 정의
|
||||
* @param {...any} fns 순수함수들
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user