Merge branch 'dev' into feature/design-remake
This commit is contained in:
commit
f0e71df5d4
@ -3,7 +3,7 @@ import { createCalculator } from '@/util/calc-utils'
|
|||||||
import '@/styles/calc.scss'
|
import '@/styles/calc.scss'
|
||||||
|
|
||||||
export const CalculatorInput = forwardRef(
|
export const CalculatorInput = forwardRef(
|
||||||
({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false, placeholder, name='', disabled = false }, ref) => {
|
({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false, placeholder, name='', disabled = false, maxLength = 12 }, ref) => {
|
||||||
const [showKeypad, setShowKeypad] = useState(false)
|
const [showKeypad, setShowKeypad] = useState(false)
|
||||||
const [displayValue, setDisplayValue] = useState(value || '0')
|
const [displayValue, setDisplayValue] = useState(value || '0')
|
||||||
const [hasOperation, setHasOperation] = useState(false)
|
const [hasOperation, setHasOperation] = useState(false)
|
||||||
@ -48,28 +48,56 @@ export const CalculatorInput = forwardRef(
|
|||||||
const calculator = calculatorRef.current
|
const calculator = calculatorRef.current
|
||||||
let newDisplayValue = ''
|
let newDisplayValue = ''
|
||||||
|
|
||||||
|
// maxLength 체크
|
||||||
|
if (maxLength > 0) {
|
||||||
|
const currentLength = (calculator.currentOperand || '').length + (calculator.previousOperand || '').length + (calculator.operation || '').length
|
||||||
|
if (currentLength >= maxLength) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 소수점 이하 2자리 제한 로직 추가
|
// 소수점 이하 2자리 제한 로직 추가
|
||||||
const shouldPreventInput = (value) => {
|
const shouldPreventInput = (value) => {
|
||||||
const decimalParts = (value || '').split('.')
|
if (!value) return false
|
||||||
|
const decimalParts = value.toString().split('.')
|
||||||
return decimalParts.length > 1 && decimalParts[1].length >= 2
|
return decimalParts.length > 1 && decimalParts[1].length >= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 숫자 추가 함수
|
||||||
|
const appendNumber = (current, num) => {
|
||||||
|
// maxLength 체크
|
||||||
|
if (maxLength > 0 && (current + num).length > maxLength) {
|
||||||
|
return current
|
||||||
|
}
|
||||||
|
// 현재 값이 0이고 소수점이 없을 때 0이 아닌 숫자를 입력하면 대체
|
||||||
|
if (current === '0' && num !== '.' && !current.includes('.')) {
|
||||||
|
return num.toString()
|
||||||
|
}
|
||||||
|
// 0. 다음에 0을 입력하는 경우 허용
|
||||||
|
if (current === '0' && num === '0') {
|
||||||
|
return '0.'
|
||||||
|
}
|
||||||
|
return current + num
|
||||||
|
}
|
||||||
|
|
||||||
if (hasOperation) {
|
if (hasOperation) {
|
||||||
// 연산자 이후 숫자 입력 시
|
// 연산자 이후 숫자 입력 시
|
||||||
if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
|
if (calculator.shouldResetDisplay) {
|
||||||
calculator.currentOperand = num.toString()
|
calculator.currentOperand = num.toString()
|
||||||
calculator.shouldResetDisplay = false
|
calculator.shouldResetDisplay = false
|
||||||
}else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
} else if (num === '.') {
|
||||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
if (!calculator.currentOperand.includes('.')) {
|
||||||
|
calculator.currentOperand = calculator.currentOperand || '0' + '.'
|
||||||
}
|
}
|
||||||
// else {
|
} else if (!shouldPreventInput(calculator.currentOperand)) {
|
||||||
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
calculator.currentOperand = appendNumber(calculator.currentOperand || '0', num)
|
||||||
// }
|
}
|
||||||
|
|
||||||
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
||||||
setDisplayValue(newDisplayValue)
|
setDisplayValue(newDisplayValue)
|
||||||
} else {
|
} else {
|
||||||
// 첫 번째 숫자 입력 시
|
// 첫 번째 숫자 입력 시
|
||||||
if (displayValue === '0' || calculator.shouldResetDisplay) {
|
if (calculator.shouldResetDisplay) {
|
||||||
calculator.currentOperand = num.toString()
|
calculator.currentOperand = num.toString()
|
||||||
calculator.shouldResetDisplay = false
|
calculator.shouldResetDisplay = false
|
||||||
newDisplayValue = calculator.currentOperand
|
newDisplayValue = calculator.currentOperand
|
||||||
@ -77,8 +105,17 @@ export const CalculatorInput = forwardRef(
|
|||||||
if (!hasOperation) {
|
if (!hasOperation) {
|
||||||
onChange(calculator.currentOperand)
|
onChange(calculator.currentOperand)
|
||||||
}
|
}
|
||||||
} else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
} else if (num === '.') {
|
||||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
if (!calculator.currentOperand.includes('.')) {
|
||||||
|
calculator.currentOperand = (calculator.currentOperand || '0') + '.'
|
||||||
|
newDisplayValue = calculator.currentOperand
|
||||||
|
setDisplayValue(newDisplayValue)
|
||||||
|
if (!hasOperation) {
|
||||||
|
onChange(newDisplayValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!shouldPreventInput(calculator.currentOperand)) {
|
||||||
|
calculator.currentOperand = appendNumber(calculator.currentOperand || '0', num)
|
||||||
newDisplayValue = calculator.currentOperand
|
newDisplayValue = calculator.currentOperand
|
||||||
setDisplayValue(newDisplayValue)
|
setDisplayValue(newDisplayValue)
|
||||||
if (!hasOperation) {
|
if (!hasOperation) {
|
||||||
@ -382,6 +419,7 @@ export const CalculatorInput = forwardRef(
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
autoComplete={'off'}
|
autoComplete={'off'}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
maxLength={maxLength}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{showKeypad && !readOnly && (
|
{showKeypad && !readOnly && (
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import { useSwal } from '@/hooks/useSwal'
|
|||||||
import { QcastContext } from '@/app/QcastProvider'
|
import { QcastContext } from '@/app/QcastProvider'
|
||||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||||
import {normalizeDigits, normalizeDecimal} from '@/util/input-utils'
|
import {normalizeDigits, normalizeDecimal} from '@/util/input-utils'
|
||||||
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
export default function Estimate({}) {
|
export default function Estimate({}) {
|
||||||
const [uniqueData, setUniqueData] = useState([])
|
const [uniqueData, setUniqueData] = useState([])
|
||||||
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
||||||
@ -2106,15 +2107,27 @@ export default function Estimate({}) {
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="input-wrap" style={{ width: '100%' }}>
|
<div className="input-wrap" style={{ width: '100%' }}>
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
className="input-light al-r"
|
{/* className="input-light al-r"*/}
|
||||||
|
{/* value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}*/}
|
||||||
|
{/* disabled={item.itemId === '' || !!item?.paDispOrder}*/}
|
||||||
|
{/* onChange={(e) => {*/}
|
||||||
|
{/* onChangeAmount(e.target.value, item.dispOrder, index)*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/* maxLength={6}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
className={"input-light al-r"}
|
||||||
value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}
|
value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}
|
||||||
disabled={item.itemId === '' || !!item?.paDispOrder}
|
disabled={item.itemId === '' || !!item?.paDispOrder}
|
||||||
onChange={(e) => {
|
onChange={(value) =>{
|
||||||
onChangeAmount(e.target.value, item.dispOrder, index)
|
onChangeAmount(value, item.dispOrder, index)
|
||||||
|
}}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
}}
|
}}
|
||||||
maxLength={6}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -2122,9 +2135,32 @@ export default function Estimate({}) {
|
|||||||
<td>
|
<td>
|
||||||
<div className="form-flex-wrap">
|
<div className="form-flex-wrap">
|
||||||
<div className="input-wrap mr5">
|
<div className="input-wrap mr5">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
className="input-light al-r"
|
{/* className="input-light al-r"*/}
|
||||||
|
{/* value={*/}
|
||||||
|
{/* item.openFlg === '1'*/}
|
||||||
|
{/* ? 'OPEN'*/}
|
||||||
|
{/* : convertNumberToPriceDecimal(item?.showSalePrice === '0' ? null : item?.salePrice?.replaceAll(',', ''))*/}
|
||||||
|
{/* }*/}
|
||||||
|
{/* disabled={*/}
|
||||||
|
{/* item.openFlg === '1'*/}
|
||||||
|
{/* ? true*/}
|
||||||
|
{/* : estimateContextState?.estimateType === 'YJSS'*/}
|
||||||
|
{/* ? item?.paDispOrder*/}
|
||||||
|
{/* ? true*/}
|
||||||
|
{/* : item.pkgMaterialFlg !== '1'*/}
|
||||||
|
{/* : item.itemId === '' || !!item?.paDispOrder*/}
|
||||||
|
{/* ? true*/}
|
||||||
|
{/* : item.openFlg === '1'*/}
|
||||||
|
{/* }*/}
|
||||||
|
{/* onChange={(e) => {*/}
|
||||||
|
{/* onChangeSalePrice(e.target.value, item.dispOrder, index)*/}
|
||||||
|
{/* }}*/}
|
||||||
|
{/* maxLength={12}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
className={"input-light al-r"}
|
||||||
value={
|
value={
|
||||||
item.openFlg === '1'
|
item.openFlg === '1'
|
||||||
? 'OPEN'
|
? 'OPEN'
|
||||||
@ -2140,13 +2176,15 @@ export default function Estimate({}) {
|
|||||||
: item.itemId === '' || !!item?.paDispOrder
|
: item.itemId === '' || !!item?.paDispOrder
|
||||||
? true
|
? true
|
||||||
: item.openFlg === '1'
|
: item.openFlg === '1'
|
||||||
? true
|
|
||||||
: false
|
|
||||||
}
|
}
|
||||||
onChange={(e) => {
|
onChange={(value) =>{
|
||||||
onChangeSalePrice(e.target.value, item.dispOrder, index)
|
onChangeSalePrice(value, item.dispOrder, index)
|
||||||
}}
|
}}
|
||||||
maxLength={12}
|
maxLength={12}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{item.openFlg === '1' && (
|
{item.openFlg === '1' && (
|
||||||
|
|||||||
@ -845,37 +845,33 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
// 먼저 좌표 업데이트
|
// 먼저 좌표 업데이트
|
||||||
this.setCoords()
|
this.setCoords()
|
||||||
|
|
||||||
// 캔버스 줌과 viewport transform 고려한 좌표 변환
|
// viewport transform만 역변환 (캔버스 줌/팬 보정)
|
||||||
let localPoint = point
|
// 결과는 WORLD 좌표 (캔버스 좌표계)
|
||||||
|
let canvasPoint = point
|
||||||
if (this.canvas) {
|
if (this.canvas) {
|
||||||
const vpt = this.canvas.viewportTransform
|
const vpt = this.canvas.viewportTransform
|
||||||
if (vpt) {
|
if (vpt) {
|
||||||
// viewport transform 역변환
|
|
||||||
const inverted = fabric.util.invertTransform(vpt)
|
const inverted = fabric.util.invertTransform(vpt)
|
||||||
localPoint = fabric.util.transformPoint(point, inverted)
|
canvasPoint = fabric.util.transformPoint(point, inverted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 오브젝트의 transform matrix를 고려한 좌표 변환
|
// canvasPoint는 WORLD 좌표
|
||||||
const matrix = this.calcTransformMatrix()
|
// inPolygonImproved에서 getCurrentPoints()도 WORLD 좌표를 반환
|
||||||
const invertedMatrix = fabric.util.invertTransform(matrix)
|
// 따라서 좌표 시스템이 일치함
|
||||||
const transformedPoint = fabric.util.transformPoint(localPoint, invertedMatrix)
|
const checkPoint = {
|
||||||
|
x: Number(canvasPoint.x.toFixed(this.toFixed)),
|
||||||
// pathOffset을 고려한 최종 좌표 계산
|
y: Number(canvasPoint.y.toFixed(this.toFixed)),
|
||||||
const pathOffset = this.get('pathOffset')
|
|
||||||
const finalPoint = {
|
|
||||||
x: Number((transformedPoint.x + pathOffset.x).toFixed(this.toFixed)),
|
|
||||||
y: Number((transformedPoint.y + pathOffset.y).toFixed(this.toFixed)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.name === POLYGON_TYPE.ROOF && this.isFixed) {
|
if (this.name === POLYGON_TYPE.ROOF && this.isFixed) {
|
||||||
const isInside = this.inPolygonImproved(finalPoint)
|
const isInside = this.inPolygonImproved(checkPoint)
|
||||||
if (!this.selectable) {
|
if (!this.selectable) {
|
||||||
this.set('selectable', isInside)
|
this.set('selectable', isInside)
|
||||||
}
|
}
|
||||||
return isInside
|
return isInside
|
||||||
} else {
|
} else {
|
||||||
return this.inPolygonImproved(finalPoint)
|
return this.inPolygonImproved(checkPoint)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -235,11 +235,23 @@ export default function Module({ setTabNum }) {
|
|||||||
<div className="eaves-keraba-td">
|
<div className="eaves-keraba-td">
|
||||||
<div className="outline-form">
|
<div className="outline-form">
|
||||||
<div className="grid-select mr10">
|
<div className="grid-select mr10">
|
||||||
<input
|
{/*<input*/}
|
||||||
type="text"
|
{/* type="text"*/}
|
||||||
|
{/* className="input-origin block"*/}
|
||||||
|
{/* value={inputVerticalSnowCover}*/}
|
||||||
|
{/* onChange={(e) => setInputVerticalSnowCover(normalizeDecimal(e.target.value))}*/}
|
||||||
|
{/*/>*/}
|
||||||
|
<CalculatorInput
|
||||||
|
id=""
|
||||||
|
name=""
|
||||||
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputVerticalSnowCover}
|
value={inputVerticalSnowCover}
|
||||||
onChange={(e) => setInputVerticalSnowCover(normalizeDecimal(e.target.value))}
|
onChange={(value) => setInputVerticalSnowCover(value)}
|
||||||
|
options={{
|
||||||
|
allowNegative: false,
|
||||||
|
allowDecimal: false
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="thin">cm</span>
|
<span className="thin">cm</span>
|
||||||
|
|||||||
@ -638,7 +638,7 @@ export const Orientation = forwardRef((props, ref) => {
|
|||||||
name=""
|
name=""
|
||||||
label=""
|
label=""
|
||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={inputInstallHeight}
|
value={inputVerticalSnowCover}
|
||||||
onChange={(value) => handleChangeVerticalSnowCover(value)}
|
onChange={(value) => handleChangeVerticalSnowCover(value)}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: false,
|
allowNegative: false,
|
||||||
|
|||||||
@ -5,12 +5,13 @@ import StepUp from '@/components/floor-plan/modal/circuitTrestle/step/StepUp'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { usePopup } from '@/hooks/usePopup'
|
import { usePopup } from '@/hooks/usePopup'
|
||||||
import PassivityCircuitAllocation from './step/type/PassivityCircuitAllocation'
|
import PassivityCircuitAllocation from './step/type/PassivityCircuitAllocation'
|
||||||
|
import BasicSetting from '@/components/floor-plan/modal/basic/BasicSetting'
|
||||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
|
||||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
||||||
import { POLYGON_TYPE } from '@/common/common'
|
import { POLYGON_TYPE, MENU } from '@/common/common'
|
||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { canvasState, canvasZoomState } from '@/store/canvasAtom'
|
import { canvasState, canvasZoomState, currentMenuState } from '@/store/canvasAtom'
|
||||||
|
|
||||||
import { useTrestle } from '@/hooks/module/useTrestle'
|
import { useTrestle } from '@/hooks/module/useTrestle'
|
||||||
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
|
import { moduleSelectionDataState, selectedModuleState } from '@/store/selectedModuleOptions'
|
||||||
@ -29,11 +30,12 @@ const ALLOCATION_TYPE = {
|
|||||||
}
|
}
|
||||||
export default function CircuitTrestleSetting({ id }) {
|
export default function CircuitTrestleSetting({ id }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { closePopup } = usePopup()
|
const { closePopup, addPopup } = usePopup()
|
||||||
const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle, setAllModuleSurfaceIsComplete } = useTrestle()
|
const { apply, setViewCircuitNumberTexts, getEstimateData, clear: clearTrestle, setAllModuleSurfaceIsComplete } = useTrestle()
|
||||||
const { swalFire } = useSwal()
|
const { swalFire } = useSwal()
|
||||||
const { saveEstimate } = useEstimate()
|
const { saveEstimate } = useEstimate()
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
||||||
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
const [canvasZoom, setCanvasZoom] = useRecoilState(canvasZoomState)
|
||||||
const [tabNum, setTabNum] = useState(1)
|
const [tabNum, setTabNum] = useState(1)
|
||||||
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
|
const [allocationType, setAllocationType] = useState(ALLOCATION_TYPE.AUTO)
|
||||||
@ -106,6 +108,167 @@ export default function CircuitTrestleSetting({ id }) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
// 모듈이 설치된 경우 rack설치 여부에 따라 설치 된 모듈 아래에 작은 모듈이 설치되어 있을 경우는 모듈 설치 메뉴 reopen
|
||||||
|
useEffect(() => {
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
if (modules.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 랙 설치 시 모듈 크기 검증
|
||||||
|
* - 남쪽: 아래쪽 모듈이 위쪽 모듈보다 커야 함
|
||||||
|
* - 북쪽: 위쪽 모듈이 아래쪽 모듈보다 커야 함
|
||||||
|
* - 동쪽: 오른쪽 모듈이 왼쪽 모듈보다 커야 함
|
||||||
|
* - 서쪽: 왼쪽 모듈이 오른쪽 모듈보다 커야 함
|
||||||
|
*/
|
||||||
|
const validateModuleSizeForRack = (surface) => {
|
||||||
|
const { modules, direction, trestleDetail } = surface
|
||||||
|
const { rackYn, moduleIntvlHor, moduleIntvlVer } = trestleDetail
|
||||||
|
|
||||||
|
if (rackYn === 'N' || !modules || modules.length < 2) {
|
||||||
|
return true // 검증 통과
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모듈 중심점 및 크기 정보 계산
|
||||||
|
const centerPoints = modules.map((module) => {
|
||||||
|
const { x, y } = module.getCenterPoint()
|
||||||
|
const { width, height } = module
|
||||||
|
return {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width: Math.floor(width),
|
||||||
|
height: Math.floor(height),
|
||||||
|
area: Math.floor(width) * Math.floor(height),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 방향별 설정
|
||||||
|
const isVertical = direction === 'south' || direction === 'north'
|
||||||
|
const primaryInterval = isVertical ? moduleIntvlVer : moduleIntvlHor
|
||||||
|
const secondaryInterval = isVertical ? moduleIntvlHor : moduleIntvlVer
|
||||||
|
|
||||||
|
// 정렬 함수: 큰 모듈이 있어야 할 위치부터 시작
|
||||||
|
const getSortFn = () => {
|
||||||
|
switch (direction) {
|
||||||
|
case 'south': return (a, b) => b.y - a.y // 아래쪽(y 큼)부터
|
||||||
|
case 'north': return (a, b) => a.y - b.y // 위쪽(y 작음)부터
|
||||||
|
case 'east': return (a, b) => b.x - a.x // 오른쪽(x 큼)부터
|
||||||
|
case 'west': return (a, b) => a.x - b.x // 왼쪽(x 작음)부터
|
||||||
|
default: return () => 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 타겟 모듈 찾기 (현재 모듈보다 작아야 할 위치의 모듈)
|
||||||
|
const findTargetModules = (current, margin) => {
|
||||||
|
return centerPoints.filter(cp => {
|
||||||
|
const sameAxis = isVertical
|
||||||
|
? Math.abs(cp.x - current.x) < margin
|
||||||
|
: Math.abs(cp.y - current.y) < margin
|
||||||
|
const targetDirection = direction === 'south' ? cp.y < current.y
|
||||||
|
: direction === 'north' ? cp.y > current.y
|
||||||
|
: direction === 'east' ? cp.x < current.x
|
||||||
|
: cp.x > current.x
|
||||||
|
return sameAxis && targetDirection
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 가장 가까운 타겟 모듈 찾기
|
||||||
|
const getClosestTarget = (filtered) => {
|
||||||
|
if (filtered.length === 0) return null
|
||||||
|
return filtered.reduce((closest, cp) => {
|
||||||
|
switch (direction) {
|
||||||
|
case 'south': return cp.y > closest.y ? cp : closest
|
||||||
|
case 'north': return cp.y < closest.y ? cp : closest
|
||||||
|
case 'east': return cp.x > closest.x ? cp : closest
|
||||||
|
case 'west': return cp.x < closest.x ? cp : closest
|
||||||
|
default: return closest
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 두 모듈 간 간격 계산
|
||||||
|
const getGap = (current, target) => {
|
||||||
|
if (isVertical) {
|
||||||
|
return direction === 'south'
|
||||||
|
? (current.y - current.height / 2) - (target.y + target.height / 2)
|
||||||
|
: (target.y - target.height / 2) - (current.y + current.height / 2)
|
||||||
|
} else {
|
||||||
|
return direction === 'east'
|
||||||
|
? (current.x - current.width / 2) - (target.x + target.width / 2)
|
||||||
|
: (target.x - target.width / 2) - (current.x + current.width / 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 인접 모듈 여부 확인
|
||||||
|
const isAdjacent = (current, target) => {
|
||||||
|
const gap = getGap(current, target)
|
||||||
|
return gap >= 0 && gap <= primaryInterval + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 정렬된 모듈 순회
|
||||||
|
const sortedPoints = [...centerPoints].sort(getSortFn())
|
||||||
|
|
||||||
|
for (const current of sortedPoints) {
|
||||||
|
// 1. 일반 배치: 같은 라인에서 인접 모듈 검사
|
||||||
|
const directTargets = findTargetModules(current, secondaryInterval)
|
||||||
|
const closestTarget = getClosestTarget(directTargets)
|
||||||
|
|
||||||
|
if (closestTarget && isAdjacent(current, closestTarget) && closestTarget.area > current.area) {
|
||||||
|
return false // 검증 실패
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 물떼새 배치: 반 오프셋 위치의 인접 모듈 검사
|
||||||
|
const size = isVertical ? current.width : current.height
|
||||||
|
const halfOffset = (size + secondaryInterval) / 2
|
||||||
|
|
||||||
|
for (const sign of [-1, 1]) {
|
||||||
|
const offsetValue = sign * halfOffset
|
||||||
|
const findHalfTarget = centerPoints.filter((cp) => {
|
||||||
|
const offsetAxis = isVertical
|
||||||
|
? Math.abs(cp.x - (current.x + offsetValue)) <= primaryInterval
|
||||||
|
: Math.abs(cp.y - (current.y + offsetValue)) <= primaryInterval
|
||||||
|
const targetDirection = direction === 'south' ? cp.y < current.y
|
||||||
|
: direction === 'north' ? cp.y > current.y
|
||||||
|
: direction === 'east' ? cp.x < current.x
|
||||||
|
: cp.x > current.x
|
||||||
|
return offsetAxis && targetDirection
|
||||||
|
})
|
||||||
|
|
||||||
|
const closestHalf = getClosestTarget(findHalfTarget)
|
||||||
|
if (closestHalf && isAdjacent(current, closestHalf) && closestHalf.area > current.area) {
|
||||||
|
return false // 검증 실패
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true // 검증 통과
|
||||||
|
}
|
||||||
|
|
||||||
|
// 모든 설치면에 대해 검증 수행
|
||||||
|
const moduleSetupSurfaces = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||||
|
for (const surface of moduleSetupSurfaces) {
|
||||||
|
if (!validateModuleSizeForRack(surface)) {
|
||||||
|
swalFire({
|
||||||
|
text: getMessage('module.size.validation.rack.error'),
|
||||||
|
icon: 'error',
|
||||||
|
confirmFn: () => {
|
||||||
|
// 현재 팝업 닫기
|
||||||
|
closePopup(id)
|
||||||
|
// 메뉴 하이라이트 변경
|
||||||
|
setCurrentMenu(MENU.MODULE_CIRCUIT_SETTING.BASIC_SETTING)
|
||||||
|
// 모듈/가대설정 팝업 열기
|
||||||
|
const newPopupId = uuidv4()
|
||||||
|
clearTrestle()
|
||||||
|
setAllModuleSurfaceIsComplete(false)
|
||||||
|
addPopup(newPopupId, 1, <BasicSetting id={newPopupId} />)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
const capture = async (type) => {
|
const capture = async (type) => {
|
||||||
beforeCapture(type)
|
beforeCapture(type)
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
import { GlobalDataContext } from '@/app/GlobalDataProvider'
|
|
||||||
import QSelectBox from '@/components/common/select/QSelectBox'
|
import QSelectBox from '@/components/common/select/QSelectBox'
|
||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { modelState, pcsCheckState } from '@/store/circuitTrestleAtom'
|
import { pcsCheckState } from '@/store/circuitTrestleAtom'
|
||||||
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
import { selectedModuleState } from '@/store/selectedModuleOptions'
|
||||||
import { useContext, useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { useCanvasPopupStatusController } from '@/hooks/common/useCanvasPopupStatusController'
|
|
||||||
import { canvasPopupStatusStore } from '@/store/canvasPopupStatusAtom'
|
|
||||||
import { useMasterController } from '@/hooks/common/useMasterController'
|
import { useMasterController } from '@/hooks/common/useMasterController'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
import { globalLocaleStore } from '@/store/localeAtom'
|
import { globalLocaleStore } from '@/store/localeAtom'
|
||||||
@ -15,7 +12,6 @@ import { POLYGON_TYPE } from '@/common/common'
|
|||||||
import { useSwal } from '@/hooks/useSwal'
|
import { useSwal } from '@/hooks/useSwal'
|
||||||
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
import { circuitNumDisplaySelector } from '@/store/settingAtom'
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { PCS_MKR_MULTI_TYPE } from './PowerConditionalSelect'
|
|
||||||
|
|
||||||
export default function StepUp(props) {
|
export default function StepUp(props) {
|
||||||
const {
|
const {
|
||||||
@ -42,6 +38,7 @@ export default function StepUp(props) {
|
|||||||
const [arrayLength, setArrayLength] = useState(3) //module-table-inner의 반복 개수
|
const [arrayLength, setArrayLength] = useState(3) //module-table-inner의 반복 개수
|
||||||
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
|
const [pcsCheck, setPcsCheck] = useRecoilState(pcsCheckState)
|
||||||
const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk, getPcsConnOptionItemList } = useMasterController()
|
const { getPcsVoltageStepUpList, getPcsAutoRecommendList, getPcsVoltageChk, getPcsConnOptionItemList } = useMasterController()
|
||||||
|
const [originPcsVoltageStepUpList, setOriginPcsVoltageStepUpList] = useState([])
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
const selectedModules = useRecoilValue(selectedModuleState)
|
const selectedModules = useRecoilValue(selectedModuleState)
|
||||||
const [optCodes, setOptCodes] = useState([])
|
const [optCodes, setOptCodes] = useState([])
|
||||||
@ -100,6 +97,9 @@ export default function StepUp(props) {
|
|||||||
|
|
||||||
/** PCS 승압설정 정보 SET */
|
/** PCS 승압설정 정보 SET */
|
||||||
setStepUpListData(stepUpListData)
|
setStepUpListData(stepUpListData)
|
||||||
|
if (originPcsVoltageStepUpList.length === 0) {
|
||||||
|
setOriginPcsVoltageStepUpList(stepUpListData)
|
||||||
|
}
|
||||||
|
|
||||||
/** PCS 옵션 조회 */
|
/** PCS 옵션 조회 */
|
||||||
// const formattedOptCodes = formatOptionCodes(res.data.optionList)
|
// const formattedOptCodes = formatOptionCodes(res.data.optionList)
|
||||||
@ -108,8 +108,7 @@ export default function StepUp(props) {
|
|||||||
|
|
||||||
/** 캔버스에 회로 정보 적용 */
|
/** 캔버스에 회로 정보 적용 */
|
||||||
// 병설일때 pcs 있으면 setSubOpsions, 없으면 setMainOptions
|
// 병설일때 pcs 있으면 setSubOpsions, 없으면 setMainOptions
|
||||||
console.log('stepUpListData', stepUpListData)
|
let mChk = 0
|
||||||
let mChk = 0;
|
|
||||||
stepUpListData[0].pcsItemList.forEach((pcsItem, index) => {
|
stepUpListData[0].pcsItemList.forEach((pcsItem, index) => {
|
||||||
const optionList = formatOptionCodes(pcsItem.optionList)
|
const optionList = formatOptionCodes(pcsItem.optionList)
|
||||||
if (isMultiOptions()) {
|
if (isMultiOptions()) {
|
||||||
@ -166,7 +165,7 @@ export default function StepUp(props) {
|
|||||||
targetModule.circuitNumber = module.circuit
|
targetModule.circuitNumber = module.circuit
|
||||||
canvas.add(moduleCircuitText)
|
canvas.add(moduleCircuitText)
|
||||||
} else {
|
} else {
|
||||||
mChk++;
|
mChk++
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -399,10 +398,14 @@ export default function StepUp(props) {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleChangeApplyParalQty = (mainIdx, subIdx, applyParalQty) => {
|
||||||
|
handleRowClick(mainIdx, subIdx, applyParalQty)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 행 선택 핸들러 함수 추가
|
* 행 선택 핸들러 함수 추가
|
||||||
*/
|
*/
|
||||||
const handleRowClick = (mainIdx, subIdx) => {
|
const handleRowClick = (mainIdx, subIdx, applyParalQty = null) => {
|
||||||
/** 자동 승압 설정인 경우만 실행 */
|
/** 자동 승압 설정인 경우만 실행 */
|
||||||
if (allocationType !== 'auto') return
|
if (allocationType !== 'auto') return
|
||||||
|
|
||||||
@ -434,7 +437,13 @@ export default function StepUp(props) {
|
|||||||
|
|
||||||
/** 선택된 serQty 찾기 */
|
/** 선택된 serQty 찾기 */
|
||||||
const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0
|
const selectedSerQty = matchingPcsItem?.serQtyList.find((serQty) => serQty.selected)?.serQty || 0
|
||||||
|
if (index === 0) {
|
||||||
|
return {
|
||||||
|
...pcsItem,
|
||||||
|
applySerQty: selectedSerQty,
|
||||||
|
applyParalQty: +applyParalQty,
|
||||||
|
}
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...pcsItem,
|
...pcsItem,
|
||||||
applySerQty: selectedSerQty,
|
applySerQty: selectedSerQty,
|
||||||
@ -645,15 +654,49 @@ export default function StepUp(props) {
|
|||||||
<tr
|
<tr
|
||||||
key={`row-${serQtyIdx}`}
|
key={`row-${serQtyIdx}`}
|
||||||
className={`${item.selected ? 'on' : ''}`}
|
className={`${item.selected ? 'on' : ''}`}
|
||||||
onClick={() => handleRowClick(idx, serQtyIdx)}
|
|
||||||
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
style={{ cursor: allocationType === 'auto' ? 'pointer' : 'default' }}
|
||||||
>
|
>
|
||||||
<td className="al-r">{item.serQty}</td>
|
<td
|
||||||
|
className="al-r"
|
||||||
|
onClick={() => {
|
||||||
|
handleRowClick(idx, serQtyIdx, item.paralQty)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.serQty}
|
||||||
|
</td>
|
||||||
<td className="al-r">
|
<td className="al-r">
|
||||||
{/* 2025.12.04 select 추가 */}
|
{/* 2025.12.04 select 추가 */}
|
||||||
<select className="select-light dark table-select" name="" id="">
|
{idx === 0 ? (
|
||||||
<option value="">{item.paralQty}</option>
|
<select
|
||||||
|
className="select-light dark table-select"
|
||||||
|
defaultValue={item.paralQty}
|
||||||
|
name=""
|
||||||
|
id=""
|
||||||
|
onChange={(e) => {
|
||||||
|
handleChangeApplyParalQty(idx, serQtyIdx, e.target.value)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item.paralQty === 0 && (
|
||||||
|
<option key="0" value="0">
|
||||||
|
0
|
||||||
|
</option>
|
||||||
|
)}
|
||||||
|
{Array.from(
|
||||||
|
{
|
||||||
|
length: originPcsVoltageStepUpList[index]
|
||||||
|
? originPcsVoltageStepUpList[index]?.pcsItemList[idx].serQtyList[serQtyIdx].paralQty
|
||||||
|
: item.paralQty,
|
||||||
|
},
|
||||||
|
(_, i) => i + 1,
|
||||||
|
).map((num) => (
|
||||||
|
<option key={num} value={num}>
|
||||||
|
{num}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
</select>
|
</select>
|
||||||
|
) : (
|
||||||
|
<>{item.paralQty}</>
|
||||||
|
)}
|
||||||
</td>
|
</td>
|
||||||
{/* <td className="al-r">{item.paralQty}</td> */}
|
{/* <td className="al-r">{item.paralQty}</td> */}
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -103,17 +103,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||||
})
|
})
|
||||||
|
|
||||||
if (surfaceList.length > 1) {
|
|
||||||
if (Object.keys(surfaceType).length > 1) {
|
|
||||||
swalFire({
|
|
||||||
text: getMessage('module.circuit.fix.not.same.roof.error'),
|
|
||||||
type: 'alert',
|
|
||||||
icon: 'warning',
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!circuitNumber || circuitNumber === 0) {
|
if (!circuitNumber || circuitNumber === 0) {
|
||||||
swalFire({
|
swalFire({
|
||||||
text: getMessage('module.circuit.minimun.error'),
|
text: getMessage('module.circuit.minimun.error'),
|
||||||
@ -146,6 +135,10 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
surfaceType[`${surface.direction}-${surface.roofMaterial.pitch}`] = surface
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'OUTDMULTI': {
|
||||||
if (surfaceList.length > 1) {
|
if (surfaceList.length > 1) {
|
||||||
if (Object.keys(surfaceType).length > 1) {
|
if (Object.keys(surfaceType).length > 1) {
|
||||||
swalFire({
|
swalFire({
|
||||||
@ -156,10 +149,6 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 'OUTDMULTI': {
|
|
||||||
if (selectedModels.length > 1) {
|
if (selectedModels.length > 1) {
|
||||||
let result = false
|
let result = false
|
||||||
|
|
||||||
|
|||||||
@ -84,6 +84,7 @@ export function useModule() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const surfaceId = selectedModules[0].surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.move.module'),
|
title: getMessage('can.not.move.module'),
|
||||||
@ -96,11 +97,15 @@ export function useModule() {
|
|||||||
top: module.originCoords.top,
|
top: module.originCoords.top,
|
||||||
fill: module.originCoords.fill,
|
fill: module.originCoords.fill,
|
||||||
})
|
})
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,6 +162,7 @@ export function useModule() {
|
|||||||
activeModule.set({ strokeWidth: 3 })
|
activeModule.set({ strokeWidth: 3 })
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.move.module'),
|
title: getMessage('can.not.move.module'),
|
||||||
@ -165,11 +171,15 @@ export function useModule() {
|
|||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,6 +212,7 @@ export function useModule() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = surface.id
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.move.module'),
|
title: getMessage('can.not.move.module'),
|
||||||
@ -210,11 +221,15 @@ export function useModule() {
|
|||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -269,6 +284,7 @@ export function useModule() {
|
|||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const surfaceId = surface.id
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.copy.module'),
|
title: getMessage('can.not.copy.module'),
|
||||||
@ -276,11 +292,13 @@ export function useModule() {
|
|||||||
type: 'alert',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.remove(...copyModules)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
surface.set({ modules: [...surface.modules, ...copyModules] })
|
surface.set({ modules: [...surface.modules, ...copyModules] })
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -333,6 +351,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const surfaceId = modules[0].surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.copy.module'),
|
title: getMessage('can.not.copy.module'),
|
||||||
@ -340,11 +359,13 @@ export function useModule() {
|
|||||||
type: 'alert',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.remove(...copyModules)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
}
|
}
|
||||||
@ -426,6 +447,7 @@ export function useModule() {
|
|||||||
})
|
})
|
||||||
activeModule.set({ strokeWidth: 3 })
|
activeModule.set({ strokeWidth: 3 })
|
||||||
|
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.copy.module'),
|
title: getMessage('can.not.copy.module'),
|
||||||
@ -433,12 +455,14 @@ export function useModule() {
|
|||||||
type: 'alert',
|
type: 'alert',
|
||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
canvas.remove(...copyModules)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
moduleSetupSurface.set({ modules: [...moduleSetupSurface.modules, ...copyModules] })
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +501,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (width === -1) width = module.left - activeModule.left
|
if (width === -1) width = module.left - activeModule.left
|
||||||
module.set({ left: module.left - width })
|
module.set({ left: module.left - width })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
if (isOverlapOtherModules(module, leftModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
if (isOverlapOtherModules(module, leftModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
@ -484,7 +509,7 @@ export function useModule() {
|
|||||||
isWarning = true
|
isWarning = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
targetModules = rightModules
|
targetModules = rightModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
} else if (type === MODULE_REMOVE_TYPE.RIGHT) {
|
||||||
leftModules.forEach((module) => {
|
leftModules.forEach((module) => {
|
||||||
@ -495,6 +520,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (width === -1) width = activeModule.left - module.left
|
if (width === -1) width = activeModule.left - module.left
|
||||||
module.set({ left: module.left + width })
|
module.set({ left: module.left + width })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
if (isOverlapOtherModules(module, rightModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
if (isOverlapOtherModules(module, rightModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
@ -502,7 +528,7 @@ export function useModule() {
|
|||||||
isWarning = true
|
isWarning = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
targetModules = leftModules
|
targetModules = leftModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
} else if (type === MODULE_REMOVE_TYPE.HORIZONTAL_SIDE) {
|
||||||
const sideModules = [...leftModules, ...rightModules]
|
const sideModules = [...leftModules, ...rightModules]
|
||||||
@ -514,6 +540,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (width === -1) width = activeModule.left - module.left
|
if (width === -1) width = activeModule.left - module.left
|
||||||
module.set({ left: module.left + width / 2 })
|
module.set({ left: module.left + width / 2 })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
@ -526,6 +553,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (width === -1) width = module.left - activeModule.left
|
if (width === -1) width = module.left - activeModule.left
|
||||||
module.set({ left: module.left - width / 2 })
|
module.set({ left: module.left - width / 2 })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
})
|
})
|
||||||
@ -547,6 +575,7 @@ export function useModule() {
|
|||||||
targetModules = sideModules
|
targetModules = sideModules
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.remove.module'),
|
title: getMessage('can.not.remove.module'),
|
||||||
@ -557,17 +586,24 @@ export function useModule() {
|
|||||||
canvas.add(...columnModules)
|
canvas.add(...columnModules)
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
columnModules.forEach((module) => {
|
||||||
|
module.dirty = true
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
moduleSetupSurface.modules = moduleSetupSurface.modules.filter(
|
moduleSetupSurface.modules = moduleSetupSurface.modules.filter(
|
||||||
(module) => !columnModules.map((copyModule) => copyModule.id).includes(module.id),
|
(module) => !columnModules.map((copyModule) => copyModule.id).includes(module.id),
|
||||||
)
|
)
|
||||||
}
|
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleRowRemove = (type) => {
|
const moduleRowRemove = (type) => {
|
||||||
@ -599,6 +635,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (height === -1) height = module.top - activeModule.top
|
if (height === -1) height = module.top - activeModule.top
|
||||||
module.set({ top: module.top - height })
|
module.set({ top: module.top - height })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
if (isOverlapOtherModules(module, topModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
if (isOverlapOtherModules(module, topModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
@ -606,7 +643,7 @@ export function useModule() {
|
|||||||
module.set({ fill: 'red' })
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
targetModules = bottomModules
|
targetModules = bottomModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
} else if (type === MODULE_REMOVE_TYPE.BOTTOM) {
|
||||||
topModules.forEach((module) => {
|
topModules.forEach((module) => {
|
||||||
@ -617,6 +654,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
if (height === -1) height = activeModule.top - module.top
|
if (height === -1) height = activeModule.top - module.top
|
||||||
module.set({ top: module.top + activeModule.height })
|
module.set({ top: module.top + activeModule.height })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
if (isOverlapOtherModules(module, bottomModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
if (isOverlapOtherModules(module, bottomModules) || isOverlapObjects(module, objects) || isOutsideSurface(module, moduleSetupSurface)) {
|
||||||
@ -624,6 +662,7 @@ export function useModule() {
|
|||||||
module.set({ fill: 'red' })
|
module.set({ fill: 'red' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
canvas.requestRenderAll()
|
||||||
targetModules = topModules
|
targetModules = topModules
|
||||||
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
} else if (type === MODULE_REMOVE_TYPE.VERTICAL_SIDE) {
|
||||||
topModules.forEach((module) => {
|
topModules.forEach((module) => {
|
||||||
@ -635,6 +674,7 @@ export function useModule() {
|
|||||||
// if (height === -1) height = activeModule.top - module.top
|
// if (height === -1) height = activeModule.top - module.top
|
||||||
if (height === -1) height = activeModule.height
|
if (height === -1) height = activeModule.height
|
||||||
module.set({ top: module.top + height / 2 })
|
module.set({ top: module.top + height / 2 })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -647,10 +687,11 @@ export function useModule() {
|
|||||||
// if (height === -1) height = module.top - activeModule.top
|
// if (height === -1) height = module.top - activeModule.top
|
||||||
if (height === -1) height = activeModule.height
|
if (height === -1) height = activeModule.height
|
||||||
module.set({ top: module.top - height / 2 })
|
module.set({ top: module.top - height / 2 })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
const sideModules = [...topModules, ...bottomModules]
|
const sideModules = [...topModules, ...bottomModules]
|
||||||
sideModules.forEach((module) => {
|
sideModules.forEach((module) => {
|
||||||
if (
|
if (
|
||||||
@ -668,6 +709,7 @@ export function useModule() {
|
|||||||
targetModules = sideModules
|
targetModules = sideModules
|
||||||
}
|
}
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
if (isWarning && type !== MODULE_REMOVE_TYPE.NONE) {
|
||||||
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
targetModules.forEach((rect) => rect.set({ fill: 'red' }))
|
||||||
swalFire({
|
swalFire({
|
||||||
@ -679,13 +721,20 @@ export function useModule() {
|
|||||||
canvas.add(...rowModules)
|
canvas.add(...rowModules)
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
rowModules.forEach((module) => {
|
||||||
|
module.dirty = true
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleColumnInsert = (type) => {
|
const moduleColumnInsert = (type) => {
|
||||||
@ -756,6 +805,7 @@ export function useModule() {
|
|||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.insert.module'),
|
title: getMessage('can.not.insert.module'),
|
||||||
@ -764,16 +814,19 @@ export function useModule() {
|
|||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.remove(...copyModules)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
moduleSetupSurface.modules = [...moduleSetupSurface.modules, ...copyModules]
|
moduleSetupSurface.modules = [...moduleSetupSurface.modules, ...copyModules]
|
||||||
}
|
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isFixedModule = () => {
|
const isFixedModule = () => {
|
||||||
@ -863,6 +916,7 @@ export function useModule() {
|
|||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
|
||||||
|
const surfaceId = activeModule.surfaceId
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.insert.module'),
|
title: getMessage('can.not.insert.module'),
|
||||||
@ -871,16 +925,19 @@ export function useModule() {
|
|||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
targetModules.forEach((module) => {
|
targetModules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.remove(...copyModules)
|
canvas.remove(...copyModules)
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
moduleSetupSurface.modules = [...moduleSetupSurface.modules, ...copyModules]
|
moduleSetupSurface.modules = [...moduleSetupSurface.modules, ...copyModules]
|
||||||
}
|
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const alignModule = (type, surfaceArray) => {
|
const alignModule = (type, surfaceArray) => {
|
||||||
@ -924,6 +981,7 @@ export function useModule() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
|
const surfaceId = surface.id
|
||||||
if (isWarning) {
|
if (isWarning) {
|
||||||
swalFire({
|
swalFire({
|
||||||
title: getMessage('can.not.align.module'),
|
title: getMessage('can.not.align.module'),
|
||||||
@ -932,11 +990,15 @@ export function useModule() {
|
|||||||
confirmFn: () => {
|
confirmFn: () => {
|
||||||
modules.forEach((module) => {
|
modules.forEach((module) => {
|
||||||
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
module.set({ top: module.originPos.top, left: module.originPos.left, fill: module.originPos.fill })
|
||||||
|
module.dirty = true
|
||||||
module.setCoords()
|
module.setCoords()
|
||||||
})
|
})
|
||||||
canvas.renderAll()
|
canvas.requestRenderAll()
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
recalculateAllModulesCoords(surfaceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -964,6 +1026,7 @@ export function useModule() {
|
|||||||
canvas.remove(activeModule)
|
canvas.remove(activeModule)
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
setModuleStatisticsData()
|
setModuleStatisticsData()
|
||||||
|
recalculateAllModulesCoords(activeModule.surfaceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
const moduleRoofRemove = (surfaceArray) => {
|
const moduleRoofRemove = (surfaceArray) => {
|
||||||
@ -1049,6 +1112,38 @@ export function useModule() {
|
|||||||
removeTrestleMaterials()
|
removeTrestleMaterials()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모든 모듈의 좌표를 재계산
|
||||||
|
* 열/단 삭제, 복사, 추가 후 호출하여 선택 영역(bounding box)을 업데이트
|
||||||
|
* @param {string} surfaceId - 특정 surface의 모듈만 재계산 (선택적)
|
||||||
|
*/
|
||||||
|
const recalculateAllModulesCoords = (surfaceId = null) => {
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
|
const modules = canvas
|
||||||
|
.getObjects()
|
||||||
|
.filter((obj) => obj.name === POLYGON_TYPE.MODULE)
|
||||||
|
.filter((obj) => (surfaceId ? obj.surfaceId === surfaceId : true))
|
||||||
|
|
||||||
|
// 모듈의 캐시를 초기화하고 좌표 재계산
|
||||||
|
modules.forEach((module) => {
|
||||||
|
// Fabric.js 내부 캐시 초기화
|
||||||
|
delete module.oCoords
|
||||||
|
delete module.aCoords
|
||||||
|
delete module.lineCoords
|
||||||
|
delete module.__corner
|
||||||
|
delete module.matrixCache
|
||||||
|
delete module.ownMatrixCache
|
||||||
|
|
||||||
|
// dirty 플래그 설정 및 좌표 재계산
|
||||||
|
module.dirty = true
|
||||||
|
module.setCoords()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 렌더링
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
moduleMove,
|
moduleMove,
|
||||||
moduleMultiMove,
|
moduleMultiMove,
|
||||||
@ -1063,5 +1158,6 @@ export function useModule() {
|
|||||||
modulesRemove,
|
modulesRemove,
|
||||||
moduleRoofRemove,
|
moduleRoofRemove,
|
||||||
alignModule,
|
alignModule,
|
||||||
|
recalculateAllModulesCoords,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -123,6 +123,7 @@ export function useModuleBasicSetting(tabNum) {
|
|||||||
.getObjects()
|
.getObjects()
|
||||||
.filter((roof) => roof.name === POLYGON_TYPE.ROOF)
|
.filter((roof) => roof.name === POLYGON_TYPE.ROOF)
|
||||||
.forEach((roof) => {
|
.forEach((roof) => {
|
||||||
|
changeLineType(roof)
|
||||||
if (!roof.roofMaterial) return
|
if (!roof.roofMaterial) return
|
||||||
const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번
|
const roofIndex = roof.roofMaterial.index //지붕의 지붕재의 순번
|
||||||
|
|
||||||
@ -168,6 +169,61 @@ export function useModuleBasicSetting(tabNum) {
|
|||||||
}
|
}
|
||||||
}, [trestleDetailList])
|
}, [trestleDetailList])
|
||||||
|
|
||||||
|
const changeLineType = (polygon) => {
|
||||||
|
if (!polygon || !polygon.lines || polygon.lines.length === 0) return
|
||||||
|
|
||||||
|
const direction = polygon.direction
|
||||||
|
|
||||||
|
// 1. 모든 라인을 케라바(GABLE)로 초기화
|
||||||
|
polygon.lines.forEach((line) => {
|
||||||
|
line.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
type: LINE_TYPE.WALLLINE.GABLE,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 방향에 따른 좌표 설정
|
||||||
|
const directionConfig = {
|
||||||
|
south: { coord1: 'y1', coord2: 'y2', findExtreme: Math.max },
|
||||||
|
north: { coord1: 'y1', coord2: 'y2', findExtreme: Math.min },
|
||||||
|
east: { coord1: 'x1', coord2: 'x2', findExtreme: Math.max },
|
||||||
|
west: { coord1: 'x1', coord2: 'x2', findExtreme: Math.min },
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = directionConfig[direction] || directionConfig.south
|
||||||
|
const { coord1, coord2, findExtreme } = config
|
||||||
|
|
||||||
|
// 2. 직선만 필터링 (대각선 제외)
|
||||||
|
// 남/북: y1 === y2 인 경우 수평 직선
|
||||||
|
// 동/서: x1 === x2 인 경우 수직 직선
|
||||||
|
const straightLines = polygon.lines.filter((line) => line[coord1] === line[coord2])
|
||||||
|
|
||||||
|
if (straightLines.length === 0) return
|
||||||
|
|
||||||
|
// 3. 가장 끝에 있는 직선 찾기
|
||||||
|
// 남쪽: 가장 하단 (y값이 가장 큰), 북쪽: 가장 상단 (y값이 가장 작은)
|
||||||
|
// 동쪽: 가장 오른쪽 (x값이 가장 큰), 서쪽: 가장 왼쪽 (x값이 가장 작은)
|
||||||
|
const extremeValue = findExtreme(...straightLines.map((line) => line[coord1]))
|
||||||
|
const eavesLines = straightLines.filter((line) => line[coord1] === extremeValue)
|
||||||
|
|
||||||
|
// 4. 직선에 대해 타입 설정
|
||||||
|
straightLines.forEach((line) => {
|
||||||
|
if (eavesLines.includes(line)) {
|
||||||
|
// 가장 끝에 있는 직선은 eaves
|
||||||
|
line.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
type: LINE_TYPE.WALLLINE.EAVES,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 나머지 직선은 ridge
|
||||||
|
line.attributes = {
|
||||||
|
...line.attributes,
|
||||||
|
type: LINE_TYPE.SUBLINE.RIDGE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const roofOutlineColor = (roofIndex) => {
|
const roofOutlineColor = (roofIndex) => {
|
||||||
if (roofIndex === 1) {
|
if (roofIndex === 1) {
|
||||||
return '#FFC000'
|
return '#FFC000'
|
||||||
@ -267,14 +323,14 @@ export function useModuleBasicSetting(tabNum) {
|
|||||||
//도머일때
|
//도머일때
|
||||||
if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) {
|
if (obj.name === BATCH_TYPE.TRIANGLE_DORMER || obj.name === BATCH_TYPE.PENTAGON_DORMER) {
|
||||||
const groupPoints = obj.getCurrentPoints()
|
const groupPoints = obj.getCurrentPoints()
|
||||||
const offsetObjects = offsetPolygon(groupPoints, 10)
|
const offsetObjects = offsetPolygon(groupPoints, 30)
|
||||||
const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions)
|
const dormerOffset = new QPolygon(offsetObjects, batchObjectOptions)
|
||||||
dormerOffset.setViewLengthText(false)
|
dormerOffset.setViewLengthText(false)
|
||||||
canvas.add(dormerOffset) //모듈설치면 만들기
|
canvas.add(dormerOffset) //모듈설치면 만들기
|
||||||
} else {
|
} else {
|
||||||
//개구, 그림자일때
|
//개구, 그림자일때
|
||||||
const points = obj.getCurrentPoints()
|
const points = obj.getCurrentPoints()
|
||||||
const offsetObjects = offsetPolygon(points, 10)
|
const offsetObjects = offsetPolygon(points, 30)
|
||||||
const offset = new QPolygon(offsetObjects, batchObjectOptions)
|
const offset = new QPolygon(offsetObjects, batchObjectOptions)
|
||||||
offset.setViewLengthText(false)
|
offset.setViewLengthText(false)
|
||||||
canvas.add(offset) //모듈설치면 만들기
|
canvas.add(offset) //모듈설치면 만들기
|
||||||
|
|||||||
@ -316,12 +316,13 @@ export function useRoofAllocationSetting(id) {
|
|||||||
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
|
||||||
} else {
|
} else {
|
||||||
apply()
|
apply()
|
||||||
//기존 지붕 선은 남겨둔다.
|
|
||||||
drawOriginRoofLine()
|
|
||||||
resetPoints()
|
resetPoints()
|
||||||
|
|
||||||
basicSettingSave()
|
basicSettingSave()
|
||||||
}
|
}
|
||||||
|
//기존 지붕 선은 남겨둔다.
|
||||||
|
drawOriginRoofLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawOriginRoofLine = () => {
|
const drawOriginRoofLine = () => {
|
||||||
@ -473,7 +474,20 @@ export function useRoofAllocationSetting(id) {
|
|||||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||||
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
||||||
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
||||||
roofBase.lines = [...newEaveLines]
|
// Filter out lines from roofBase.lines that share any points with newEaveLines
|
||||||
|
const linesToKeep = roofBase.lines.filter(roofLine => {
|
||||||
|
return !newEaveLines.some(eaveLine => {
|
||||||
|
// Check if any endpoint of roofLine matches any endpoint of eaveLine
|
||||||
|
return (
|
||||||
|
// Check if any endpoint of roofLine matches any endpoint of eaveLine
|
||||||
|
(Math.abs(roofLine.x1 - eaveLine.x1) < 0.1 && Math.abs(roofLine.y1 - eaveLine.y1) < 0.1) || // p1 matches p1
|
||||||
|
(Math.abs(roofLine.x2 - eaveLine.x2) < 0.1 && Math.abs(roofLine.y2 - eaveLine.y2) < 0.1) // p2 matches p2
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Combine remaining lines with newEaveLines
|
||||||
|
roofBase.lines = [...linesToKeep, ...newEaveLines];
|
||||||
} else {
|
} else {
|
||||||
roofBase.lines = [...roofEaveHelpLines]
|
roofBase.lines = [...roofEaveHelpLines]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,6 +50,10 @@ export function useCanvasEvent() {
|
|||||||
|
|
||||||
if (target) {
|
if (target) {
|
||||||
// settleDown(target)
|
// settleDown(target)
|
||||||
|
// roof 이동 후 좌표 재계산
|
||||||
|
if (target.name === POLYGON_TYPE.ROOF && target.type === 'QPolygon') {
|
||||||
|
target.fire('polygonMoved')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addEvent: (e) => {
|
addEvent: (e) => {
|
||||||
|
|||||||
@ -91,6 +91,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
return {
|
return {
|
||||||
itemId: m.itemId,
|
itemId: m.itemId,
|
||||||
mixMatlNo: m.mixMatlNo,
|
mixMatlNo: m.mixMatlNo,
|
||||||
|
northModuleYn: m.northModuleYn,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -355,6 +355,12 @@ export function useContextMenu() {
|
|||||||
canvas.remove(line)
|
canvas.remove(line)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
//동이동현이동
|
||||||
|
const eaveHelpLines = canvas.getObjects().filter((obj) => obj.name === 'eaveHelpLine' && obj.parentId === currentObject.attributes.roofId)
|
||||||
|
eaveHelpLines.forEach((line) => {
|
||||||
|
canvas.remove(line)
|
||||||
|
})
|
||||||
|
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -134,6 +134,7 @@
|
|||||||
"modal.module.basic.settting.module.error10": "棟側の配置領域の値を{0} mm以上に変更してください。\n(屋根材: {1})",
|
"modal.module.basic.settting.module.error10": "棟側の配置領域の値を{0} mm以上に変更してください。\n(屋根材: {1})",
|
||||||
"modal.module.basic.settting.module.error11": "ケラバ側の配置領域の値を{0} mm以上に変更してください。\n(屋根材: {1})",
|
"modal.module.basic.settting.module.error11": "ケラバ側の配置領域の値を{0} mm以上に変更してください。\n(屋根材: {1})",
|
||||||
"modal.module.basic.settting.module.error12": "施工方法を選択してください。\n(屋根材: {0})",
|
"modal.module.basic.settting.module.error12": "施工方法を選択してください。\n(屋根材: {0})",
|
||||||
|
"module.size.validation.rack.error": "モジュール配置が不正です。 正しく配置し直してください。",
|
||||||
"modal.module.basic.setting.module.placement": "モジュールの配置",
|
"modal.module.basic.setting.module.placement": "モジュールの配置",
|
||||||
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
|
"modal.module.basic.setting.module.placement.select.fitting.type": "設置形態を選択してください。",
|
||||||
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
|
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "千鳥配置",
|
||||||
|
|||||||
@ -134,6 +134,7 @@
|
|||||||
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
|
"modal.module.basic.settting.module.error10": "용마루쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
|
||||||
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
|
"modal.module.basic.settting.module.error11": "케라바쪽 값은 {0}mm 이상이어야 합니다.\n(지붕재: {1})",
|
||||||
"modal.module.basic.settting.module.error12": "시공법을 선택해주세요.\n(지붕재: {0})",
|
"modal.module.basic.settting.module.error12": "시공법을 선택해주세요.\n(지붕재: {0})",
|
||||||
|
"module.size.validation.rack.error": "모듈 배치가 잘못되었습니다. 올바르게 다시 배치해 주세요.",
|
||||||
"modal.module.basic.setting.module.placement": "모듈 배치",
|
"modal.module.basic.setting.module.placement": "모듈 배치",
|
||||||
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
|
"modal.module.basic.setting.module.placement.select.fitting.type": "설치형태를 선택합니다.",
|
||||||
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
|
"modal.module.basic.setting.module.placement.waterfowl.arrangement": "물떼새 배치",
|
||||||
|
|||||||
@ -677,8 +677,9 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
// 조건에 맞는 라인들만 필터링
|
// 조건에 맞는 라인들만 필터링
|
||||||
const validWallLines = [...wallLines].sort((a, b) => a.idx - b.idx).filter((wallLine, index) => wallLine.idx - 1 === index)
|
const validWallLines = [...wallLines].sort((a, b) => a.idx - b.idx).filter((wallLine, index) => wallLine.idx - 1 === index)
|
||||||
|
|
||||||
console.log('', sortRoofLines, sortWallLines, sortWallBaseLines)
|
console.log('', sortRoofLines, sortWallLines, sortWallBaseLines);
|
||||||
sortWallLines.length > 3 &&
|
|
||||||
|
(sortWallLines.length === sortWallBaseLines.length && sortWallBaseLines.length > 3) &&
|
||||||
sortWallLines.forEach((wallLine, index) => {
|
sortWallLines.forEach((wallLine, index) => {
|
||||||
|
|
||||||
const roofLine = sortRoofLines[index]
|
const roofLine = sortRoofLines[index]
|
||||||
@ -729,7 +730,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
coordinateText(line)
|
//coordinateText(line)
|
||||||
canvas.add(line)
|
canvas.add(line)
|
||||||
line.bringToFront()
|
line.bringToFront()
|
||||||
canvas.renderAll()
|
canvas.renderAll()
|
||||||
@ -844,7 +845,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length
|
const nextIndex = (index + 1) % sortRoofLines.length
|
||||||
const newLine = sortRoofLines[prevIndex]
|
const newLine = sortRoofLines[nextIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -871,7 +872,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//newPStart.y = wallLine.y1;
|
//newPStart.y = wallLine.y1;
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||||
newPStart.y = Big(wallBaseLine.y1).minus(rLineM).abs().toNumber()
|
newPStart.y = Big(wallBaseLine.y1).minus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.x2 > inLine.x1) {
|
if (inLine.x2 > inLine.x1) {
|
||||||
@ -898,7 +899,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[nextIndex]
|
const newLine = sortRoofLines[prevIndex]
|
||||||
|
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) {
|
if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) {
|
||||||
@ -927,7 +928,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||||
newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).abs().toNumber()
|
newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.x2 > inLine.x1) {
|
if (inLine.x2 > inLine.x1) {
|
||||||
@ -1002,8 +1003,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
if (isStartEnd.start) {
|
if (isStartEnd.start) {
|
||||||
//x1 inside
|
//x1 inside
|
||||||
const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber()
|
const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber()
|
||||||
const aStartY = Big(roofLine.y1).plus(moveDist).abs().toNumber()
|
const aStartY = Big(roofLine.y1).plus(moveDist).toNumber()
|
||||||
const bStartY = Big(wallLine.y1).plus(moveDist).abs().toNumber()
|
const bStartY = Big(wallLine.y1).plus(moveDist).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 })
|
const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 })
|
||||||
console.log('startLines:::::::', inLine)
|
console.log('startLines:::::::', inLine)
|
||||||
const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber()
|
const eLineY = Big(bStartY).minus(wallLine.y1).abs().toNumber()
|
||||||
@ -1014,7 +1015,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length
|
const nextIndex = (index + 1) % sortRoofLines.length
|
||||||
const newLine = sortRoofLines[prevIndex]
|
const newLine = sortRoofLines[nextIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -1041,7 +1042,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//newPStart.y = wallLine.y1;
|
//newPStart.y = wallLine.y1;
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.x1).minus(roofLine.x1).abs().toNumber()
|
const rLineM = Big(wallBaseLine.x1).minus(roofLine.x1).abs().toNumber()
|
||||||
newPStart.y = Big(wallBaseLine.y1).plus(rLineM).abs().toNumber()
|
newPStart.y = Big(wallBaseLine.y1).plus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.x2 > inLine.x1) {
|
if (inLine.x2 > inLine.x1) {
|
||||||
@ -1056,8 +1057,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
if (isStartEnd.end) {
|
if (isStartEnd.end) {
|
||||||
const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber()
|
const moveDist = Big(wallLine.x1).minus(wallBaseLine.x1).abs().toNumber()
|
||||||
const aStartY = Big(roofLine.y2).minus(moveDist).abs().toNumber()
|
const aStartY = Big(roofLine.y2).minus(moveDist).toNumber()
|
||||||
const bStartY = Big(wallLine.y2).minus(moveDist).abs().toNumber()
|
const bStartY = Big(wallLine.y2).minus(moveDist).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 })
|
const inLine = findLineContainingPoint(innerLines, { y: aStartY, x: roofLine.x1 })
|
||||||
console.log('startLines:::::::', inLine)
|
console.log('startLines:::::::', inLine)
|
||||||
const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber()
|
const eLineY = Big(bStartY).minus(wallLine.y2).abs().toNumber()
|
||||||
@ -1068,7 +1069,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[nextIndex]
|
const newLine = sortRoofLines[prevIndex]
|
||||||
|
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.x2 < inLine.x1) {
|
if (inLine.x2 < inLine.x1) {
|
||||||
@ -1096,7 +1097,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||||
newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).abs().toNumber()
|
newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.x2 > inLine.x1) {
|
if (inLine.x2 > inLine.x1) {
|
||||||
@ -1167,7 +1168,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
const newPointY = Big(roofLine.y1).plus(moveDist).toNumber()
|
const newPointY = Big(roofLine.y1).plus(moveDist).toNumber()
|
||||||
|
|
||||||
const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber()
|
const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||||
const pLineX = Big(roofLine.x2).minus(0).abs().toNumber()
|
const pLineX = Big(roofLine.x2).minus(0).toNumber()
|
||||||
|
|
||||||
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
||||||
// const pLineY = sortRoofLines[idx + 1].y2
|
// const pLineY = sortRoofLines[idx + 1].y2
|
||||||
@ -1203,7 +1204,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[prevIndex]
|
const newLine = sortRoofLines[nextIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -1229,7 +1230,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
} else {
|
} else {
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||||
newPStart.x = Big(wallBaseLine.x1).plus(rLineM).abs().toNumber()
|
newPStart.x = Big(wallBaseLine.x1).plus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.y2 > inLine.y1) {
|
if (inLine.y2 > inLine.y1) {
|
||||||
@ -1243,11 +1244,11 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
}
|
}
|
||||||
if (isStartEnd.end) {
|
if (isStartEnd.end) {
|
||||||
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
||||||
const aStartX = Big(roofLine.x2).minus(moveDist).abs().toNumber()
|
const aStartX = Big(roofLine.x2).minus(moveDist).toNumber()
|
||||||
const bStartX = Big(wallLine.x2).minus(moveDist).abs().toNumber()
|
const bStartX = Big(wallLine.x2).minus(moveDist).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y })
|
const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: newPEnd.y })
|
||||||
console.log('startLines:::::::', inLine)
|
console.log('startLines:::::::', inLine)
|
||||||
const eLineX = Big(bStartX).minus(wallLine.x2).abs().toNumber()
|
const eLineX = Big(bStartX).minus(wallLine.x2).toNumber()
|
||||||
newPStart.x = roofLine.x1 //Big(newPStart.x).minus(eLineX).abs().toNumber()
|
newPStart.x = roofLine.x1 //Big(newPStart.x).minus(eLineX).abs().toNumber()
|
||||||
newPEnd.x = aStartX
|
newPEnd.x = aStartX
|
||||||
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
||||||
@ -1255,7 +1256,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[nextIndex]
|
const newLine = sortRoofLines[prevIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -1282,7 +1283,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//newPEnd.x = wallLine.x2;
|
//newPEnd.x = wallLine.x2;
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||||
newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).abs().toNumber()
|
newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.y1 > inLine.y2) {
|
if (inLine.y1 > inLine.y2) {
|
||||||
@ -1303,7 +1304,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
const newPointY = Big(roofLine.y2).minus(moveDist).toNumber()
|
const newPointY = Big(roofLine.y2).minus(moveDist).toNumber()
|
||||||
|
|
||||||
const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber()
|
const pDist = Big(wallLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||||
const pLineX = Big(roofLine.x1).minus(0).abs().toNumber()
|
const pLineX = Big(roofLine.x1).minus(0).toNumber()
|
||||||
|
|
||||||
// let idx = 0 > index - 1 ? sortRoofLines.length : index
|
// let idx = 0 > index - 1 ? sortRoofLines.length : index
|
||||||
// const pLineY = sortRoofLines[idx - 1].y1
|
// const pLineY = sortRoofLines[idx - 1].y1
|
||||||
@ -1330,7 +1331,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
const newPointY = Big(roofLine.y1).minus(moveDist).toNumber()
|
const newPointY = Big(roofLine.y1).minus(moveDist).toNumber()
|
||||||
|
|
||||||
const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber()
|
const pDist = Big(wallLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||||
const pLineX = Big(roofLine.x2).minus(0).abs().toNumber()
|
const pLineX = Big(roofLine.x2).minus(0).toNumber()
|
||||||
|
|
||||||
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
// let idx = sortRoofLines.length < index + 1 ? 0 : index
|
||||||
// const pLineY = sortRoofLines[idx + 1].y2
|
// const pLineY = sortRoofLines[idx + 1].y2
|
||||||
@ -1353,8 +1354,8 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
console.log('bottom_out isStartEnd:::::::', isStartEnd)
|
console.log('bottom_out isStartEnd:::::::', isStartEnd)
|
||||||
if (isStartEnd.start) {
|
if (isStartEnd.start) {
|
||||||
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
const moveDist = Big(wallLine.y1).minus(wallBaseLine.y1).abs().toNumber()
|
||||||
const aStartX = Big(roofLine.x1).minus(moveDist).abs().toNumber()
|
const aStartX = Big(roofLine.x1).minus(moveDist).toNumber()
|
||||||
const bStartX = Big(wallLine.x1).minus(moveDist).abs().toNumber()
|
const bStartX = Big(wallLine.x1).minus(moveDist).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 })
|
const inLine = findLineContainingPoint(innerLines, { x: aStartX, y: roofLine.y1 })
|
||||||
console.log('startLines:::::::', inLine)
|
console.log('startLines:::::::', inLine)
|
||||||
const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber()
|
const eLineX = Big(bStartX).minus(wallLine.x1).abs().toNumber()
|
||||||
@ -1365,7 +1366,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[prevIndex]
|
const newLine = sortRoofLines[nextIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -1392,7 +1393,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//newPStart.x = wallLine.x1;
|
//newPStart.x = wallLine.x1;
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||||
newPStart.x = Big(wallBaseLine.x1).minus(rLineM).abs().toNumber()
|
newPStart.x = Big(wallBaseLine.x1).minus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.y2 > inLine.y1) {
|
if (inLine.y2 > inLine.y1) {
|
||||||
@ -1419,7 +1420,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
|
|
||||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||||
const newLine = sortRoofLines[nextIndex]
|
const newLine = sortRoofLines[prevIndex]
|
||||||
|
|
||||||
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
@ -1446,7 +1447,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
|||||||
//newPEnd.x = wallLine.x2;
|
//newPEnd.x = wallLine.x2;
|
||||||
//외곽 라인 그리기
|
//외곽 라인 그리기
|
||||||
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||||
newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).abs().toNumber()
|
newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).toNumber()
|
||||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||||
if (inLine) {
|
if (inLine) {
|
||||||
if (inLine.y1 > inLine.y2) {
|
if (inLine.y1 > inLine.y2) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user