import { useEffect, useRef, useState } from 'react' import { useRecoilValue } from 'recoil' import { canvasState } from '@/store/canvasAtom' import { useMessage } from '@/hooks/useMessage' import { useEvent } from '@/hooks/useEvent' import { LINE_TYPE } from '@/common/common' import { useLine } from '@/hooks/useLine' import { useMode } from '@/hooks/useMode' // 처마.케라바 변경 export function useEavesGableEdit() { const canvas = useRecoilValue(canvasState) const { getMessage } = useMessage() const { addCanvasMouseEventListener, initEvent } = useEvent() 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 } = useLine() const { drawRoofPolygon } = useMode() const pitchRef = useRef(null) const offsetRef = useRef(null) const widthRef = useRef(null) const radioTypeRef = useRef('1') // 각 페이지에서 사용하는 radio type 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 }, ] useEffect(() => { const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') 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: pitchRef.current.value, offset: offsetRef.current.value / 10, } } else { attributes = { type: LINE_TYPE.WALLLINE.HIPANDGABLE, pitch: 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: 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 === 'roofBase') roofBases.forEach((roof) => { roof.innerLines.forEach((line) => { removeLine(line) }) canvas.remove(roof) }) const wallLines = canvas.getObjects().filter((obj) => obj.name === 'wallLine') wallLines.forEach((wallLine) => { const roof = drawRoofPolygon(wallLine) canvas?.renderAll() roof.drawHelpLine() }) wallLines.forEach((wallLine) => { convertPolygonToLines(wallLine) }) 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 } }