256 lines
7.3 KiB
JavaScript
256 lines
7.3 KiB
JavaScript
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
|
import { useRecoilValue } from 'recoil'
|
|
import { useEffect, useRef, useState } from 'react'
|
|
import { useLine } from '@/hooks/useLine'
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { useEvent } from '@/hooks/useEvent'
|
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
import { useMode } from '@/hooks/useMode'
|
|
import { usePolygon } from '@/hooks/usePolygon'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
import { getChonByDegree } from '@/util/canvas-util'
|
|
|
|
//지붕형상 수동 설정
|
|
export function useRoofShapePassivitySetting(id) {
|
|
const TYPES = {
|
|
EAVES: 'eaves',
|
|
GABLE: 'gable',
|
|
SHED: 'shed',
|
|
}
|
|
const canvas = useRecoilValue(canvasState)
|
|
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
|
const pitchText = useRecoilValue(pitchTextSelector)
|
|
const { getMessage } = useMessage()
|
|
const { showLine, hideLine, addPitchTextsByOuterLines } = useLine()
|
|
const { swalFire } = useSwal()
|
|
const { addCanvasMouseEventListener, initEvent } = useEvent()
|
|
// const { addCanvasMouseEventListener, initEvent } = useContext(EventContext)
|
|
const { drawRoofPolygon } = useMode()
|
|
const { addPolygonByLines, addLengthText } = usePolygon()
|
|
const currentObject = useRecoilValue(currentObjectState)
|
|
const offsetRef = useRef(null)
|
|
const pitchRef = useRef(null)
|
|
const currentLineRef = useRef(null)
|
|
const history = useRef([])
|
|
const [type, setType] = useState(TYPES.EAVES)
|
|
const isFix = useRef(false)
|
|
const initLines = useRef([])
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
|
|
const { closePopup } = usePopup()
|
|
const buttons = [
|
|
{ id: 1, name: getMessage('eaves'), type: TYPES.EAVES },
|
|
{ id: 2, name: getMessage('gable'), type: TYPES.GABLE },
|
|
{ id: 3, name: getMessage('windage'), type: TYPES.SHED },
|
|
]
|
|
|
|
useEffect(() => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
if (!canvas.outerLineFix || outerLines.length === 0) {
|
|
swalFire({ text: getMessage('wall.line.not.found') })
|
|
closePopup(id)
|
|
return
|
|
}
|
|
setIsLoading(true)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (!isLoading) return
|
|
addCanvasMouseEventListener('mouse:down', mouseDown)
|
|
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
|
|
|
canvas?.remove(...wallLines)
|
|
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
initLines.current = outerLines.map((line) => ({ ...line }))
|
|
outerLines.forEach((outerLine, idx) => {
|
|
if (idx === 0) {
|
|
currentLineRef.current = outerLine
|
|
}
|
|
outerLine.set({ selectable: true })
|
|
showLine(outerLine)
|
|
outerLine.bringToFront()
|
|
})
|
|
canvas?.renderAll()
|
|
|
|
return () => {
|
|
handleLineToPolygon()
|
|
canvas?.discardActiveObject()
|
|
initEvent()
|
|
}
|
|
}, [isLoading])
|
|
|
|
useEffect(() => {
|
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
let stroke, strokeWidth
|
|
lines.forEach((line) => {
|
|
if (line.attributes?.type === LINE_TYPE.WALLLINE.EAVES || line.attributes?.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
|
stroke = '#45CD7D'
|
|
strokeWidth = 4
|
|
} else if (line.attributes?.type === LINE_TYPE.WALLLINE.GABLE || line.attributes?.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
|
stroke = '#3FBAE6'
|
|
strokeWidth = 4
|
|
} else {
|
|
stroke = '#000000'
|
|
strokeWidth = 4
|
|
}
|
|
line.set({
|
|
stroke,
|
|
strokeWidth,
|
|
})
|
|
})
|
|
canvas.renderAll()
|
|
if (!currentObject) {
|
|
return
|
|
}
|
|
if (currentObject.name !== 'outerLine') {
|
|
return
|
|
}
|
|
|
|
currentObject.set({
|
|
stroke: '#EA10AC',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
currentLineRef.current = currentObject
|
|
canvas.renderAll()
|
|
}, [currentObject])
|
|
|
|
const mouseDown = (e) => {
|
|
if (!e.target) {
|
|
currentLineRef.current = null
|
|
return
|
|
}
|
|
|
|
if (e.target && e.target.name === 'outerLine') {
|
|
currentLineRef.current = e.target
|
|
}
|
|
}
|
|
|
|
const nextLineFocus = (selectedLine) => {
|
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
const index = lines.findIndex((line) => line === selectedLine)
|
|
|
|
const nextLine = lines[index + 1] || lines[0]
|
|
if (nextLine.attributes?.isFixed) {
|
|
canvas.discardActiveObject()
|
|
return
|
|
}
|
|
canvas.setActiveObject(nextLine)
|
|
}
|
|
|
|
const handleConfirm = () => {
|
|
if (!currentLineRef.current) {
|
|
alert('선택된 외곽선이 없습니다.')
|
|
return
|
|
}
|
|
let attributes
|
|
const offset = Number(offsetRef.current.value) / 10
|
|
if (type === TYPES.EAVES) {
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
offset,
|
|
pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitchRef.current.value : getChonByDegree(pitchRef.current.value),
|
|
}
|
|
} else if (type === TYPES.GABLE) {
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
offset,
|
|
}
|
|
} else if (type === TYPES.SHED) {
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
offset,
|
|
}
|
|
}
|
|
|
|
currentLineRef.current.set({
|
|
attributes: { ...attributes, isFixed: true },
|
|
})
|
|
|
|
history.current.push(currentLineRef.current)
|
|
nextLineFocus(currentLineRef.current)
|
|
}
|
|
|
|
const handleRollback = () => {
|
|
if (history.current.length === 0) {
|
|
return
|
|
}
|
|
const lastLine = history.current.pop()
|
|
|
|
delete lastLine.attributes
|
|
lastLine.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
canvas.setActiveObject(lastLine)
|
|
canvas.renderAll()
|
|
}
|
|
|
|
const handleSave = () => {
|
|
isFix.current = true
|
|
handleLineToPolygon()
|
|
|
|
closePopup(id)
|
|
}
|
|
|
|
const handleLineToPolygon = () => {
|
|
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
|
const exceptObjs = canvas.getObjects().filter((obj) => obj.name !== 'outerLine' && obj.parent?.name !== 'outerLine')
|
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
let checkedAllSetting = true
|
|
|
|
lines.forEach((line) => {
|
|
if (!line.attributes) {
|
|
checkedAllSetting = false
|
|
}
|
|
})
|
|
|
|
if (!checkedAllSetting) {
|
|
swalFire({ text: '설정이 완료되지 않은 외벽선이 있습니다.', icon: 'warning' })
|
|
return
|
|
}
|
|
|
|
exceptObjs.forEach((obj) => {
|
|
canvas.remove(obj)
|
|
})
|
|
|
|
lines.forEach((line) => {
|
|
hideLine(line)
|
|
})
|
|
|
|
let wall
|
|
|
|
if (isFix.current) {
|
|
wall = addPolygonByLines(lines, { name: POLYGON_TYPE.WALL, fill: 'transparent', stroke: 'black' })
|
|
} else {
|
|
// 그냥 닫을 경우 처리
|
|
wall = addPolygonByLines([...initLines.current], {
|
|
name: POLYGON_TYPE.WALL,
|
|
fill: 'transparent',
|
|
stroke: 'black',
|
|
})
|
|
lines.forEach((line, idx) => {
|
|
line.attributes = initLines.current[idx].attributes
|
|
})
|
|
}
|
|
|
|
wall.lines = [...lines]
|
|
// 기존 그려진 지붕이 없다면
|
|
|
|
if (isFix.current) {
|
|
// 완료 한 경우에는 지붕까지 그려줌
|
|
addPitchTextsByOuterLines()
|
|
const roof = drawRoofPolygon(wall)
|
|
addLengthText(roof)
|
|
}
|
|
|
|
canvas.renderAll()
|
|
}
|
|
|
|
return { handleSave, handleConfirm, buttons, type, setType, TYPES, offsetRef, pitchRef, handleRollback, pitchText }
|
|
}
|