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 { useSwal } from '@/hooks/useSwal' import { LINE_TYPE, POLYGON_TYPE } from '@/common/common' import Big from 'big.js' import { calcLinePlaneSize } from '@/util/qpolygon-utils' import { getSelectLinePosition } from '@/util/skeleton-utils' import { useMouse } from '@/hooks/useMouse' //동선이동 형 올림 내림 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 { getIntersectMousePoint } = useMouse() 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 { swalFire } = useSwal() const FLOW_LINE_REF = { POINTER_INPUT_REF: useRef(null), FILLED_INPUT_REF: useRef(null), DOWN_LEFT_RADIO_REF: useRef(null), UP_RIGHT_RADIO_REF: useRef(null), } const UP_DOWN_REF = { POINTER_INPUT_REF: useRef(null), FILLED_INPUT_REF: useRef(null), UP_RADIO_REF: useRef(null), DOWN_RADIO_REF: useRef(null), } const CONFIRM_LINE_REF = useRef(null) const FOLLOW_LINE_REF = useRef(null) /** 동선이동, 형이동 선택시 속성 처리*/ useEffect(() => { typeRef.current = type selectedObject.current = null if (FOLLOW_LINE_REF.current != null) { canvas.remove(FOLLOW_LINE_REF.current) canvas.renderAll() FOLLOW_LINE_REF.current = null } if (CONFIRM_LINE_REF.current != null) { canvas.remove(CONFIRM_LINE_REF.current) canvas.renderAll() CONFIRM_LINE_REF.current = null } clearRef() canvas.discardActiveObject() /** 전체 object 선택 불가 */ canvas.getObjects().forEach((obj) => { obj.set({ selectable: false }) }) /** 지붕선 관련 속성 처리*/ const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) roofs.forEach((roof) => { roof.set({ stroke: '#000000' }) roof.innerLines.forEach((line) => { if (type === TYPE.FLOW_LINE && line.name === LINE_TYPE.SUBLINE.RIDGE) { line.set({ selectable: true, strokeWidth: 5, stroke: '#1083E3' }) line.bringToFront() } else { line.set({ selectable: false, strokeWidth: 2, stroke: '#000000' }) } }) }) /** 외벽선 관련 속성 처리*/ const walls = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) walls.forEach((wall) => { if (wall.baseLines.length === 0) { wall.baseLines = canvas.getObjects().filter((obj) => obj.name === 'baseLine' && obj.attributes.wallId === wall.id) } wall.baseLines.forEach((line) => { if (type === TYPE.UP_DOWN) { line.set({ selectable: true, visible: true, stroke: '#1085E5', strokeWidth: 5 }) line.setCoords() line.bringToFront() } else { line.set({ selectable: false, visible: false }) } }) }) /** outerLines 속성처리*/ const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') outerLines.forEach((line) => line.set({ visible: true })) canvas.renderAll() }, [type]) /** 팝업창이 열릴때,닫힐때 속성들을 처리*/ useEffect(() => { addCanvasMouseEventListener('mouse:move', mouseMoveEvent) addCanvasMouseEventListener('mouse:down', mouseDownEvent) return () => { canvas.discardActiveObject() if (FOLLOW_LINE_REF.current != null) { canvas.remove(FOLLOW_LINE_REF.current) FOLLOW_LINE_REF.current = null } if (CONFIRM_LINE_REF.current != null) { canvas.remove(CONFIRM_LINE_REF.current) CONFIRM_LINE_REF.current = null } const roofs = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) roofs.forEach((roof) => { roof.set({ stroke: '#1083E3' }) roof.innerLines.forEach((line) => line.set({ selectable: true, strokeWidth: 2, stroke: '#1083E3' })) }) const walls = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL) walls.forEach((wall) => { if (wall.baseLines.length === 0) { wall.baseLines = canvas.getObjects().filter((obj) => obj.name === 'baseLine' && obj.attributes.wallId === wall.id) } wall.baseLines.forEach((baseLine) => { baseLine.set({ selectable: false, visible: false }) }) }) const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') outerLines.forEach((line) => line.set({ visible: true })) canvas.renderAll() initEvent() } }, []) /** object 선택이 변경될 때 처리*/ useEffect(() => { if (FOLLOW_LINE_REF.current != null) { canvas.remove(FOLLOW_LINE_REF.current) canvas.renderAll() FOLLOW_LINE_REF.current = null } if (selectedObject.current != null) { selectedObject.current.set({ stroke: '#1083E3' }) selectedObject.current = null } if (!currentObject) return clearRef() canvas .getObjects() .filter((obj) => obj.name === 'checkPoint' || obj.name === 'checkLine') .forEach((obj) => canvas.remove(obj)) canvas.renderAll() if (CONFIRM_LINE_REF.current != null) { canvas.remove(CONFIRM_LINE_REF.current) canvas.renderAll() CONFIRM_LINE_REF.current = null } currentObject.set({ stroke: '#EA10AC' }) selectedObject.current = currentObject const followLine = new fabric.Line([currentObject.x1, currentObject.y1, currentObject.x2, currentObject.y2], { stroke: '#000000', strokeWidth: 4, selectable: false, name: 'followLine', }) canvas.add(followLine) FOLLOW_LINE_REF.current = followLine canvas.on('mouse:move', (event) => { const mousePos = getIntersectMousePoint(event) if (followLine.x1 === followLine.x2) { followLine.left = mousePos.x - 2 } else { followLine.top = mousePos.y - 2 } canvas.renderAll() }) canvas.renderAll() }, [currentObject]) const clearRef = () => { if (type === TYPE.FLOW_LINE) { // 안전한 ref 접근 if (FLOW_LINE_REF.POINTER_INPUT_REF.current) { FLOW_LINE_REF.POINTER_INPUT_REF.current.value = '' } if (FLOW_LINE_REF.FILLED_INPUT_REF.current) { FLOW_LINE_REF.FILLED_INPUT_REF.current.value = '' } const upRightChecked = FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current?.checked || false const downLeftChecked = FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current?.checked || false if (upRightChecked || downLeftChecked) { if (FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current) { FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = !downLeftChecked } if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current) { FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = !upRightChecked } } else { if (FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current) { FLOW_LINE_REF.DOWN_LEFT_RADIO_REF.current.checked = true } if (FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current) { FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked = false } } } if (type === TYPE.UP_DOWN) { // 안전한 ref 접근 if (UP_DOWN_REF.POINTER_INPUT_REF.current) { UP_DOWN_REF.POINTER_INPUT_REF.current.value = '' } if (UP_DOWN_REF.FILLED_INPUT_REF.current) { UP_DOWN_REF.FILLED_INPUT_REF.current.value = '' } if (UP_DOWN_REF.UP_RADIO_REF.current) { UP_DOWN_REF.UP_RADIO_REF.current.checked = true } if (UP_DOWN_REF.DOWN_RADIO_REF.current) { UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } } let currentCalculatedValue = 0 const mouseMoveEvent = (e) => { //console.log('mouseMoveEvent:::::',e) const target = canvas.getActiveObject() if (!target) return // 디버깅 로그 추가 // if (typeRef.current === TYPE.UP_DOWN) { // console.log('UP_DOWN_REF.POINTER_INPUT_REF.current:', UP_DOWN_REF.POINTER_INPUT_REF.current); // if (!UP_DOWN_REF.POINTER_INPUT_REF.current) { // console.warn('UP_DOWN_REF.POINTER_INPUT_REF.current is null/undefined'); // } // } const { top: targetTop, left: targetLeft } = target const currentX = Big(getIntersectMousePoint(e).x) const currentY = Big(getIntersectMousePoint(e).y) let value = '' let direction = '' if (Math.abs(target.y1 - target.y2) < 0.5) { // 수평 라인 value = Big(targetTop).minus(currentY).times(10).round(0) // 방향 감지 if (value.toNumber() > 0) { direction = 'up' // 마우스가 라인 위쪽에 있음 (위로 움직임) } else if (value.toNumber() < 0) { direction = 'down' // 마우스가 라인 아래쪽에 있음 (아래로 움직임) } } else { // 수직 라인 value = Big(targetLeft).minus(currentX).times(10).round(0).neg() // 방향 감지 if (value.toNumber() > 0) { direction = 'right' // 마우스가 라인 오른쪽에 있음 (오른쪽으로 움직임) } else if (value.toNumber() < 0) { direction = 'left' // 마우스가 라인 왼쪽에 있음 (왼쪽으로 움직임) } } // 방향 정보를 사용하여 라디오 버튼 상태 업데이트 //console.log(`방향: ${direction}, 값: ${value.toNumber()}`) currentCalculatedValue = value.toNumber() if (typeRef.current === TYPE.FLOW_LINE) { // ref가 존재하는지 확인 후 값 설정 if (FLOW_LINE_REF.POINTER_INPUT_REF.current) { FLOW_LINE_REF.POINTER_INPUT_REF.current.value = value.toNumber() } } else { // UP_DOWN 타입일 때 안전한 접근 if (UP_DOWN_REF.POINTER_INPUT_REF.current) { UP_DOWN_REF.POINTER_INPUT_REF.current.value = value.abs().toNumber() } const midX = Big(target.x1).plus(target.x2).div(2) const midY = Big(target.y1).plus(target.y2).div(2) const wall = canvas.getObjects().find((obj) => obj.id === target.attributes.wallId) const result = getSelectLinePosition(wall, target, { testDistance: 5, // 테스트 거리 debug: true // 디버깅 로그 출력 }); //console.log("1111litarget:::::", target); //console.log("1111linePosition:::::", result.position); // 'top', 'bottom', 'left', 'right' let linePosition = result.position; //console.log("1111linePosition:::::", direction, linePosition); if (target.y1 === target.y2) { //수평벽 const setRadioStates = (isUp) => { if (UP_DOWN_REF.UP_RADIO_REF.current) { UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp; } if (UP_DOWN_REF.DOWN_RADIO_REF.current) { UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp; } }; if (linePosition === 'top') { setRadioStates(value.s !== -1); } else if (linePosition === 'bottom') { setRadioStates(value.s !== 1); } if(direction === 'up') { } /* checkPoint = { x: midX.toNumber(), y: midY.plus(10).toNumber() } if (wall.inPolygon(checkPoint)) { //선택라인이 내부 if (value.s === -1) { console.log('1value:::', value.s) if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true } else { if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } else { // if (value.s === 1) { //선택라인이 외부 console.log('2value:::', value.s) if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true } else { if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } */ } else { const setRadioStates = (isUp) => { if (UP_DOWN_REF.UP_RADIO_REF.current) { UP_DOWN_REF.UP_RADIO_REF.current.checked = isUp; } if (UP_DOWN_REF.DOWN_RADIO_REF.current) { UP_DOWN_REF.DOWN_RADIO_REF.current.checked = !isUp; } }; if (linePosition === 'left') { setRadioStates(value.s !== 1); } else if (linePosition === 'right') { setRadioStates(value.s !== -1); } /* checkPoint = { x: midX.plus(10).toNumber(), y: midY.toNumber() } if (wall.inPolygon(checkPoint)) { if (value.s === 1) { console.log('3value:::', value.s) if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true } else { if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } else { if (value.s === -1) { console.log('-1value:::', value.s) if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = false if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = true } else { if (UP_DOWN_REF.UP_RADIO_REF.current) UP_DOWN_REF.UP_RADIO_REF.current.checked = true if (UP_DOWN_REF.DOWN_RADIO_REF.current) UP_DOWN_REF.DOWN_RADIO_REF.current.checked = false } } */ } } } const mouseDownEvent = (e) => { canvas .getObjects() .filter((obj) => obj.name === 'checkPoint' || obj.name === 'checkLine') .forEach((obj) => canvas.remove(obj)) canvas.renderAll() //const target = selectedObject.current const target = selectedObject.current if (!target) return const roofId = target.attributes.roofId const followLine = canvas.getObjects().find((obj) => obj.name === 'followLine') const confirmLine = new fabric.Line([followLine.x1, followLine.y1, followLine.x2, followLine.y2], { left: followLine.left, top: followLine.top, stroke: '#000000', strokeWidth: 4, selectable: false, parentId: roofId, name: 'confirmLine', target, }) canvas.add(confirmLine) canvas.renderAll() CONFIRM_LINE_REF.current = confirmLine handleSave() } const handleSave = () => { if (CONFIRM_LINE_REF.current !== null) { canvas.remove(CONFIRM_LINE_REF.current) CONFIRM_LINE_REF.current = null canvas.renderAll() } if (FOLLOW_LINE_REF.current !== null) { canvas.remove(FOLLOW_LINE_REF.current) FOLLOW_LINE_REF.current = null canvas.renderAll() } if (UP_DOWN_REF.current !== null) { canvas.remove(UP_DOWN_REF.current) UP_DOWN_REF.current = null canvas.renderAll() } const target = selectedObject.current !== null ? selectedObject.current : CONFIRM_LINE_REF.current?.target if (!target) return const roofId = target.attributes.roofId const roof = canvas.getObjects().find((obj) => obj.id === roofId) // 현이동, 동이동 추가 let flPointValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value ?? 0; let flFilledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value ?? 0; flPointValue = (flFilledValue > 0 || flFilledValue < 0) ? flFilledValue : flPointValue; const moveFlowLine = typeRef.current === TYPE.FLOW_LINE ? flPointValue : 0 let udPointValue = UP_DOWN_REF.POINTER_INPUT_REF.current?.value ?? 0; let udFilledValue = UP_DOWN_REF.FILLED_INPUT_REF.current?.value ?? 0; udPointValue = udFilledValue > 0 ? udFilledValue : udPointValue; const moveUpDown = typeRef.current === TYPE.UP_DOWN ? udPointValue : 0 roof.moveFlowLine = parseInt(moveFlowLine, 10) || 0; roof.moveUpDown = parseInt(moveUpDown, 10) || 0; roof.moveDirect = ""; roof.moveSelectLine = target //console.log("target::::", target, roof.moveSelectLine) const wall = canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL && obj.attributes.roofId === roofId) const baseLines = wall.baseLines let centerPoint = wall.getCenterPoint(); let targetBaseLines = [] let isGableRoof if (typeRef.current === TYPE.FLOW_LINE) { const gableType = [LINE_TYPE.WALLLINE.GABLE, LINE_TYPE.WALLLINE.HIPANDGABLE] if (baseLines.find((line) => gableType.includes(line.attributes.type))) { isGableRoof = true let gableStartIndex = baseLines.findIndex((line) => gableType.includes(line.attributes.type)) baseLines.forEach((line, index) => { if (isGableRoof) { const isEvenLine = (index - gableStartIndex) % 2 === 0 if (isEvenLine && !gableType.includes(line.attributes.type)) { isGableRoof = false } } }) } else { isGableRoof = false } const lineVector = Math.abs(target.y1 - target.y2) < 0.2 ? FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked ? 'up' : 'down' : FLOW_LINE_REF.UP_RIGHT_RADIO_REF.current.checked ? 'right' : 'left' let checkBaseLines, currentBaseLines roof.moveDirect = lineVector switch (lineVector) { case 'up': checkBaseLines = baseLines.filter((line) => line.y1 === line.y2 && line.y1 < target.y1) currentBaseLines = checkBaseLines.filter((line) => { const minX = Math.min(target.x1, target.x2) const maxX = Math.max(target.x1, target.x2) return minX <= line.x1 && line.x1 <= maxX && minX <= line.x2 && line.x2 <= maxX }) if (isGableRoof && currentBaseLines.length > 0) { currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() })) } else { checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.y1).minus(line.y1).abs().toNumber() })) } baseLines .filter((line) => line.y1 === line.y2 && line.y1 < target.y1) .forEach((line) => targetBaseLines.push({ line, distance: Big(target.y1).minus(line.y1).abs().toNumber() })) break case 'down': checkBaseLines = baseLines.filter((line) => line.y1 === line.y2 && line.y1 > target.y1) currentBaseLines = checkBaseLines.filter((line) => { const minX = Math.min(target.x1, target.x2) const maxX = Math.max(target.x1, target.x2) return minX <= line.x1 && line.x1 <= maxX && minX <= line.x2 && line.x2 <= maxX }) if (isGableRoof && currentBaseLines.length > 0) { currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() })) } else { checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.y1).minus(target.y1).abs().toNumber() })) } break case 'right': checkBaseLines = baseLines.filter((line) => line.x1 === line.x2 && line.x1 > target.x1) currentBaseLines = checkBaseLines.filter((line) => { const minY = Math.min(target.y1, target.y2) const maxY = Math.max(target.y1, target.y2) return minY <= line.y1 && line.y1 <= maxY && minY <= line.y2 && line.y2 <= maxY }) if (isGableRoof && currentBaseLines.length > 0) { currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.x1).minus(target.x1).abs().toNumber() })) } else { checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.x1).minus(line.x1).abs().toNumber() })) } break case 'left': checkBaseLines = baseLines.filter((line) => line.x1 === line.x2 && line.x1 < target.x1) currentBaseLines = checkBaseLines.filter((line) => { const minY = Math.min(target.y1, target.y2) const maxY = Math.max(target.y1, target.y2) return minY <= line.y1 && line.y1 <= maxY && minY <= line.y2 && line.y2 <= maxY }) if (isGableRoof && currentBaseLines.length > 0) { currentBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(line.x1).minus(target.x1).abs().toNumber() })) } else { checkBaseLines.forEach((line) => targetBaseLines.push({ line, distance: Big(target.x1).minus(line.x1).abs().toNumber() })) } break } } else { roof.moveDirect = UP_DOWN_REF.UP_RADIO_REF.current.checked ? 'out' : UP_DOWN_REF.DOWN_RADIO_REF.current.checked ? 'in' : 'out' targetBaseLines.push({ line: target, distance: 0 }) } targetBaseLines.sort((a, b) => a.distance - b.distance) targetBaseLines = targetBaseLines.filter((line) => line.distance === targetBaseLines[0].distance) if (isGableRoof) { const zeroLengthLines = targetBaseLines.filter( (line) => Math.sqrt(Math.pow(line.line.x2 - line.line.x1, 2) + Math.pow(line.line.y2 - line.line.y1, 2)) < 1, ) if (zeroLengthLines.length > 0) { zeroLengthLines.forEach((line) => { const findLine = line.line const findCoords = [ { x: findLine.x1, y: findLine.y1 }, { x: findLine.x2, y: findLine.y2 }, ] wall.baseLines .filter((baseLine) => { return findCoords.some( (coord) => (Math.abs(coord.x - baseLine.x1) < 0.1 && Math.abs(coord.y - baseLine.y1) < 0.1) || (Math.abs(coord.x - baseLine.x2) < 0.1 && Math.abs(coord.y - baseLine.y2) < 0.1), ) }) .forEach((baseLine) => { const isAlready = targetBaseLines.find((target) => target.line === baseLine) if (isAlready) return targetBaseLines.push({ line: baseLine, distance: targetBaseLines[0].distance }) }) }) } } let value if (typeRef.current === TYPE.FLOW_LINE) { value = (() => { const filledValue = FLOW_LINE_REF.FILLED_INPUT_REF.current?.value; const pointerValue = FLOW_LINE_REF.POINTER_INPUT_REF.current?.value; if (filledValue && !isNaN(filledValue) && filledValue.trim() !== '') { return Big(filledValue).times(2); } else if (pointerValue && !isNaN(pointerValue) && pointerValue.trim() !== '') { return Big(pointerValue).times(2); } return Big(0); // 기본값으로 0 반환 또는 다른 적절한 기본값 })(); if (target.y1 === target.y2) { value = value.neg() } } else { //console.log("error::", UP_DOWN_REF) value = UP_DOWN_REF.FILLED_INPUT_REF.current.value !== '' ? Big(UP_DOWN_REF.FILLED_INPUT_REF.current.value) : Big(UP_DOWN_REF.POINTER_INPUT_REF.current.value) const midX = Big(target.x1).plus(target.x2).div(2) const midY = Big(target.y1).plus(target.y2).div(2) const wall = canvas.getObjects().find((obj) => obj.id === target.attributes.wallId) let checkPoint if (target.y1 === target.y2) { checkPoint = { x: midX.toNumber(), y: midY.plus(10).times(value.s).toNumber() } } else { checkPoint = { x: midX.plus(10).times(value.s).toNumber(), y: midY.toNumber() } } const inPolygon = wall.inPolygon(checkPoint) // if (UP_DOWN_REF.UP_RADIO_REF.current.checked && inPolygon) { // value = value.neg() // } else if (UP_DOWN_REF.DOWN_RADIO_REF.current.checked && !inPolygon) { // value = value.neg() // } } // console.log("2222titarget:::::", target); // console.log("2222저장된 moveSelectLine:", roof.moveSelectLine); // console.log("222wall::::", wall.points) const result = getSelectLinePosition(wall, target, { testDistance: 5, // 테스트 거리 debug: true // 디버깅 로그 출력 }); //console.log("2222linePosition:::::", result.position); //console.log("222moveDirect:::::", roof.moveDirect); // 디버깅용 분류 결과 확인 let linePosition = result.position; roof.movePosition = linePosition value = value.div(10) targetBaseLines .filter((line) => Math.sqrt(Math.pow(line.line.x2 - line.line.x1, 2) + Math.pow(line.line.y2 - line.line.y1, 2)) >= 1) .forEach((target) => { const currentLine = target.line //console.log("linePosition::::::::::::::", linePosition) if (UP_DOWN_REF?.DOWN_RADIO_REF?.current?.checked ){ //position확인 if(linePosition === 'bottom' || linePosition === 'right') { //console.log("1value::::::::::::::", value.toString()) value = value.neg() } }else { if(linePosition === 'top' || linePosition === 'left') { //console.log("1value::::::::::::::", value.toString()) value = value.neg() } } //console.log("2value::::::::::::::", value.toString()) const index = baseLines.findIndex((line) => line === currentLine) const nextLine = baseLines[(index + 1) % baseLines.length] const prevLine = baseLines[(index - 1 + baseLines.length) % baseLines.length] let deltaX = 0 let deltaY = 0 if (currentLine.y1 === currentLine.y2) { deltaY = value.toNumber() } else { deltaX = value.toNumber() } currentLine.set({ x1: currentLine.x1 + deltaX, y1: currentLine.y1 + deltaY, x2: currentLine.x2 + deltaX, y2: currentLine.y2 + deltaY, startPoint: { x: currentLine.x1 + deltaX, y: currentLine.y1 + deltaY }, endPoint: { x: currentLine.x2 + deltaX, y: currentLine.y2 + deltaY }, }) const currentSize = calcLinePlaneSize({ x1: currentLine.x1, y1: currentLine.y1, x2: currentLine.x2, y2: currentLine.y2, }) currentLine.attributes.planeSize = currentSize currentLine.attributes.actualSize = currentSize nextLine.set({ x1: currentLine.x2, y1: currentLine.y2, startPoint: { x: currentLine.x2, y: currentLine.y2 }, }) const nextSize = calcLinePlaneSize({ x1: nextLine.x1, y1: nextLine.y1, x2: nextLine.x2, y2: nextLine.y2 }) nextLine.attributes.planeSize = nextSize nextLine.attributes.actualSize = nextSize prevLine.set({ x2: currentLine.x1, y2: currentLine.y1, endPoint: { x: currentLine.x1, y: currentLine.y1 }, }) const prevSize = calcLinePlaneSize({ x1: prevLine.x1, y1: prevLine.y1, x2: prevLine.x2, y2: prevLine.y2 }) prevLine.attributes.planeSize = prevSize prevLine.attributes.actualSize = prevSize }) roof.drawHelpLine() initEvent() closePopup(id) } // javascript return { TYPE, closePopup, buttonType, type, setType, FLOW_LINE_REF, UP_DOWN_REF, handleSave, } }