qcast-front/src/hooks/module/useModule.js

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,
}
}