1059 lines
35 KiB
JavaScript
1059 lines
35 KiB
JavaScript
import { BATCH_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
import { canvasState } from '@/store/canvasAtom'
|
|
import { isOverlap, polygonToTurfPolygon, rectToPolygon } from '@/util/canvas-util'
|
|
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
|
import { v4 as uuidv4 } from 'uuid'
|
|
import * as turf from '@turf/turf'
|
|
import { useSwal } from '../useSwal'
|
|
import { useModuleBasicSetting } from './useModuleBasicSetting'
|
|
import { useMessage } from '../useMessage'
|
|
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
|
import { moduleStatisticsState } from '@/store/circuitTrestleAtom'
|
|
import { useCircuitTrestle } from '../useCirCuitTrestle'
|
|
|
|
export const MODULE_REMOVE_TYPE = {
|
|
LEFT: 'left',
|
|
RIGHT: 'right',
|
|
HORIZONTAL_SIDE: 'horizontalSide',
|
|
TOP: 'top',
|
|
BOTTOM: 'bottom',
|
|
VERTICAL_SIDE: 'verticalSide',
|
|
NONE: 'none',
|
|
}
|
|
|
|
export const MODULE_INSERT_TYPE = {
|
|
LEFT: 'left',
|
|
RIGHT: 'right',
|
|
TOP: 'up',
|
|
BOTTOM: 'down',
|
|
}
|
|
|
|
export const MODULE_ALIGN_TYPE = {
|
|
VERTICAL: 'vertical',
|
|
HORIZONTAL: 'horizontal',
|
|
}
|
|
|
|
export function useModule() {
|
|
const canvas = useRecoilValue(canvasState)
|
|
const { swalFire } = useSwal()
|
|
const { getMessage } = useMessage()
|
|
const { checkModuleDisjointObjects } = useModuleBasicSetting()
|
|
const selectedModules = useRecoilValue(selectedModuleState)
|
|
const { setModuleStatisticsData } = useCircuitTrestle()
|
|
|
|
const moduleMove = (length, direction) => {
|
|
const selectedObj = canvas.getActiveObjects() //선택된 객체들을 가져옴
|
|
const selectedIds = selectedObj.map((obj) => obj.id) // selectedObj의 ID 추출
|
|
if (selectedObj[0].circuit) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
canvas.discardActiveObject() //선택해제
|
|
|
|
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]
|
|
let isWarning = false
|
|
const objects = getObjects()
|
|
|
|
if (selectedModules) {
|
|
selectedModules.forEach((module) => {
|
|
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()
|
|
})
|
|
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
selectedModules.forEach((module) => {
|
|
module.set({ left: module.originCoords.left, top: module.originCoords.top, fill: module.originCoords.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
}
|
|
}
|
|
const moduleMultiMove = (type, length, direction) => {
|
|
if (canvas.getActiveObjects().length === 0) return
|
|
if (canvas.getActiveObjects().length > 1) {
|
|
swalFire({
|
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
canvas.discardActiveObject()
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
if (activeModule.circuit) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
const modules = type === 'row' ? getRowModules(activeModule) : getColumnModules(activeModule)
|
|
const otherModules = getOtherModules(modules)
|
|
const objects = getObjects()
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
|
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 })
|
|
module.setCoords()
|
|
canvas.renderAll()
|
|
|
|
if (isOverlapOtherModules(module, otherModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
})
|
|
|
|
canvas.renderAll()
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
modules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
const moduleMoveAll = (length, direction, surfaceArray) => {
|
|
surfaceArray.forEach((surface) => {
|
|
const modules = canvas
|
|
.getObjects()
|
|
.filter((module) => module.name === POLYGON_TYPE.MODULE)
|
|
.filter((module) => module.surfaceId === surface.id)
|
|
const objects = getObjects()
|
|
|
|
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 })
|
|
module.setCoords()
|
|
canvas.renderAll()
|
|
|
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, surface)) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
})
|
|
|
|
canvas.renderAll()
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
modules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const moduleCopyAll = (length, direction, surfaceArray) => {
|
|
surfaceArray.forEach((surface) => {
|
|
const modules = canvas
|
|
.getObjects()
|
|
.filter((module) => module.name === POLYGON_TYPE.MODULE)
|
|
.filter((module) => module.surfaceId === surface.id)
|
|
const objects = getObjects()
|
|
const copyModules = []
|
|
|
|
let copyModule = null
|
|
let isWarning = false
|
|
let moduleLength = 0
|
|
if (['up', 'down'].includes(direction)) {
|
|
modules.sort((a, b) => a.top - b.top)
|
|
moduleLength = Number(modules[modules.length - 1].top) + Number(modules[modules.length - 1].height) - Number(modules[0].top)
|
|
} else if (['left', 'right'].includes(direction)) {
|
|
modules.sort((a, b) => a.left - b.left)
|
|
moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
|
|
}
|
|
|
|
modules.forEach((module) => {
|
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
|
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,
|
|
moduleInfo: module.moduleInfo,
|
|
left,
|
|
top,
|
|
id: uuidv4(),
|
|
})
|
|
copyModule = obj
|
|
canvas.add(obj)
|
|
copyModules.push(obj)
|
|
obj.setCoords()
|
|
})
|
|
if (isOverlapObjects(copyModule, objects) || isOutsideSurface(copyModule, surface)) {
|
|
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 moduleCopy = (length, direction) => {
|
|
if (canvas.getActiveObjects().length === 0) return
|
|
const activeModuleIds = canvas.getActiveObjects().map((obj) => obj.id)
|
|
const modules = canvas.getObjects().filter((obj) => activeModuleIds.includes(obj.id))
|
|
const objects = getObjects()
|
|
const otherModules = canvas.getObjects().filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE)
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
|
let isWarning = false
|
|
let copyModules = []
|
|
let copyModule = null
|
|
canvas.discardActiveObject() //선택해제
|
|
modules.forEach((module) => {
|
|
const { top, left } = getPosotion(module, direction, length, 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,
|
|
moduleInfo: module.moduleInfo,
|
|
left,
|
|
top,
|
|
id: uuidv4(),
|
|
})
|
|
copyModules.push(obj)
|
|
copyModule = obj
|
|
canvas.add(obj)
|
|
canvas.renderAll()
|
|
})
|
|
|
|
if (
|
|
isOverlapOtherModules(copyModule, otherModules) ||
|
|
isOverlapObjects(copyModule, objects) ||
|
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
|
) {
|
|
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()
|
|
},
|
|
})
|
|
} else {
|
|
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
|
}
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const moduleMultiCopy = (type, length, direction) => {
|
|
if (canvas.getActiveObjects().length === 0) return
|
|
if (canvas.getActiveObjects().length > 1) {
|
|
swalFire({
|
|
title: '여러 개의 모듈을 선택할 수 없습니다.',
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
canvas.discardActiveObject()
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
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 copyModules = []
|
|
let copyModule = null
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === modules[0].surfaceId)[0]
|
|
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)
|
|
} else if (['left', 'right'].includes(direction)) {
|
|
moduleLength = Number(modules[modules.length - 1].left) + Number(modules[modules.length - 1].width) - Number(modules[0].left)
|
|
}
|
|
|
|
modules.forEach((module) => {
|
|
const { top, left } = getPosotion(module, direction, Number(length) + Number(moduleLength), false)
|
|
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,
|
|
moduleInfo: module.moduleInfo,
|
|
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' })
|
|
}
|
|
canvas.renderAll()
|
|
})
|
|
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.copy.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
canvas.remove(...copyModules)
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
} else {
|
|
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
|
setModuleStatisticsData()
|
|
}
|
|
}
|
|
|
|
const moduleColumnRemove = (type) => {
|
|
if (isFixedModule()) {
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
if (activeModule.circuit) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
const columnModules = getColumnModules(activeModule)
|
|
const otherModules = getOtherModules(columnModules)
|
|
const objects = getObjects()
|
|
let targetModules = []
|
|
const rightModules = otherModules.filter((module) => activeModule.left < module.left).sort((a, b) => a.left - b.left)
|
|
const leftModules = otherModules.filter((module) => activeModule.left > module.left).sort((a, b) => b.left - a.left)
|
|
let width = -1
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
|
let isWarning = false
|
|
canvas.discardActiveObject()
|
|
moduleSetupSurface.set({ modules: otherModules })
|
|
canvas.remove(...columnModules)
|
|
canvas.renderAll()
|
|
|
|
if (type === MODULE_REMOVE_TYPE.LEFT) {
|
|
rightModules.forEach((module) => {
|
|
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()
|
|
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()
|
|
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]
|
|
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 / 2 })
|
|
module.setCoords()
|
|
canvas.renderAll()
|
|
})
|
|
|
|
rightModules.forEach((module) => {
|
|
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()
|
|
})
|
|
|
|
sideModules.forEach((module) => {
|
|
if (
|
|
isOverlapOtherModules(
|
|
module,
|
|
sideModules.filter((m) => m.id !== module.id),
|
|
) ||
|
|
isOverlapObjects(module, objects) ||
|
|
isOutsideSurface(module, moduleSetupSurface)
|
|
) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
})
|
|
|
|
targetModules = sideModules
|
|
}
|
|
canvas.renderAll()
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.remove.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
canvas.add(...columnModules)
|
|
targetModules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const moduleRowRemove = (type) => {
|
|
if (isFixedModule()) {
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
const rowModules = getRowModules(activeModule)
|
|
const otherModules = getOtherModules(rowModules)
|
|
const objects = getObjects()
|
|
let targetModules = []
|
|
const topModules = otherModules.filter((module) => activeModule.top > module.top).sort((a, b) => b.top - a.top)
|
|
const bottomModules = otherModules.filter((module) => activeModule.top < module.top).sort((a, b) => a.top - b.top)
|
|
let height = -1
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
|
let isWarning = false
|
|
|
|
canvas.discardActiveObject()
|
|
moduleSetupSurface.set({ modules: otherModules })
|
|
canvas.remove(...rowModules)
|
|
canvas.renderAll()
|
|
|
|
if (type === MODULE_REMOVE_TYPE.TOP) {
|
|
bottomModules.forEach((module) => {
|
|
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()
|
|
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 + activeModule.height })
|
|
module.setCoords()
|
|
canvas.renderAll()
|
|
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) {
|
|
topModules.forEach((module) => {
|
|
module.originPos = {
|
|
left: module.left,
|
|
top: module.top,
|
|
fill: module.fill,
|
|
}
|
|
// if (height === -1) height = activeModule.top - module.top
|
|
if (height === -1) height = activeModule.height
|
|
module.set({ top: module.top + height / 2 })
|
|
module.setCoords()
|
|
})
|
|
|
|
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 = activeModule.height
|
|
module.set({ top: module.top - height / 2 })
|
|
module.setCoords()
|
|
})
|
|
|
|
canvas.renderAll()
|
|
const sideModules = [...topModules, ...bottomModules]
|
|
sideModules.forEach((module) => {
|
|
if (
|
|
isOverlapOtherModules(
|
|
module,
|
|
sideModules.filter((m) => m.id !== module.id),
|
|
) ||
|
|
isOverlapObjects(module, objects) ||
|
|
isOutsideSurface(module, moduleSetupSurface)
|
|
) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
})
|
|
targetModules = sideModules
|
|
}
|
|
canvas.renderAll()
|
|
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
|
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
|
swalFire({
|
|
title: getMessage('can.not.remove.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
canvas.add(...rowModules)
|
|
targetModules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const moduleColumnInsert = (type) => {
|
|
if (isFixedModule()) {
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
const columnModules = getColumnModules(activeModule)
|
|
let otherModules = getOtherModules(columnModules)
|
|
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) => 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]
|
|
if (moduleSetupSurface.modules.filter((module) => module.circuit).length > 0) {
|
|
return
|
|
}
|
|
let width = -1
|
|
let isWarning = false
|
|
if (targetModules.length === 0) {
|
|
swalFire({
|
|
title: '마지막 모듈입니다.',
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
canvas.discardActiveObject()
|
|
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, module.width, false)
|
|
module.originPos = {
|
|
left: module.left,
|
|
top: module.top,
|
|
fill: module.fill,
|
|
}
|
|
module.set({ left, top })
|
|
canvas.renderAll()
|
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
otherModules = getOtherModules(columnModules)
|
|
columnModules.forEach((module) => {
|
|
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,
|
|
moduleInfo: module.moduleInfo,
|
|
surfaceId: module.surfaceId,
|
|
left,
|
|
top,
|
|
id: uuidv4(),
|
|
})
|
|
copyModule = obj
|
|
canvas.add(obj)
|
|
copyModules.push(obj)
|
|
obj.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
|
|
if (
|
|
isOverlapOtherModules(copyModule, otherModules) ||
|
|
isOverlapObjects(copyModule, objects) ||
|
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
|
) {
|
|
isWarning = true
|
|
}
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.insert.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
targetModules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.remove(...copyModules)
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const isFixedModule = () => {
|
|
const completeSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.isComplete)
|
|
|
|
if (completeSurfaces.length > 0) {
|
|
swalFire({
|
|
title: getMessage('modal.module.can.not.edit'),
|
|
type: 'alert',
|
|
icon: 'error',
|
|
})
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
const muduleRowInsert = (type) => {
|
|
if (isFixedModule()) {
|
|
return
|
|
}
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
const rowModules = getRowModules(activeModule)
|
|
let otherModules = getOtherModules(rowModules)
|
|
const targetModules =
|
|
type === MODULE_INSERT_TYPE.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)
|
|
if (targetModules.length === 0) {
|
|
swalFire({
|
|
title: '마지막 모듈입니다.',
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
const objects = getObjects()
|
|
const copyModules = []
|
|
const moduleSetupSurface = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE && obj.id === activeModule.surfaceId)[0]
|
|
if (moduleSetupSurface.modules.filter((module) => module.circuit).length > 0) {
|
|
return
|
|
}
|
|
let height = -1
|
|
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, activeModule.height, false)
|
|
module.originPos = {
|
|
left: module.left,
|
|
top: module.top,
|
|
fill: module.fill,
|
|
}
|
|
module.set({ left, top })
|
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
otherModules = getOtherModules(rowModules)
|
|
rowModules.forEach((module) => {
|
|
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,
|
|
moduleInfo: module.moduleInfo,
|
|
fill: module.fill,
|
|
left,
|
|
top,
|
|
id: uuidv4(),
|
|
})
|
|
copyModule = obj
|
|
canvas.add(obj)
|
|
copyModules.push(obj)
|
|
obj.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
|
|
if (
|
|
isOverlapOtherModules(copyModule, otherModules) ||
|
|
isOverlapObjects(copyModule, objects) ||
|
|
isOutsideSurface(copyModule, moduleSetupSurface)
|
|
) {
|
|
isWarning = true
|
|
copyModule.set({ fill: 'red' })
|
|
}
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.insert.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
targetModules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.remove(...copyModules)
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const alignModule = (type, surfaceArray) => {
|
|
surfaceArray.forEach((surface) => {
|
|
const modules = surface.modules
|
|
|
|
const objects = getObjects()
|
|
let [top, bottom, left, right] = [0, 0, 0, 0]
|
|
|
|
top = Math.min(...modules.map((module) => module.top))
|
|
bottom = Math.max(...modules.map((module) => module.top + module.height))
|
|
left = Math.min(...modules.map((module) => module.left))
|
|
right = Math.max(...modules.map((module) => module.left + module.width))
|
|
const moduleSurfacePos = {
|
|
top: Math.min(...surface.points.map((point) => point.y)),
|
|
left: Math.min(...surface.points.map((point) => point.x)),
|
|
}
|
|
const [height, width] = [bottom - top, right - left]
|
|
const verticalCenterLength = moduleSurfacePos.top + surface.height / 2 - (top + height / 2)
|
|
const horizontalCenterLength = moduleSurfacePos.left + surface.width / 2 - (left + width / 2)
|
|
let isWarning = false
|
|
|
|
canvas.discardActiveObject()
|
|
modules.forEach((module) => {
|
|
module.originPos = {
|
|
left: module.left,
|
|
top: module.top,
|
|
fill: module.fill,
|
|
}
|
|
if (type === MODULE_ALIGN_TYPE.VERTICAL) {
|
|
module.set({ top: module.top + verticalCenterLength })
|
|
} else if (type === MODULE_ALIGN_TYPE.HORIZONTAL) {
|
|
module.set({ left: module.left + horizontalCenterLength })
|
|
}
|
|
|
|
canvas.renderAll()
|
|
module.setCoords()
|
|
if (isOverlapObjects(module, objects) || isOutsideSurface(module, surface)) {
|
|
isWarning = true
|
|
module.set({ fill: 'red' })
|
|
}
|
|
})
|
|
canvas.renderAll()
|
|
if (isWarning) {
|
|
swalFire({
|
|
title: getMessage('can.not.align.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
confirmFn: () => {
|
|
modules.forEach((module) => {
|
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
|
module.setCoords()
|
|
})
|
|
canvas.renderAll()
|
|
},
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
const modulesRemove = () => {
|
|
const activeModule = canvas.getObjects().filter((obj) => canvas.getActiveObjects()[0].id === obj.id)[0]
|
|
if (activeModule.circuit) {
|
|
swalFire({
|
|
title: getMessage('can.not.move.module'),
|
|
icon: 'error',
|
|
type: 'alert',
|
|
})
|
|
return
|
|
}
|
|
const modules = canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.surfaceId === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE && activeModule.id !== obj.id)
|
|
const surface = canvas.getObjects().filter((obj) => obj.id === activeModule.surfaceId && obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)[0]
|
|
surface.set({ modules: modules })
|
|
canvas.remove(activeModule)
|
|
canvas.renderAll()
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const moduleRoofRemove = (surfaceArray) => {
|
|
surfaceArray.forEach((surface) => {
|
|
surface.modules = []
|
|
canvas
|
|
.getObjects()
|
|
.filter((module) => module.name === POLYGON_TYPE.MODULE && module.surfaceId === surface.id)
|
|
.forEach((module) => {
|
|
canvas.remove(module.circuit)
|
|
canvas.remove(module)
|
|
})
|
|
})
|
|
canvas.renderAll()
|
|
setModuleStatisticsData()
|
|
}
|
|
|
|
const isOverlapOtherModules = (module, otherModules) => {
|
|
if (otherModules.length === 0) return false
|
|
|
|
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()
|
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.top === target.top)
|
|
.sort((a, b) => a.left - b.left)
|
|
}
|
|
|
|
const getColumnModules = (target) => {
|
|
return canvas
|
|
.getObjects()
|
|
.filter((obj) => target.surfaceId === obj.surfaceId && obj.name === POLYGON_TYPE.MODULE && obj.left === target.left)
|
|
.sort((a, b) => a.top - b.top)
|
|
}
|
|
|
|
const getPosotion = (target, direction, length, hasMargin = false) => {
|
|
let top = target.top
|
|
let left = target.left
|
|
|
|
if (direction === 'up') {
|
|
top = Number(target.top) - Number(length) / 10
|
|
top = hasMargin ? top - Number(target.height) : top
|
|
} else if (direction === 'down') {
|
|
top = Number(target.top) + Number(length) / 10
|
|
top = hasMargin ? top + Number(target.height) : top
|
|
} else if (direction === 'left') {
|
|
left = Number(target.left) - Number(length) / 10
|
|
left = hasMargin ? left - Number(target.width) : left
|
|
} else if (direction === 'right') {
|
|
left = Number(target.left) + Number(length) / 10
|
|
left = hasMargin ? left + Number(target.width) : left
|
|
}
|
|
return { top, left }
|
|
}
|
|
|
|
const getOtherModules = (modules) => {
|
|
const moduleIds = modules.map((module) => module.id)
|
|
return canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.surfaceId === modules[0].surfaceId && obj.name === POLYGON_TYPE.MODULE && !moduleIds.includes(obj.id))
|
|
}
|
|
|
|
const getObjects = () => {
|
|
return canvas
|
|
?.getObjects()
|
|
.filter((obj) => [BATCH_TYPE.OPENING, BATCH_TYPE.TRIANGLE_DORMER, BATCH_TYPE.PENTAGON_DORMER, BATCH_TYPE.SHADOW].includes(obj.name))
|
|
}
|
|
|
|
return {
|
|
moduleMove,
|
|
moduleMultiMove,
|
|
moduleMoveAll,
|
|
moduleCopy,
|
|
moduleMultiCopy,
|
|
moduleCopyAll,
|
|
moduleColumnRemove,
|
|
moduleRowRemove,
|
|
moduleColumnInsert,
|
|
muduleRowInsert,
|
|
modulesRemove,
|
|
moduleRoofRemove,
|
|
alignModule,
|
|
}
|
|
}
|