import { useMessage } from '@/hooks/useMessage' import WithDraggable from '@/components/common/draggable/WithDraggable' import { usePopup } from '@/hooks/usePopup' import { useRecoilValue } from 'recoil' import { contextPopupPositionState } from '@/store/popupAtom' import { canvasState, currentObjectState } from '@/store/canvasAtom' import { useEffect, useState } from 'react' import Big from 'big.js' import { calcLineActualSize, calcLinePlaneSize } from '@/util/qpolygon-utils' import { normalizeDigits } from '@/util/input-utils' import { CalculatorInput } from '@/components/common/input/CalcInput' export default function AuxiliarySize(props) { const contextPopupPosition = useRecoilValue(contextPopupPositionState) const { id, pos = contextPopupPosition } = props const [checkedRadio, setCheckedRadio] = useState(null) const [value1, setValue1] = useState('') const [value2, setValue2] = useState('') const [size, setSize] = useState(0) const { getMessage } = useMessage() const { closePopup } = usePopup() 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.replace(/^0+/, '') if (value === '') { if (checkedRadio === 1) setValue1(value) if (checkedRadio === 2) setValue2(value) setSize(0) } else { //value = Big(value.replace(/[^0-9]/g, '')) value = Big(normalizeDigits(value)) 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 ( closePopup(id)} />
setCheckedRadio(1)} />
mm
{getMessage('length')}
{/**/}
mm
setCheckedRadio(2)} />
mm
{getMessage('length')}
{/**/}
mm
) }