From f883235dc2221e3ec75b0798d56b9005bd714965 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Tue, 11 Feb 2025 16:44:10 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B3=B4=EC=A1=B0=EC=84=A0=20=EC=82=AC?= =?UTF-8?q?=EC=9D=B4=EC=A6=88=20=EC=A1=B0=EC=A0=95=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/auxiliary/AuxiliarySize.jsx | 119 ++++++++++++++++-- 1 file changed, 110 insertions(+), 9 deletions(-) diff --git a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx index 1afdd7ec..f8bf4ca7 100644 --- a/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx +++ b/src/components/floor-plan/modal/auxiliary/AuxiliarySize.jsx @@ -3,14 +3,113 @@ import WithDraggable from '@/components/common/draggable/WithDraggable' import { usePopup } from '@/hooks/usePopup' import { useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' -import { useCanvas } from '@/hooks/useCanvas' +import { canvasState, currentObjectState } from '@/store/canvasAtom' +import { useEffect, useState } from 'react' +import Big from 'big.js' +import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils' export default function AuxiliarySize(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition } = props + const [checkedRadio, setCheckedRadio] = useState(null) + const [value1, setValue1] = useState(null) + const [value2, setValue2] = useState(null) + const [size, setSize] = useState(0) const { getMessage } = useMessage() const { closePopup } = usePopup() - const { currentObject } = useCanvas() + const currentObject = useRecoilValue(currentObjectState) + const canvas = useRecoilValue(canvasState) + + useEffect(() => { + return () => { + canvas?.discardActiveObject() + } + }, []) + + useEffect(() => { + setValue1('') + setValue2('') + }, [checkedRadio]) + + useEffect(() => { + if (currentObject === null) closePopup(id) + }, [currentObject]) + + const handleInput = (e) => { + let value = e.target.value.replace(/^0+/, '') + if (value === '') { + if (checkedRadio === 1) setValue1(value) + if (checkedRadio === 2) setValue2(value) + setSize(0) + } else { + value = Big(value.replace(/[^0-9]/g, '')) + if (checkedRadio === 1) setValue1(value.toNumber()) + if (checkedRadio === 2) setValue2(value.toNumber()) + setSize(value.div(10).toNumber()) + } + } + + const handleSave = () => { + const { x1, y1, x2, y2 } = currentObject + + // 선택한 선분의 planeSize와 actualSize의 사잇각을 구한다. + const angleBetweenLines = () => { + const planeSize = Big(currentObject?.attributes.planeSize) + const actualSize = Big(currentObject?.attributes.actualSize) + // actualSize가 planeSize보다 작거나 같을때는 각도가 0 + if (actualSize.lte(planeSize)) { + return 0 + } + // 삼각법을 사용하여 각도를 계산합니다 + // cos(theta) = adjacent / hypotenuse + const cosTheta = planeSize.div(actualSize) + const thetaRadians = Big(Math.acos(cosTheta.toNumber())) // Angle in radians + return thetaRadians.times(180).div(Math.PI) + } + const degree = angleBetweenLines() + + if (size > 0 && (checkedRadio === 1 || checkedRadio === 2)) { + // 두 지점 사이의 거리를 구한다. + const dx = Big(x2).minus(Big(x1)) + const dy = Big(y2).minus(Big(y1)) + const distance = Big(dx.pow(2).plus(dy.pow(2)).sqrt()) + + if (distance > 0) { + // 현재 선분의 길이와 입력된 길이의 차이를 구한다. + const scaleFactor = Big(size).div(distance) + + //1지점 선택일때는 2지점의 좌표, 2지점 선택일때는 1지점의 좌표를 조정한다. + if (checkedRadio === 1) { + const newX2 = Big(x1).plus(dx.times(scaleFactor)) + const newY2 = Big(y1).plus(dy.times(scaleFactor)) + currentObject.set({ x2: newX2, y2: newY2 }) + } else if (checkedRadio === 2) { + const newX1 = Big(x2).minus(dx.times(scaleFactor)) + const newY1 = Big(y2).minus(dy.times(scaleFactor)) + currentObject.set({ x1: newX1, y1: newY1 }) + } + //planeSize와 actualSize를 재계산한다. + currentObject.attributes.planeSize = calcLinePlaneSize({ + x1: currentObject.x1, + y1: currentObject.y1, + x2: currentObject.x2, + y2: currentObject.y2, + }) + currentObject.attributes.actualSize = calcLineActualSize( + { + x1: currentObject.x1, + y1: currentObject.y1, + x2: currentObject.x2, + y2: currentObject.y2, + }, + degree, + ) + currentObject.addLengthText() + } + canvas.renderAll() + } + closePopup(id) + } return (
@@ -23,44 +122,46 @@ export default function AuxiliarySize(props) {
- + setCheckedRadio(1)} />
- +
mm
{getMessage('length')}
- +
mm
- + setCheckedRadio(2)} />
- +
mm
{getMessage('length')}
- +
mm
- +