247 lines
7.6 KiB
JavaScript
247 lines
7.6 KiB
JavaScript
import { useEffect, useRef, useState } from 'react'
|
|
import { useRecoilValue } from 'recoil'
|
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom'
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { useEvent } from '@/hooks/useEvent'
|
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
import { useLine } from '@/hooks/useLine'
|
|
import { useMode } from '@/hooks/useMode'
|
|
import { outerLineFixState } from '@/store/outerLineAtom'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
import { getChonByDegree } from '@/util/canvas-util'
|
|
import { settingModalFirstOptionsState } from '@/store/settingAtom'
|
|
|
|
// 처마.케라바 변경
|
|
export function useEavesGableEdit(id) {
|
|
const canvas = useRecoilValue(canvasState)
|
|
const { getMessage } = useMessage()
|
|
const { addCanvasMouseEventListener, initEvent } = useEvent()
|
|
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
|
const { closePopup } = usePopup()
|
|
const TYPES = {
|
|
EAVES: 'eaves',
|
|
GABLE: 'gable',
|
|
WALL_MERGE: 'wall.merge',
|
|
SHED: 'shed',
|
|
}
|
|
const [type, setType] = useState(TYPES.EAVES)
|
|
const typeRef = useRef(TYPES.EAVES)
|
|
const { removeLine, addPitchTextsByOuterLines } = useLine()
|
|
const { swalFire } = useSwal()
|
|
|
|
const { drawRoofPolygon } = useMode()
|
|
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
|
const pitchText = useRecoilValue(pitchTextSelector)
|
|
|
|
const pitchRef = useRef(null)
|
|
const offsetRef = useRef(null)
|
|
const widthRef = useRef(null)
|
|
const radioTypeRef = useRef('1') // 각 페이지에서 사용하는 radio type
|
|
const outerLineFix = useRecoilValue(outerLineFixState)
|
|
|
|
const buttonMenu = [
|
|
{ id: 1, name: getMessage('eaves'), type: TYPES.EAVES },
|
|
{ id: 2, name: getMessage('gable'), type: TYPES.GABLE },
|
|
{ id: 3, name: getMessage('wall.merge'), type: TYPES.WALL_MERGE },
|
|
{ id: 4, name: getMessage('shed'), type: TYPES.SHED },
|
|
]
|
|
|
|
const settingModalFirstOptions = useRecoilValue(settingModalFirstOptionsState)
|
|
|
|
useEffect(() => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
if (outerLines.length === 0) {
|
|
swalFire({ text: getMessage('wall.line.not.found') })
|
|
closePopup(id)
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
wallLines.forEach((wallLine) => {
|
|
const id = wallLine.id
|
|
wallLine.lines = outerLines.filter((line) => line.attributes?.wallId === id)
|
|
})
|
|
wallLines.forEach((wallLine) => {
|
|
convertPolygonToLines(wallLine)
|
|
})
|
|
|
|
addCanvasMouseEventListener('mouse:over', mouseOverEvent)
|
|
addCanvasMouseEventListener('mouse:down', mouseDownEvent)
|
|
|
|
return () => {
|
|
canvas.discardActiveObject()
|
|
wallLines.forEach((wallLine) => {
|
|
convertLinesToPolygon(wallLine)
|
|
})
|
|
initEvent()
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
typeRef.current = type
|
|
}, [type])
|
|
|
|
const mouseOverEvent = (e) => {
|
|
if (e.target && e.target.name === 'outerLine') {
|
|
e.target.set({
|
|
stroke: 'red',
|
|
})
|
|
e.target.bringToFront()
|
|
canvas.renderAll()
|
|
} else {
|
|
canvas
|
|
?.getObjects()
|
|
.filter((obj) => obj.name === 'outerLine')
|
|
.forEach((line) => {
|
|
line.set({
|
|
stroke: 'black',
|
|
})
|
|
line.bringToFront()
|
|
})
|
|
}
|
|
canvas.renderAll()
|
|
}
|
|
|
|
const mouseDownEvent = (e) => {
|
|
if (!e.target || (e.target && e.target.name !== 'outerLine')) {
|
|
return
|
|
}
|
|
|
|
const target = e.target
|
|
|
|
let attributes = target.get('attributes')
|
|
|
|
switch (typeRef.current) {
|
|
case TYPES.EAVES:
|
|
if (radioTypeRef.current === '1') {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitchRef.current.value : getChonByDegree(pitchRef.current.value),
|
|
offset: offsetRef.current.value / 10,
|
|
}
|
|
} else {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.HIPANDGABLE,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitchRef.current.value : getChonByDegree(pitchRef.current.value),
|
|
offset: offsetRef.current.value / 10,
|
|
width: widthRef.current.value / 10,
|
|
}
|
|
}
|
|
break
|
|
case TYPES.GABLE:
|
|
if (radioTypeRef.current === '1') {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
offset: offsetRef.current.value / 10,
|
|
}
|
|
} else {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.JERKINHEAD,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitchRef.current.value : getChonByDegree(pitchRef.current.value),
|
|
offset: offsetRef.current.value / 10,
|
|
width: widthRef.current.value / 10,
|
|
}
|
|
}
|
|
break
|
|
case TYPES.WALL_MERGE:
|
|
if (radioTypeRef.current === '1') {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.WALL,
|
|
offset: 0,
|
|
}
|
|
} else {
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.WALL,
|
|
offset: offsetRef.current.value / 10,
|
|
}
|
|
}
|
|
break
|
|
case TYPES.SHED:
|
|
attributes = {
|
|
...attributes,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
offset: offsetRef.current.value / 10,
|
|
}
|
|
break
|
|
}
|
|
|
|
target.set({
|
|
attributes,
|
|
})
|
|
|
|
const roofBases = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
|
|
|
|
roofBases.forEach((roof) => {
|
|
roof.innerLines.forEach((line) => {
|
|
removeLine(line)
|
|
})
|
|
canvas.remove(roof)
|
|
})
|
|
|
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
|
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'pitchText' || obj.name === 'lengthText')
|
|
removeTargets.forEach((obj) => {
|
|
canvas.remove(obj)
|
|
})
|
|
wallLines.forEach((wallLine) => {
|
|
addPitchTextsByOuterLines()
|
|
const roof = drawRoofPolygon(wallLine)
|
|
canvas?.renderAll()
|
|
roof.drawHelpLine(settingModalFirstOptions)
|
|
})
|
|
|
|
wallLines.forEach((wallLine) => {
|
|
convertPolygonToLines(wallLine)
|
|
})
|
|
|
|
canvas.renderAll()
|
|
|
|
addCanvasMouseEventListener('mouse:over', mouseOverEvent)
|
|
addCanvasMouseEventListener('mouse:down', mouseDownEvent)
|
|
}
|
|
|
|
// polygon의 lines를 이용해 line으로 변경하기
|
|
const convertPolygonToLines = (polygon) => {
|
|
polygon.set({ visible: false })
|
|
polygon.lines.forEach((line) => {
|
|
line.set({ visible: true })
|
|
line.set({ selectable: true })
|
|
line.set({ strokeWidth: 5 })
|
|
line.set({ parent: polygon })
|
|
line.bringToFront()
|
|
})
|
|
|
|
// canvas objects에서 polygon.lines를 제외한 다른 line의 selectable을 false로 변경
|
|
canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name !== 'outerLine' && obj.type === 'QLine')
|
|
.forEach((obj) => {
|
|
obj.set({ selectable: false })
|
|
})
|
|
|
|
canvas?.renderAll()
|
|
}
|
|
|
|
// 다시 다각형으로 변경하기
|
|
const convertLinesToPolygon = (polygon) => {
|
|
polygon.set({ visible: true })
|
|
polygon.lines.forEach((line) => {
|
|
line.set({ visible: false })
|
|
// line.set({ selectable: false })
|
|
})
|
|
|
|
canvas?.renderAll()
|
|
}
|
|
|
|
return { type, setType, buttonMenu, TYPES, pitchRef, offsetRef, widthRef, radioTypeRef, pitchText }
|
|
}
|