import { useRecoilValue } from 'recoil' import { canvasState, currentObjectState } from '@/store/canvasAtom' import { usePopup } from '@/hooks/usePopup' import { useMessage } from '@/hooks/useMessage' import { useEffect, useRef, useState } from 'react' import { useEvent } from '@/hooks/useEvent' import { POLYGON_TYPE } from '@/common/common' import { OUTER_LINE_TYPE } from '@/store/outerLineAtom' import { QLine } from '@/components/fabric/QLine' //동선이동 형 올림 내림 export function useMovementSetting(id) { const TYPE = { FLOW_LINE: 'flowLine', // 동선이동 UP_DOWN: 'updown', //형 올림내림 } const canvas = useRecoilValue(canvasState) const { initEvent, addCanvasMouseEventListener } = useEvent() const { closePopup } = usePopup() const { getMessage } = useMessage() const currentObject = useRecoilValue(currentObjectState) const selectedObject = useRef(null) const buttonType = [ { id: 1, name: getMessage('modal.movement.flow.line.move'), type: TYPE.FLOW_LINE }, { id: 2, name: getMessage('modal.movement.flow.line.updown'), type: TYPE.UP_DOWN }, ] const [type, setType] = useState(TYPE.FLOW_LINE) const typeRef = useRef(type) const FLOW_LINE_REF = { DOWN_LEFT_INPUT_REF: useRef(null), UP_RIGHT_INPUT_REF: useRef(null), DOWN_LEFT_RADIO_REF: useRef(null), UP_RIGHT_RADIO_REF: useRef(null), } const UP_DOWN_REF = { UP_INPUT_REF: useRef(null), DOWN_INPUT_REF: useRef(null), UP_RADIO_REF: useRef(null), DOWN_RADIO_REF: useRef(null), } useEffect(() => { removeFlowLine() typeRef.current = type const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true outerLines.forEach((line) => { line.set({ stroke: 'black' }) line.set({ visible: false }) }) canvas.getObjects().forEach((obj) => { obj.set({ selectable: false }) }) const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // 기존 wallLine의 visible false roofs.forEach((roof) => { roof.innerLines.forEach((line) => { line.bringToFront() line.set({ selectable: false }) line.set({ strokeWidth: 1 }) }) }) if (type === TYPE.FLOW_LINE) { roofs.forEach((roof) => { roof.innerLines.forEach((line) => { line.bringToFront() line.set({ selectable: true }) line.set({ strokeWidth: 4 }) }) }) } else if (type === TYPE.UP_DOWN) { const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true outerLines.forEach((line) => { line.set({ stroke: 'black' }) line.set({ visible: true }) line.bringToFront() line.set({ selectable: true }) }) } canvas.renderAll() }, [type]) useEffect(() => { /*const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) // 기존 wallLine의 visible false wallLines.forEach((line) => { line.set({ visible: false }) })*/ canvas.renderAll() addCanvasMouseEventListener('mouse:move', mouseMoveEvent) addCanvasMouseEventListener('mouse:down', mouseDownEvent) return () => { initEvent() removeFlowLine() const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) wallLines.forEach((line) => { line.set({ visible: true }) }) const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true outerLines.forEach((line) => { line.set({ stroke: 'black' }) line.set({ visible: false }) }) canvas.renderAll() } }, []) useEffect(() => { const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') // 기존 outerLine의 selectable true outerLines.forEach((line) => { line.set({ stroke: 'black' }) }) selectedObject.current = null if (!currentObject) { return } clearRef() selectedObject.current = currentObject if (currentObject.name === OUTER_LINE_TYPE.OUTER_LINE) { currentObject.set({ stroke: '#EA10AC' }) currentObject.bringToFront() } canvas.renderAll() }, [currentObject]) const clearRef = () => { if (type === TYPE.FLOW_LINE) { FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = '' FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = '' FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = false FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = false } if (type === TYPE.UP_DOWN) { UP_DOWN_REF.UP_INPUT_REF.current.value = '' UP_DOWN_REF.DOWN_INPUT_REF.current.value = '' UP_DOWN_REF.UP_RADIO_REF.current.checked = false UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } const mouseDownEvent = (e) => { if (typeRef.current === TYPE.FLOW_LINE) { flowLineDownEvent(e) } else { updownDownEvent(e) } } const removeFlowLine = () => { const flowLine = canvas.getObjects().filter((obj) => obj.name === 'flowLine') flowLine.forEach((line) => { canvas.remove(line) }) } const mouseMoveEvent = (e) => { if (typeRef.current === TYPE.FLOW_LINE) { flowLineMoveEvent(e) } else { updownMoveEvent(e) } } //동선 이동 마우스 클릭 이벤트 const flowLineDownEvent = (e) => { const target = selectedObject.current if (!target) { return } const direction = target.direction removeFlowLine() let newPoint = [] if (direction === 'left' || direction === 'right') { if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked) { newPoint = [ target.x1, target.y1 + Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10), target.x2, target.y2 + Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10), ] } else { newPoint = [ target.x1, target.y1 - Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10), target.x2, target.y2 - Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10), ] } } else { if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked) { newPoint = [ target.x1 - Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10), target.y1, target.x2 - Number(FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value / 10), target.y2, ] } else { newPoint = [ target.x1 + Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10), target.y1, target.x2 + Number(FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value / 10), target.y2, ] } } const cloned = new fabric.Line(newPoint, { stroke: 'red', strokeWidth: 4, name: 'flowLine', currentLine: target, }) canvas.add(cloned) canvas.renderAll() canvas.discardActiveObject() } //형 올림내림 마우스 클릭 이벤트 const updownDownEvent = (e) => { console.log('updownDownEvent') } const flowLineMoveEvent = (e) => { const target = canvas.getActiveObject() if (!target) { return } const direction = target.direction const { top: targetTop, left: targetLeft } = target const currentX = canvas.getPointer(e.e).x const currentY = Math.floor(canvas.getPointer(e.e).y) if (direction === 'left' || direction === 'right') { if (targetTop > currentY) { console.log('targetTop > currentY') FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = true FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = '' FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000) } else { FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = '' FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000) } } else { if (targetLeft > currentX) { FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = '' FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000) } else { FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = true FLOW_LINE_REF.DOWN_LEFT_INPUT_REF.current.value = '' FLOW_LINE_REF.UP_RIGHT_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000) } } canvas?.renderAll() } const updownMoveEvent = (e) => { const target = canvas.getActiveObject() if (!target) { return } const direction = target.direction const { top: targetTop, left: targetLeft } = target const currentX = canvas.getPointer(e.e).x const currentY = Math.floor(canvas.getPointer(e.e).y) if (direction === 'left' || direction === 'right') { if (targetTop > currentY) { UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true UP_DOWN_REF.UP_INPUT_REF.current.value = '' UP_DOWN_REF.DOWN_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000) } else { UP_DOWN_REF.UP_RADIO_REF.current.checked = true UP_DOWN_REF.DOWN_INPUT_REF.current.value = '' UP_DOWN_REF.UP_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetTop - currentY)) / 10000).toFixed(5) * 100000) } } else { if (targetLeft > currentX) { UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true UP_DOWN_REF.UP_INPUT_REF.current.value = '' UP_DOWN_REF.DOWN_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000) } else { UP_DOWN_REF.UP_RADIO_REF.current.checked = true UP_DOWN_REF.DOWN_INPUT_REF.current.value = '' UP_DOWN_REF.UP_INPUT_REF.current.value = Math.floor((Number(Math.abs(targetLeft - currentX)) / 10000).toFixed(5) * 100000) } } canvas?.renderAll() } const handleSave = () => { if (type === TYPE.FLOW_LINE) { const flowLine = canvas.getObjects().find((obj) => obj.name === 'flowLine') const currentLine = flowLine.currentLine if (!flowLine || !currentLine) { return } currentLine.set({ x1: flowLine.x1, y1: flowLine.y1, x2: flowLine.x2, y2: flowLine.y2, }) currentLine.startPoint = { x: flowLine.x1, y: flowLine.y1 } currentLine.endPoint = { x: flowLine.x2, y: flowLine.y2 } canvas.remove(flowLine) canvas.renderAll() } else { // 형 올림내림 if (UP_DOWN_REF.UP_RADIO_REF.current.checked) { // 자릿수를 올리다 체크 const length = Number(UP_DOWN_REF.UP_INPUT_REF.current.value) } else { // 자릿수를 내리다 체크 const length = Number(UP_DOWN_REF.DOWN_INPUT_REF.current.value) } } } return { TYPE, closePopup, buttonType, type, setType, FLOW_LINE_REF, UP_DOWN_REF, handleSave, } }