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 (!outerLineFix || outerLines.length === 0) { swalFire({ text: getMessage('wall.line.not.found') }) closePopup(id) } }, []) useEffect(() => { const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) 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', }) canvas.renderAll() } else { canvas ?.getObjects() .filter((obj) => obj.name === 'outerLine') .forEach((line) => { line.set({ stroke: 'black', }) }) } 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 = { type: LINE_TYPE.WALLLINE.EAVES, pitch: currentAngleType === ANGLE_TYPE.SLOPE ? pitchRef.current.value : getChonByDegree(pitchRef.current.value), offset: offsetRef.current.value / 10, } } else { 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 = { type: LINE_TYPE.WALLLINE.GABLE, offset: offsetRef.current.value / 10, } } else { 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 = { type: LINE_TYPE.WALLLINE.WALL, offset: 0, } } else { attributes = { type: LINE_TYPE.WALLLINE.WALL, offset: offsetRef.current.value / 10, } } break case TYPES.SHED: 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 } }