Compare commits
No commits in common. "dc080a873784491cd621f669d5abd56d37fcd1ad" and "8289f7feef2e795f9ab759e414137cec57d7c1a4" have entirely different histories.
dc080a8737
...
8289f7feef
@ -3,7 +3,7 @@ import { createCalculator } from '@/util/calc-utils'
|
||||
import '@/styles/calc.scss'
|
||||
|
||||
export const CalculatorInput = forwardRef(
|
||||
({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false, placeholder, name='', disabled = false, maxLength = 6 }, ref) => {
|
||||
({ value, onChange, label, options = {}, id, className = 'calculator-input', readOnly = false, placeholder, name='', disabled = false }, ref) => {
|
||||
const [showKeypad, setShowKeypad] = useState(false)
|
||||
const [displayValue, setDisplayValue] = useState(value || '0')
|
||||
const [hasOperation, setHasOperation] = useState(false)
|
||||
@ -48,56 +48,28 @@ export const CalculatorInput = forwardRef(
|
||||
const calculator = calculatorRef.current
|
||||
let newDisplayValue = ''
|
||||
|
||||
// maxLength 체크
|
||||
if (maxLength > 0) {
|
||||
const currentLength = (calculator.currentOperand || '').length + (calculator.previousOperand || '').length + (calculator.operation || '').length
|
||||
if (currentLength >= maxLength) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 소수점 이하 2자리 제한 로직 추가
|
||||
const shouldPreventInput = (value) => {
|
||||
if (!value) return false
|
||||
const decimalParts = value.toString().split('.')
|
||||
const decimalParts = (value || '').split('.')
|
||||
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 (calculator.shouldResetDisplay) {
|
||||
if (calculator.currentOperand === '0' || calculator.shouldResetDisplay) {
|
||||
calculator.currentOperand = num.toString()
|
||||
calculator.shouldResetDisplay = false
|
||||
} else if (num === '.') {
|
||||
if (!calculator.currentOperand.includes('.')) {
|
||||
calculator.currentOperand = calculator.currentOperand || '0' + '.'
|
||||
}else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
}
|
||||
} else if (!shouldPreventInput(calculator.currentOperand)) {
|
||||
calculator.currentOperand = appendNumber(calculator.currentOperand || '0', num)
|
||||
}
|
||||
|
||||
// else {
|
||||
// calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
// }
|
||||
newDisplayValue = calculator.previousOperand + calculator.operation + calculator.currentOperand
|
||||
setDisplayValue(newDisplayValue)
|
||||
} else {
|
||||
// 첫 번째 숫자 입력 시
|
||||
if (calculator.shouldResetDisplay) {
|
||||
if (displayValue === '0' || calculator.shouldResetDisplay) {
|
||||
calculator.currentOperand = num.toString()
|
||||
calculator.shouldResetDisplay = false
|
||||
newDisplayValue = calculator.currentOperand
|
||||
@ -105,17 +77,8 @@ export const CalculatorInput = forwardRef(
|
||||
if (!hasOperation) {
|
||||
onChange(calculator.currentOperand)
|
||||
}
|
||||
} else if (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)
|
||||
} else if (!shouldPreventInput(calculator.currentOperand)) { //소수점 이하2자리
|
||||
calculator.currentOperand = (calculator.currentOperand || '') + num
|
||||
newDisplayValue = calculator.currentOperand
|
||||
setDisplayValue(newDisplayValue)
|
||||
if (!hasOperation) {
|
||||
@ -419,7 +382,6 @@ export const CalculatorInput = forwardRef(
|
||||
placeholder={placeholder}
|
||||
autoComplete={'off'}
|
||||
disabled={disabled}
|
||||
maxLength={maxLength}
|
||||
/>
|
||||
|
||||
{showKeypad && !readOnly && (
|
||||
|
||||
@ -24,7 +24,6 @@ import { useSwal } from '@/hooks/useSwal'
|
||||
import { QcastContext } from '@/app/QcastProvider'
|
||||
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
|
||||
import {normalizeDigits, normalizeDecimal} from '@/util/input-utils'
|
||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||
export default function Estimate({}) {
|
||||
const [uniqueData, setUniqueData] = useState([])
|
||||
const [handlePricingFlag, setHandlePricingFlag] = useState(false)
|
||||
@ -1694,13 +1693,13 @@ export default function Estimate({}) {
|
||||
{/* 파일첨부 끝 */}
|
||||
{/* 견적특이사항 시작 */}
|
||||
<div className="table-box-title-wrap">
|
||||
{/*<div className="title-wrap">*/}
|
||||
{/* <h3 className="product">{getMessage('estimate.detail.header.specialEstimate')}</h3>*/}
|
||||
{/* <div className="estimate-check-btn">*/}
|
||||
{/* <button className={`estimate-arr-btn down mr5 ${hidden ? '' : 'on'}`} onClick={() => setHidden(false)}></button>*/}
|
||||
{/* <button className={`estimate-arr-btn up ${hidden ? 'on' : ''}`} onClick={() => setHidden(true)}></button>*/}
|
||||
{/* </div>*/}
|
||||
{/*</div>*/}
|
||||
<div className="title-wrap">
|
||||
<h3 className="product">{getMessage('estimate.detail.header.specialEstimate')}</h3>
|
||||
<div className="estimate-check-btn">
|
||||
<button className={`estimate-arr-btn down mr5 ${hidden ? '' : 'on'}`} onClick={() => setHidden(false)}></button>
|
||||
<button className={`estimate-arr-btn up ${hidden ? 'on' : ''}`} onClick={() => setHidden(true)}></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* 견적 특이사항 코드영역시작 */}
|
||||
<div className={`estimate-check-wrap ${hidden ? 'hide' : ''}`}>
|
||||
@ -2107,27 +2106,15 @@ export default function Estimate({}) {
|
||||
</td>
|
||||
<td>
|
||||
<div className="input-wrap" style={{ width: '100%' }}>
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* 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"}
|
||||
<input
|
||||
type="text"
|
||||
className="input-light al-r"
|
||||
value={convertNumberToPriceDecimal(item?.amount?.replaceAll(',', ''))}
|
||||
disabled={item.itemId === '' || !!item?.paDispOrder}
|
||||
onChange={(value) =>{
|
||||
onChangeAmount(value, item.dispOrder, index)
|
||||
}}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
onChange={(e) => {
|
||||
onChangeAmount(e.target.value, item.dispOrder, index)
|
||||
}}
|
||||
maxLength={6}
|
||||
/>
|
||||
</div>
|
||||
</td>
|
||||
@ -2135,32 +2122,9 @@ export default function Estimate({}) {
|
||||
<td>
|
||||
<div className="form-flex-wrap">
|
||||
<div className="input-wrap mr5">
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* 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"}
|
||||
<input
|
||||
type="text"
|
||||
className="input-light al-r"
|
||||
value={
|
||||
item.openFlg === '1'
|
||||
? 'OPEN'
|
||||
@ -2176,15 +2140,13 @@ export default function Estimate({}) {
|
||||
: item.itemId === '' || !!item?.paDispOrder
|
||||
? true
|
||||
: item.openFlg === '1'
|
||||
? true
|
||||
: false
|
||||
}
|
||||
onChange={(value) =>{
|
||||
onChangeSalePrice(value, item.dispOrder, index)
|
||||
onChange={(e) => {
|
||||
onChangeSalePrice(e.target.value, item.dispOrder, index)
|
||||
}}
|
||||
maxLength={12}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{item.openFlg === '1' && (
|
||||
|
||||
@ -235,23 +235,11 @@ export default function Module({ setTabNum }) {
|
||||
<div className="eaves-keraba-td">
|
||||
<div className="outline-form">
|
||||
<div className="grid-select mr10">
|
||||
{/*<input*/}
|
||||
{/* type="text"*/}
|
||||
{/* className="input-origin block"*/}
|
||||
{/* value={inputVerticalSnowCover}*/}
|
||||
{/* onChange={(e) => setInputVerticalSnowCover(normalizeDecimal(e.target.value))}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
<input
|
||||
type="text"
|
||||
className="input-origin block"
|
||||
value={inputVerticalSnowCover}
|
||||
onChange={(value) => setInputVerticalSnowCover(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
}}
|
||||
onChange={(e) => setInputVerticalSnowCover(normalizeDecimal(e.target.value))}
|
||||
/>
|
||||
</div>
|
||||
<span className="thin">cm</span>
|
||||
|
||||
@ -638,7 +638,7 @@ export const Orientation = forwardRef((props, ref) => {
|
||||
name=""
|
||||
label=""
|
||||
className="input-origin block"
|
||||
value={inputVerticalSnowCover}
|
||||
value={inputInstallHeight}
|
||||
onChange={(value) => handleChangeVerticalSnowCover(value)}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
|
||||
@ -2125,12 +2125,12 @@ export default function StuffDetail() {
|
||||
{/* {...register('verticalSnowCover')}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id="verticalSnowCover"
|
||||
name="verticalSnowCover"
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-light"
|
||||
value={form.watch('verticalSnowCover') || ''}
|
||||
onChange={(value) => form.setValue('verticalSnowCover', value)}
|
||||
onChange={()=>{}}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
@ -2197,12 +2197,12 @@ export default function StuffDetail() {
|
||||
{/* {...register('installHeight')}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id="installHeight"
|
||||
name="installHeight"
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-light"
|
||||
value={form.watch('installHeight') || ''}
|
||||
onChange={(value) => form.setValue('installHeight', value)}
|
||||
onChange={()=>{}}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
@ -2721,12 +2721,12 @@ export default function StuffDetail() {
|
||||
{/* {...register('verticalSnowCover')}*/}
|
||||
{/*/>*/}
|
||||
<CalculatorInput
|
||||
id="verticalSnowCover"
|
||||
name="verticalSnowCover"
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-light"
|
||||
value={form.watch('verticalSnowCover') || ''}
|
||||
onChange={(value) => form.setValue('verticalSnowCover', value)}
|
||||
onChange={()=>{}}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
@ -2797,12 +2797,12 @@ export default function StuffDetail() {
|
||||
{/*/>*/}
|
||||
|
||||
<CalculatorInput
|
||||
id="installHeight"
|
||||
name="installHeight"
|
||||
id=""
|
||||
name=""
|
||||
label=""
|
||||
className="input-light"
|
||||
value={form.watch('installHeight') || ''}
|
||||
onChange={(value) => form.setValue('installHeight', value)}
|
||||
onChange={()=>{}}
|
||||
options={{
|
||||
allowNegative: false,
|
||||
allowDecimal: false
|
||||
|
||||
@ -473,20 +473,7 @@ export function useRoofAllocationSetting(id) {
|
||||
// Filter out any eaveHelpLines that are already in lines to avoid duplicates
|
||||
const existingEaveLineIds = new Set(roofBase.lines.map((line) => line.id))
|
||||
const newEaveLines = roofEaveHelpLines.filter((line) => !existingEaveLineIds.has(line.id))
|
||||
// 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];
|
||||
roofBase.lines = [...newEaveLines]
|
||||
} else {
|
||||
roofBase.lines = [...roofEaveHelpLines]
|
||||
}
|
||||
|
||||
@ -4848,9 +4848,6 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
const prevLineVector = { x: Math.sign(prevLine.x1 - prevLine.x2), y: Math.sign(prevLine.y1 - prevLine.y2) }
|
||||
const nextLineVector = { x: Math.sign(nextLine.x1 - nextLine.x2), y: Math.sign(nextLine.y1 - nextLine.y2) }
|
||||
|
||||
const midX = (baseLine.x1 + baseLine.x2) / 2
|
||||
const midY = (baseLine.y1 + baseLine.y2) / 2
|
||||
const checkPoint = { x: midX + nextLineVector.x, y: midY + nextLineVector.y }
|
||||
//반절마루 생성불가이므로 지붕선 분기를 해야하는지 확인 후 처리.
|
||||
if (
|
||||
prevLineVector.x === nextLineVector.x &&
|
||||
@ -4858,24 +4855,12 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
baseLine.attributes.type === LINE_TYPE.WALLLINE.EAVES &&
|
||||
(prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE || nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE)
|
||||
) {
|
||||
downRoofGable.push({ currLine: baseLine, currIndex: index, type: 'A' })
|
||||
}
|
||||
|
||||
if (
|
||||
(prevLineVector.x !== nextLineVector.x || prevLineVector.y !== nextLineVector.y) &&
|
||||
checkWallPolygon.inPolygon(checkPoint) &&
|
||||
prevLine.attributes.type === LINE_TYPE.WALLLINE.GABLE &&
|
||||
nextLine.attributes.type === LINE_TYPE.WALLLINE.GABLE
|
||||
) {
|
||||
downRoofGable.push({ currLine: baseLine, currIndex: index, type: 'B' })
|
||||
downRoofGable.push({ currLine: baseLine, currIndex: index })
|
||||
}
|
||||
})
|
||||
|
||||
const downRoofLines = [] // 하단지붕 파생 라인 처리후 innerLines에 추가.
|
||||
//A타입 하단 지붕 prevLine과 nextLine이 같은 방향으로 가는 경우
|
||||
downRoofGable
|
||||
.filter((l) => l.type === 'A')
|
||||
.forEach(({ currLine, currIndex }) => {
|
||||
downRoofGable.forEach(({ currLine, currIndex }) => {
|
||||
// 라인의 방향
|
||||
const currVector = { x: Math.sign(clamp01(currLine.x1 - currLine.x2)), y: Math.sign(clamp01(currLine.y1 - currLine.y2)) }
|
||||
|
||||
@ -5063,204 +5048,6 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
}
|
||||
})
|
||||
|
||||
// B타입 하단지붕 prevLine과 nextLine의 방향이 반대인데 현재 라인이 지붕 안쪽으로 들어가는 모양.
|
||||
downRoofGable
|
||||
.filter((l) => l.type === 'B')
|
||||
.forEach(({ currLine, currIndex }) => {
|
||||
const checkLine = new fabric.Line([currLine.x1, currLine.y1, currLine.x2, currLine.y2], {
|
||||
stroke: 'red',
|
||||
strokeWidth: 4,
|
||||
parentId: roofId,
|
||||
name: 'check',
|
||||
})
|
||||
canvas.add(checkLine).renderAll()
|
||||
|
||||
// 라인의 방향
|
||||
const currVector = { x: Math.sign(clamp01(currLine.x1 - currLine.x2)), y: Math.sign(clamp01(currLine.y1 - currLine.y2)) }
|
||||
|
||||
//어느쪽이 기준인지 확인.
|
||||
//대각선 제외
|
||||
if (currVector.x !== 0 && currVector.y !== 0) return
|
||||
|
||||
const prevLine = baseLines[(currIndex - 1 + baseLines.length) % baseLines.length]
|
||||
const nextLine = baseLines[(currIndex + 1) % baseLines.length]
|
||||
|
||||
const prevVector = { x: Math.sign(clamp01(prevLine.x1 - prevLine.x2)), y: Math.sign(clamp01(prevLine.y1 - prevLine.y2)) }
|
||||
const nextVector = { x: Math.sign(clamp01(nextLine.x1 - nextLine.x2)), y: Math.sign(clamp01(nextLine.y1 - nextLine.y2)) }
|
||||
|
||||
const minX = Math.min(currLine.x1, currLine.x2)
|
||||
const maxX = Math.max(currLine.x1, currLine.x2)
|
||||
const minY = Math.min(currLine.y1, currLine.y2)
|
||||
const maxY = Math.max(currLine.y1, currLine.y2)
|
||||
const midX = (currLine.x1 + currLine.x2) / 2
|
||||
const midY = (currLine.y1 + currLine.y2) / 2
|
||||
let ridgeFindVector = { x: nextVector.x, y: nextVector.y }
|
||||
if (!checkWallPolygon.inPolygon({ x: midX, y: midY })) {
|
||||
ridgeFindVector = { x: prevVector.x, y: prevVector.y }
|
||||
}
|
||||
|
||||
// 마루를 따라 생성되어야 하는 지붕선 추가.
|
||||
const oppLines = innerLines
|
||||
.filter((l) => l.name === LINE_TYPE.SUBLINE.RIDGE)
|
||||
.filter((line) => {
|
||||
const lineVector = { x: Math.sign(clamp01(line.x1 - line.x2)), y: Math.sign(clamp01(line.y1 - line.y2)) }
|
||||
let oppVector
|
||||
if (currVector.x === 0) {
|
||||
if (currVector.y === 1) {
|
||||
oppVector = { x: Math.sign(clamp01(currLine.x1 - line.x1)), y: 0 }
|
||||
} else if (currVector.y === -1) {
|
||||
oppVector = { x: Math.sign(clamp01(line.x1 - currLine.x1)), y: 0 }
|
||||
}
|
||||
} else if (currVector.y === 0) {
|
||||
if (currVector.x === 1) {
|
||||
oppVector = { x: 0, y: Math.sign(clamp01(line.y1 - currLine.y1)) }
|
||||
} else if (currVector.x === -1) {
|
||||
oppVector = { x: 0, y: Math.sign(clamp01(currLine.y1 - line.y1)) }
|
||||
}
|
||||
}
|
||||
|
||||
const lineMinX = Math.min(line.x1, line.x2)
|
||||
const lineMaxX = Math.max(line.x1, line.x2)
|
||||
const lineMinY = Math.min(line.y1, line.y2)
|
||||
const lineMaxY = Math.max(line.y1, line.y2)
|
||||
|
||||
const isInside = lineVector.y === 0 ? minX <= lineMinX && lineMaxX <= maxX : minY <= lineMinY && lineMaxY <= maxY
|
||||
|
||||
const rightOpp = ridgeFindVector.x === oppVector.x && ridgeFindVector.y === oppVector.y
|
||||
return rightOpp && isInside
|
||||
})
|
||||
|
||||
// 현재 라인의 지붕선 추가.
|
||||
const currOffset = currLine.attributes.offset
|
||||
const roofPoint = [
|
||||
currLine.x1 + -nextVector.x * currOffset,
|
||||
currLine.y1 + -nextVector.y * currOffset,
|
||||
currLine.x2 + -nextVector.x * currOffset,
|
||||
currLine.y2 + -nextVector.y * currOffset,
|
||||
]
|
||||
downRoofLines.push(drawRoofLine(roofPoint, canvas, roof, textMode))
|
||||
|
||||
// 현재 라인 좌표의 시작과 끝 포인트에서 직교하는 포인트와 라인을 찾는다
|
||||
let orthogonalStartPoint,
|
||||
orthogonalStartDistance = Infinity,
|
||||
orthogonalStartLine
|
||||
let orthogonalEndPoint,
|
||||
orthogonalEndDistance = Infinity,
|
||||
orthogonalEndLine
|
||||
oppLines.forEach((line) => {
|
||||
const checkLine = new fabric.Line([line.x1, line.y1, line.x2, line.y2], { stroke: 'red', strokeWidth: 4, parentId: roofId, name: 'check' })
|
||||
canvas.add(checkLine).renderAll()
|
||||
|
||||
if (currVector.x === 0) {
|
||||
//세로선
|
||||
// 시작포인트와 가까운 포인트의 길이
|
||||
const lineStartDist =
|
||||
Math.abs(currLine.y1 - line.y1) < Math.abs(currLine.y1 - line.y2) ? Math.abs(currLine.y1 - line.y1) : Math.abs(currLine.y1 - line.y2)
|
||||
const lineStartPoint =
|
||||
Math.abs(currLine.y1 - line.y1) < Math.abs(currLine.y1 - line.y2) ? { x: line.x1, y: currLine.y1 } : { x: line.x2, y: currLine.y1 }
|
||||
if (lineStartDist < orthogonalStartDistance) {
|
||||
orthogonalStartDistance = lineStartDist
|
||||
orthogonalStartPoint = lineStartPoint
|
||||
orthogonalStartLine = line
|
||||
}
|
||||
// 종료포인트와 가까운 포인트의 길이
|
||||
const lineEndDist =
|
||||
Math.abs(currLine.y2 - line.y1) < Math.abs(currLine.y2 - line.y2) ? Math.abs(currLine.y2 - line.y2) : Math.abs(currLine.y2 - line.y1)
|
||||
const lineEndPoint =
|
||||
Math.abs(currLine.y2 - line.y1) < Math.abs(currLine.y2 - line.y2) ? { x: line.x2, y: currLine.y2 } : { x: line.x1, y: currLine.y2 }
|
||||
if (lineEndDist < orthogonalEndDistance) {
|
||||
orthogonalEndDistance = lineEndDist
|
||||
orthogonalEndPoint = lineEndPoint
|
||||
orthogonalEndLine = line
|
||||
}
|
||||
} else if (currVector.y === 0) {
|
||||
//가로선
|
||||
// 시작포인트와 가까운 포인트의 길이
|
||||
const lineStartDist =
|
||||
Math.abs(currLine.x1 - line.x1) < Math.abs(currLine.x1 - line.x2) ? Math.abs(currLine.x1 - line.x1) : Math.abs(currLine.x1 - line.x2)
|
||||
const lineStartPoint =
|
||||
Math.abs(currLine.x1 - line.x1) < Math.abs(currLine.x1 - line.x2) ? { x: currLine.x1, y: line.y1 } : { x: currLine.x1, y: line.y2 }
|
||||
if (lineStartDist < orthogonalStartDistance) {
|
||||
orthogonalStartDistance = lineStartDist
|
||||
orthogonalStartPoint = lineStartPoint
|
||||
orthogonalStartLine = line
|
||||
}
|
||||
//종료포인트와 가까운 포인트의 길이
|
||||
const lineEndDist =
|
||||
Math.abs(currLine.x2 - line.x1) < Math.abs(currLine.x2 - line.x2) ? Math.abs(currLine.x2 - line.x1) : Math.abs(currLine.x2 - line.x2)
|
||||
const lineEndPoint =
|
||||
Math.abs(currLine.x2 - line.x1) < Math.abs(currLine.x2 - line.x2) ? { x: currLine.x2, y: line.y1 } : { x: currLine.x2, y: line.y2 }
|
||||
if (lineEndDist < orthogonalEndDistance) {
|
||||
orthogonalEndDistance = lineEndDist
|
||||
orthogonalEndPoint = lineEndPoint
|
||||
orthogonalEndLine = line
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//직교 라인이 있는 경우
|
||||
if (orthogonalStartLine !== undefined && orthogonalEndLine !== undefined) {
|
||||
if (orthogonalStartLine === orthogonalEndLine) {
|
||||
//직교 라인이 1개일때 처리
|
||||
downRoofLines.push(
|
||||
drawRoofLine([orthogonalStartPoint.x, orthogonalStartPoint.y, orthogonalEndPoint.x, orthogonalEndPoint.y], canvas, roof, textMode),
|
||||
)
|
||||
} else {
|
||||
//직교 라인이 2개일때 처리
|
||||
// 시작 라인 처리
|
||||
const startDist1 = Math.sqrt(
|
||||
Math.pow(orthogonalStartPoint.x - orthogonalStartLine.x1, 2) + Math.pow(orthogonalStartPoint.y - orthogonalStartLine.y1, 2),
|
||||
)
|
||||
const startDist2 = Math.sqrt(
|
||||
Math.pow(orthogonalStartPoint.x - orthogonalStartLine.x2, 2) + Math.pow(orthogonalStartPoint.y - orthogonalStartLine.y2, 2),
|
||||
)
|
||||
const otherStartPoint =
|
||||
startDist1 > startDist2
|
||||
? { x: orthogonalStartLine.x1, y: orthogonalStartLine.y1 }
|
||||
: { x: orthogonalStartLine.x2, y: orthogonalStartLine.y2 }
|
||||
downRoofLines.push(
|
||||
drawRoofLine([orthogonalStartPoint.x, orthogonalStartPoint.y, otherStartPoint.x, otherStartPoint.y], canvas, roof, textMode),
|
||||
)
|
||||
|
||||
const endDist1 = Math.sqrt(
|
||||
Math.pow(orthogonalEndPoint.x - orthogonalEndLine.x1, 2) + Math.pow(orthogonalEndPoint.y - orthogonalEndLine.y1, 2),
|
||||
)
|
||||
const endDist2 = Math.sqrt(
|
||||
Math.pow(orthogonalEndPoint.x - orthogonalEndLine.x2, 2) + Math.pow(orthogonalEndPoint.y - orthogonalEndLine.y2, 2),
|
||||
)
|
||||
const otherEndPoint =
|
||||
endDist1 > endDist2 ? { x: orthogonalEndLine.x1, y: orthogonalEndLine.y1 } : { x: orthogonalEndLine.x2, y: orthogonalEndLine.y2 }
|
||||
downRoofLines.push(drawRoofLine([orthogonalEndPoint.x, orthogonalEndPoint.y, otherEndPoint.x, otherEndPoint.y], canvas, roof, textMode))
|
||||
}
|
||||
|
||||
//지붕선(roofPoint)에서 직교포인트까지 연결하는 라인을 추가한다.
|
||||
const orthogonalPoint1 = [roofPoint[0], roofPoint[1], orthogonalStartPoint.x, orthogonalStartPoint.y]
|
||||
const orthogonalPoint2 = [roofPoint[2], roofPoint[3], orthogonalEndPoint.x, orthogonalEndPoint.y]
|
||||
downRoofLines.push(
|
||||
drawHipLine(
|
||||
orthogonalPoint1,
|
||||
canvas,
|
||||
roof,
|
||||
textMode,
|
||||
null,
|
||||
getDegreeByChon(currLine.attributes.pitch),
|
||||
getDegreeByChon(currLine.attributes.pitch),
|
||||
),
|
||||
)
|
||||
downRoofLines.push(
|
||||
drawHipLine(
|
||||
orthogonalPoint2,
|
||||
canvas,
|
||||
roof,
|
||||
textMode,
|
||||
null,
|
||||
getDegreeByChon(currLine.attributes.pitch),
|
||||
getDegreeByChon(currLine.attributes.pitch),
|
||||
),
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
//추가된 하단 지붕 라인 innerLines에 추가.
|
||||
innerLines.push(...downRoofLines)
|
||||
|
||||
@ -5320,13 +5107,7 @@ export const drawRoofByAttribute = (roofId, canvas, textMode) => {
|
||||
}
|
||||
startPoint = point
|
||||
}
|
||||
if (splitPoint.length === 1) {
|
||||
innerLines.push(drawRoofLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode))
|
||||
} else {
|
||||
innerLines.push(
|
||||
drawHipLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode, null, nextDegree, nextDegree),
|
||||
)
|
||||
}
|
||||
innerLines.push(drawHipLine([startPoint.x, startPoint.y, currentLine.x2, currentLine.y2], canvas, roof, textMode, null, nextDegree, nextDegree))
|
||||
} else {
|
||||
innerLines.push(drawRoofLine([currentLine.x1, currentLine.y1, currentLine.x2, currentLine.y2], canvas, roof, textMode))
|
||||
}
|
||||
|
||||
@ -729,7 +729,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
},
|
||||
})
|
||||
|
||||
//coordinateText(line)
|
||||
coordinateText(line)
|
||||
canvas.add(line)
|
||||
line.bringToFront()
|
||||
canvas.renderAll()
|
||||
@ -844,7 +844,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
||||
const nextIndex = (index + 1) % sortRoofLines.length
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -871,7 +871,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//newPStart.y = wallLine.y1;
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||
newPStart.y = Big(wallBaseLine.y1).minus(rLineM).toNumber()
|
||||
newPStart.y = Big(wallBaseLine.y1).minus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||
if (inLine) {
|
||||
if (inLine.x2 > inLine.x1) {
|
||||
@ -898,7 +898,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
|
||||
|
||||
if (Math.abs(wallBaseLine.y2 - wallLine.y2) < 0.1) {
|
||||
@ -927,7 +927,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||
newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).toNumber()
|
||||
newPEnd.y = Big(wallBaseLine.y2).plus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||
if (inLine) {
|
||||
if (inLine.x2 > inLine.x1) {
|
||||
@ -1014,7 +1014,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length
|
||||
const nextIndex = (index + 1) % sortRoofLines.length
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.y1 - wallLine.y1) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -1041,7 +1041,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//newPStart.y = wallLine.y1;
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.x1).minus(roofLine.x1).abs().toNumber()
|
||||
newPStart.y = Big(wallBaseLine.y1).plus(rLineM).toNumber()
|
||||
newPStart.y = Big(wallBaseLine.y1).plus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||
if (inLine) {
|
||||
if (inLine.x2 > inLine.x1) {
|
||||
@ -1068,7 +1068,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
|
||||
if (inLine) {
|
||||
if (inLine.x2 < inLine.x1) {
|
||||
@ -1096,7 +1096,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.x2).minus(roofLine.x2).abs().toNumber()
|
||||
newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).toNumber()
|
||||
newPEnd.y = Big(wallBaseLine.y2).minus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||
if (inLine) {
|
||||
if (inLine.x2 > inLine.x1) {
|
||||
@ -1203,7 +1203,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -1229,7 +1229,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
} else {
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||
newPStart.x = Big(wallBaseLine.x1).plus(rLineM).toNumber()
|
||||
newPStart.x = Big(wallBaseLine.x1).plus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||
if (inLine) {
|
||||
if (inLine.y2 > inLine.y1) {
|
||||
@ -1255,7 +1255,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -1282,7 +1282,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//newPEnd.x = wallLine.x2;
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||
newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).toNumber()
|
||||
newPEnd.x = Big(wallBaseLine.x2).minus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||
if (inLine) {
|
||||
if (inLine.y1 > inLine.y2) {
|
||||
@ -1365,7 +1365,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.x1 - wallLine.x1) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -1392,7 +1392,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//newPStart.x = wallLine.x1;
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.y1).minus(roofLine.y1).abs().toNumber()
|
||||
newPStart.x = Big(wallBaseLine.x1).minus(rLineM).toNumber()
|
||||
newPStart.x = Big(wallBaseLine.x1).minus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPStart.y, x: newPStart.x })
|
||||
if (inLine) {
|
||||
if (inLine.y2 > inLine.y1) {
|
||||
@ -1419,7 +1419,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
|
||||
const prevIndex = (index - 1 + sortRoofLines.length) % sortRoofLines.length;
|
||||
const nextIndex = (index + 1) % sortRoofLines.length;
|
||||
const newLine = sortRoofLines[prevIndex]
|
||||
const newLine = sortRoofLines[nextIndex]
|
||||
|
||||
if (Math.abs(wallBaseLine.x2 - wallLine.x2) < 0.1) {
|
||||
if (inLine) {
|
||||
@ -1446,7 +1446,7 @@ const createInnerLinesFromSkeleton = (roofId, canvas, skeleton, textMode) => {
|
||||
//newPEnd.x = wallLine.x2;
|
||||
//외곽 라인 그리기
|
||||
const rLineM = Big(wallBaseLine.y2).minus(roofLine.y2).abs().toNumber()
|
||||
newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).toNumber()
|
||||
newPEnd.x = Big(wallBaseLine.x2).plus(rLineM).abs().toNumber()
|
||||
const inLine = findLineContainingPoint(innerLines, { y: newPEnd.y, x: newPEnd.x })
|
||||
if (inLine) {
|
||||
if (inLine.y1 > inLine.y2) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user