Merge branch 'dev' of ssh://git.jetbrains.space/nalpari/q-cast-iii/qcast-front into dev

This commit is contained in:
김민식 2025-02-11 16:48:31 +09:00
commit 4724354204
3 changed files with 129 additions and 10 deletions

View File

@ -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 (
<WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm mount`}>
@ -23,44 +122,46 @@ export default function AuxiliarySize(props) {
<div className="modal-body">
<div className="discrimination-box mb10">
<div className="d-check-radio pop mb10">
<input type="radio" name="radio01" id="ra01" />
<input type="radio" name="radio01" id="ra01" onClick={(e) => setCheckedRadio(1)} />
<label htmlFor="ra01">1{getMessage('modal.auxiliary.size.edit.point')}</label>
</div>
<div className="outline-form mb15">
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
<input type="text" className="input-origin block" defaultValue={currentObject?.length} readOnly={true} />
<input type="text" className="input-origin block" defaultValue={currentObject?.attributes.planeSize} readOnly={true} />
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form">
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
<div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={100} />
<input type="text" className="input-origin block" value={value1} readOnly={checkedRadio !== 1} onChange={handleInput} />
</div>
<span className="thin">mm</span>
</div>
</div>
<div className="discrimination-box ">
<div className="d-check-radio pop mb10">
<input type="radio" name="radio01" id="ra02" />
<input type="radio" name="radio01" id="ra02" onClick={(e) => setCheckedRadio(2)} />
<label htmlFor="ra02">2{getMessage('modal.auxiliary.size.edit.point')}</label>
</div>
<div className="outline-form mb15">
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
<input type="text" className="input-origin block" defaultValue={100} readOnly={true} />
<input type="text" className="input-origin block" defaultValue={currentObject?.attributes.planeSize} readOnly={true} />
</div>
<span className="thin">mm</span>
</div>
<div className="outline-form">
<span style={{ width: 'auto' }}>{getMessage('length')}</span>
<div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={currentObject?.length} readOnly={true} />
<input type="text" className="input-origin block" value={value2} readOnly={checkedRadio !== 2} onChange={handleInput} />
</div>
<span className="thin">mm</span>
</div>
</div>
<div className="grid-btn-wrap">
<button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
<button className="btn-frame modal act" onClick={handleSave}>
{getMessage('modal.common.save')}
</button>
</div>
</div>
<div className="modal-foot modal-handle"></div>

View File

@ -75,7 +75,21 @@ export function useFont() {
}
}, [lengthText])
useEffect(() => {}, [circuitNumberText])
useEffect(() => {
if (canvas && circuitNumberText.fontWeight.value) {
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'circuitNumber')
textObjs.forEach((obj) => {
obj.set({
fontFamily: circuitNumberText.fontFamily.value,
fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
fontSize: circuitNumberText.fontSize.value,
fill: circuitNumberText.fontColor.value,
})
})
canvas.renderAll()
}
}, [circuitNumberText])
return {}
}

View File

@ -7,6 +7,8 @@ import { v4 as uuidv4 } from 'uuid'
import { useMasterController } from '@/hooks/common/useMasterController'
import { basicSettingState, trestleDisplaySelector } from '@/store/settingAtom'
import { useSwal } from '@/hooks/useSwal'
import { useContext } from 'react'
import { QcastContext } from '@/app/QcastProvider'
// 회로 및 가대설정
export const useTrestle = () => {
@ -17,10 +19,12 @@ export const useTrestle = () => {
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
const isTrestleDisplay = useRecoilValue(trestleDisplaySelector)
const { swalFire } = useSwal()
const { setIsGlobalLoading } = useContext(QcastContext)
const apply = () => {
const notAllocationModules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && !obj.circuit)
if (notAllocationModules.length > 0) {
swalFire({ text: '回路番号が設定されていないモジュールがあります。 番号を設定しなおすか、 パネルを削除してください。', icon: 'error' })
setIsGlobalLoading(false)
return null
}
try {