Merge pull request 'dev' (#557) from dev into prd-deploy
Reviewed-on: #557
This commit is contained in:
commit
dc7f5e25e7
@ -224,6 +224,7 @@ export const SAVE_KEY = [
|
|||||||
'viewportTransform',
|
'viewportTransform',
|
||||||
'outerLineFix',
|
'outerLineFix',
|
||||||
'adjustRoofLines',
|
'adjustRoofLines',
|
||||||
|
'northModuleYn',
|
||||||
]
|
]
|
||||||
|
|
||||||
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
export const OBJECT_PROTOTYPE = [fabric.Line.prototype, fabric.Polygon.prototype, fabric.Triangle.prototype, fabric.Group.prototype]
|
||||||
|
|||||||
@ -96,7 +96,7 @@ export default function QSelectBox({
|
|||||||
title={tagTitle}
|
title={tagTitle}
|
||||||
>
|
>
|
||||||
<p>{selected}</p>
|
<p>{selected}</p>
|
||||||
<ul className="select-item-wrap">
|
<ul className="select-item-wrap" style={{ maxHeight: '200px' }}>
|
||||||
{options?.length > 0 &&
|
{options?.length > 0 &&
|
||||||
options?.map((option, index) => (
|
options?.map((option, index) => (
|
||||||
<li key={option.id + '_' + index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
<li key={option.id + '_' + index} className="select-item" onClick={() => handleClickSelectOption(option)}>
|
||||||
|
|||||||
@ -181,8 +181,27 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
return fabric.util.transformPoint(p, matrix)
|
return fabric.util.transformPoint(p, matrix)
|
||||||
})
|
})
|
||||||
this.points = transformedPoints
|
this.points = transformedPoints
|
||||||
const { left, top } = this.calcOriginCoords()
|
|
||||||
this.set('pathOffset', { x: left, y: top })
|
// 바운딩 박스 재계산 (width, height 업데이트 - fill 영역 수정)
|
||||||
|
const calcDim = this._calcDimensions({})
|
||||||
|
this.width = calcDim.width
|
||||||
|
this.height = calcDim.height
|
||||||
|
|
||||||
|
const newPathOffset = {
|
||||||
|
x: calcDim.left + this.width / 2,
|
||||||
|
y: calcDim.top + this.height / 2,
|
||||||
|
}
|
||||||
|
this.set('pathOffset', newPathOffset)
|
||||||
|
|
||||||
|
// 변환을 points에 적용했으므로 left, top, angle, scale 모두 리셋 (이중 변환 방지)
|
||||||
|
this.set({
|
||||||
|
left: newPathOffset.x,
|
||||||
|
top: newPathOffset.y,
|
||||||
|
angle: 0,
|
||||||
|
scaleX: 1,
|
||||||
|
scaleY: 1,
|
||||||
|
})
|
||||||
|
|
||||||
this.setCoords()
|
this.setCoords()
|
||||||
this.initLines()
|
this.initLines()
|
||||||
})
|
})
|
||||||
|
|||||||
@ -234,6 +234,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
setSelectedPcs(tempSelectedPcs)
|
setSelectedPcs(tempSelectedPcs)
|
||||||
canvas.add(moduleCircuitText)
|
canvas.add(moduleCircuitText)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const roofSurfaceList = canvas
|
const roofSurfaceList = canvas
|
||||||
.getObjects()
|
.getObjects()
|
||||||
@ -244,6 +245,7 @@ export default function PassivityCircuitAllocation(props) {
|
|||||||
roofSurface: surface.direction,
|
roofSurface: surface.direction,
|
||||||
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
roofSurfaceIncl: +canvas.getObjects().filter((obj) => obj.id === surface.parentId)[0].pitch,
|
||||||
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
|
roofSurfaceNorthYn: surface.direction === 'north' ? 'Y' : 'N',
|
||||||
|
roofSurfaceNorthModuleYn: surface.northModuleYn,
|
||||||
moduleList: surface.modules.map((module) => {
|
moduleList: surface.modules.map((module) => {
|
||||||
return {
|
return {
|
||||||
itemId: module.moduleInfo.itemId,
|
itemId: module.moduleInfo.itemId,
|
||||||
|
|||||||
@ -2,11 +2,110 @@ import Image from 'next/image'
|
|||||||
import { useMessage } from '@/hooks/useMessage'
|
import { useMessage } from '@/hooks/useMessage'
|
||||||
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
import { normalizeDecimalLimit, normalizeDigits } from '@/util/input-utils'
|
||||||
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
import { CalculatorInput } from '@/components/common/input/CalcInput'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
export default function Angle({ props }) {
|
export default function Angle({ props }) {
|
||||||
const { getMessage } = useMessage()
|
const { getMessage } = useMessage()
|
||||||
const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props
|
const { angle1, setAngle1, angle1Ref, length1, setLength1, length1Ref } = props
|
||||||
|
|
||||||
|
const resetCalculatorValue = () => {
|
||||||
|
// 1. 즉시 상태를 0으로 변경
|
||||||
|
setLength1(0);
|
||||||
|
|
||||||
|
if (length1Ref.current) {
|
||||||
|
// 2. input에 포커스를 주어 계산기 UI가 떠있는 상태를 유지하게 함
|
||||||
|
length1Ref.current.focus();
|
||||||
|
length1Ref.current.value = '';
|
||||||
|
|
||||||
|
// 3. 약간의 시간차를 두어 계산기 UI 내부의 버튼을 찾음
|
||||||
|
setTimeout(() => {
|
||||||
|
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
|
||||||
|
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
|
||||||
|
|
||||||
|
if (acButton) {
|
||||||
|
acButton.click();
|
||||||
|
} else {
|
||||||
|
// 버튼을 못 찾으면 강제로 input 이벤트와 Enter/Escape 등을 시뮬레이션
|
||||||
|
length1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
}
|
||||||
|
// 다시 포커스를 주어 키패드가 유지되도록 함 (필요시)
|
||||||
|
length1Ref.current.focus();
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetCalculatorValue2 = () => {
|
||||||
|
// 1. 즉시 상태를 0으로 변경
|
||||||
|
setAngle1(0);
|
||||||
|
|
||||||
|
if (angle1Ref.current) {
|
||||||
|
// 2. input에 포커스를 주어 계산기 UI가 떠있는 상태를 유지하게 함
|
||||||
|
angle1Ref.current.focus();
|
||||||
|
angle1Ref.current.value = '';
|
||||||
|
|
||||||
|
// 3. 약간의 시간차를 두어 계산기 UI 내부의 버튼을 찾음
|
||||||
|
setTimeout(() => {
|
||||||
|
const acButton = document.querySelector('.keypad-btn.ac, .btn-ac') ||
|
||||||
|
Array.from(document.querySelectorAll('button')).find(el => el.textContent === 'AC');
|
||||||
|
|
||||||
|
if (acButton) {
|
||||||
|
acButton.click();
|
||||||
|
} else {
|
||||||
|
// 버튼을 못 찾으면 강제로 input 이벤트와 Enter/Escape 등을 시뮬레이션
|
||||||
|
angle1Ref.current.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
}
|
||||||
|
// 다시 포커스를 주어 키패드가 유지되도록 함 (필요시)
|
||||||
|
angle1Ref.current.focus();
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 키보드 입력 처리
|
||||||
|
useEffect(() => {
|
||||||
|
const handleKeyDown = (e) => {
|
||||||
|
|
||||||
|
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
|
||||||
|
// 계산기 값이 확정된 후 초기화하기 위해 약간의 지연을 줌
|
||||||
|
setTimeout(() => {
|
||||||
|
resetCalculatorValue();
|
||||||
|
}, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 계산기 키패드가 보이는지 확인
|
||||||
|
const keypadVisible = document.querySelector('.keypad-container')
|
||||||
|
|
||||||
|
// 계산기 키패드가 보이면 계산기가 처리하도록 함
|
||||||
|
if (keypadVisible) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 이미 계산기 input에 포커스가 있으면 계산기가 처리하도록 함
|
||||||
|
if (document.activeElement && document.activeElement.classList.contains('calculator-input')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 엔터키는 계산기가 숨겨진 상태에서만 페이지가 처리
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
// 엔터키를 페이지 레벨로 전달 (useOuterLineWall.js에서 처리)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 숫자 키가 입력되면 계산기 input에 포커스만 주기
|
||||||
|
if (/^[0-9+\-*\/=.]$/.test(e.key) || e.key === 'Backspace' || e.key === 'Delete') {
|
||||||
|
const calcInput = document.querySelector('.calculator-input')
|
||||||
|
if (calcInput) {
|
||||||
|
// 포커스만 주고 이벤트는 preventDefault 하지 않음
|
||||||
|
calcInput.focus()
|
||||||
|
calcInput.click()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// capture: true로 설정하여 다른 핸들러보다 먼저 실행
|
||||||
|
document.addEventListener('keydown', handleKeyDown, { capture: true })
|
||||||
|
return () => document.removeEventListener('keydown', handleKeyDown, { capture: true })
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="outline-wrap">
|
<div className="outline-wrap">
|
||||||
@ -31,19 +130,33 @@ export default function Angle({ props }) {
|
|||||||
className="input-origin block"
|
className="input-origin block"
|
||||||
value={angle1}
|
value={angle1}
|
||||||
ref={angle1Ref}
|
ref={angle1Ref}
|
||||||
onChange={(value) => setAngle1(value)}
|
onChange={(value) => {setAngle1(value)
|
||||||
|
|
||||||
|
// Convert to number and ensure it's within -180 to 180 range
|
||||||
|
const numValue = parseInt(value, 10);
|
||||||
|
if (!isNaN(numValue)) {
|
||||||
|
const clampedValue = Math.min(180, Math.max(-180, numValue));
|
||||||
|
setAngle1(String(clampedValue));
|
||||||
|
} else {
|
||||||
|
setAngle1(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
placeholder="45"
|
placeholder="45"
|
||||||
onFocus={() => (angle1Ref.current.value = '')}
|
onFocus={() => (angle1Ref.current.value = '')}
|
||||||
options={{
|
options={{
|
||||||
allowNegative: false,
|
allowNegative: true,
|
||||||
allowDecimal: true
|
allowDecimal: false
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="reset-btn"
|
className="reset-btn"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
setAngle1(0)
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
resetCalculatorValue2()
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
@ -77,8 +190,11 @@ export default function Angle({ props }) {
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
className="reset-btn"
|
className="reset-btn"
|
||||||
onClick={() => {
|
onClick={(e) => {
|
||||||
setLength1(0)
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
resetCalculatorValue()
|
||||||
}}
|
}}
|
||||||
></button>
|
></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,7 +1,19 @@
|
|||||||
import { useRecoilValue } from 'recoil'
|
import { useRecoilValue } from 'recoil'
|
||||||
import { canvasState } from '@/store/canvasAtom'
|
import { canvasState } from '@/store/canvasAtom'
|
||||||
import { fontSelector } from '@/store/fontAtom'
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
import { useEffect } from 'react'
|
import { useCallback, useEffect } from 'react'
|
||||||
|
|
||||||
|
/** 폰트 타입별 캔버스 오브젝트 이름 매핑 */
|
||||||
|
const FONT_TYPE_TO_OBJ_NAME = {
|
||||||
|
commonText: 'commonText',
|
||||||
|
dimensionLineText: 'dimensionLineText',
|
||||||
|
flowText: 'flowText',
|
||||||
|
lengthText: 'lengthText',
|
||||||
|
circuitNumberText: 'circuitNumber',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 캔버스 오브젝트 이름 → 폰트 타입 역매핑 */
|
||||||
|
const OBJ_NAME_TO_FONT_TYPE = Object.fromEntries(Object.entries(FONT_TYPE_TO_OBJ_NAME).map(([k, v]) => [v, k]))
|
||||||
|
|
||||||
export function useFont() {
|
export function useFont() {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -11,85 +23,98 @@ export function useFont() {
|
|||||||
const lengthText = useRecoilValue(fontSelector('lengthText'))
|
const lengthText = useRecoilValue(fontSelector('lengthText'))
|
||||||
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
|
const circuitNumberText = useRecoilValue(fontSelector('circuitNumberText'))
|
||||||
|
|
||||||
|
/** 폰트 타입별 설정 매핑 */
|
||||||
|
const fontSettings = {
|
||||||
|
commonText,
|
||||||
|
dimensionLineText,
|
||||||
|
flowText,
|
||||||
|
lengthText,
|
||||||
|
circuitNumberText,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 타입별 폰트 설정을 캔버스 오브젝트에 적용하는 공통 함수
|
||||||
|
* @param {string} type - 폰트 타입 (commonText, dimensionLineText, flowText, lengthText, circuitNumberText)
|
||||||
|
* @param {number} delay - 적용 지연 시간 (ms), 기본값 200
|
||||||
|
*/
|
||||||
|
const changeFontByType = useCallback(
|
||||||
|
(type, delay = 200) => {
|
||||||
|
const fontSetting = fontSettings[type]
|
||||||
|
const objName = FONT_TYPE_TO_OBJ_NAME[type]
|
||||||
|
|
||||||
|
if (!fontSetting || !objName) {
|
||||||
|
console.warn(`Invalid font type: ${type}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (canvas && fontSetting.fontWeight?.value) {
|
||||||
|
const textObjs = canvas.getObjects().filter((obj) => obj.name === objName)
|
||||||
|
textObjs.forEach((obj) => {
|
||||||
|
obj.set({
|
||||||
|
fontFamily: fontSetting.fontFamily.value,
|
||||||
|
fontWeight: fontSetting.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
||||||
|
fontStyle: fontSetting.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
||||||
|
fontSize: fontSetting.fontSize.value,
|
||||||
|
fill: fontSetting.fontColor.value,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
canvas.renderAll()
|
||||||
|
}
|
||||||
|
}, delay)
|
||||||
|
},
|
||||||
|
[canvas, fontSettings],
|
||||||
|
)
|
||||||
|
|
||||||
|
const changeAllFonts = () => {
|
||||||
|
changeFontByType('commonText')
|
||||||
|
changeFontByType('dimensionLineText')
|
||||||
|
changeFontByType('flowText')
|
||||||
|
changeFontByType('lengthText')
|
||||||
|
changeFontByType('circuitNumberText')
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 각 폰트 타입별 useEffect */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && commonText.fontWeight.value) {
|
changeFontByType('commonText')
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'commonText')
|
|
||||||
textObjs.forEach((obj) => {
|
|
||||||
obj.set({
|
|
||||||
fontFamily: commonText.fontFamily.value,
|
|
||||||
fontWeight: commonText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
fontStyle: commonText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontSize: commonText.fontSize.value,
|
|
||||||
fill: commonText.fontColor.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}, [commonText])
|
}, [commonText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && dimensionLineText.fontWeight.value) {
|
changeFontByType('dimensionLineText')
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'dimensionLineText')
|
|
||||||
textObjs.forEach((obj) => {
|
|
||||||
obj.set({
|
|
||||||
fontFamily: dimensionLineText.fontFamily.value,
|
|
||||||
fontWeight: dimensionLineText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
fontStyle: dimensionLineText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontSize: dimensionLineText.fontSize.value,
|
|
||||||
fill: dimensionLineText.fontColor.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}, [dimensionLineText])
|
}, [dimensionLineText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && flowText.fontWeight.value) {
|
changeFontByType('flowText')
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'flowText')
|
|
||||||
textObjs.forEach((obj) => {
|
|
||||||
obj.set({
|
|
||||||
fontFamily: flowText.fontFamily.value,
|
|
||||||
fontWeight: flowText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
fontStyle: flowText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontSize: flowText.fontSize.value,
|
|
||||||
fill: flowText.fontColor.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}, [flowText])
|
}, [flowText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && lengthText.fontWeight.value) {
|
changeFontByType('lengthText')
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'lengthText')
|
|
||||||
textObjs.forEach((obj) => {
|
|
||||||
obj.set({
|
|
||||||
fontFamily: lengthText.fontFamily.value,
|
|
||||||
fontWeight: lengthText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
fontStyle: lengthText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontSize: lengthText.fontSize.value,
|
|
||||||
fill: lengthText.fontColor.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}, [lengthText])
|
}, [lengthText])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (canvas && circuitNumberText.fontWeight.value) {
|
changeFontByType('circuitNumberText')
|
||||||
const textObjs = canvas?.getObjects().filter((obj) => obj.name === 'circuitNumber')
|
|
||||||
textObjs.forEach((obj) => {
|
|
||||||
obj.set({
|
|
||||||
fontFamily: circuitNumberText.fontFamily.value,
|
|
||||||
fontWeight: circuitNumberText.fontWeight.value.toLowerCase().includes('bold') ? 'bold' : 'normal',
|
|
||||||
fontStyle: circuitNumberText.fontWeight.value.toLowerCase().includes('italic') ? 'italic' : 'normal',
|
|
||||||
fontSize: circuitNumberText.fontSize.value,
|
|
||||||
fill: circuitNumberText.fontColor.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
canvas.renderAll()
|
|
||||||
}
|
|
||||||
}, [circuitNumberText])
|
}, [circuitNumberText])
|
||||||
|
|
||||||
return {}
|
/** 캔버스에 텍스트 오브젝트 추가 시 자동으로 폰트 적용 */
|
||||||
|
useEffect(() => {
|
||||||
|
if (!canvas) return
|
||||||
|
|
||||||
|
const handleObjectAdded = (e) => {
|
||||||
|
const obj = e.target
|
||||||
|
if (!obj?.name) return
|
||||||
|
|
||||||
|
const fontType = OBJ_NAME_TO_FONT_TYPE[obj.name]
|
||||||
|
if (fontType) {
|
||||||
|
changeFontByType(fontType, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.on('object:added', handleObjectAdded)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
canvas.off('object:added', handleObjectAdded)
|
||||||
|
}
|
||||||
|
}, [canvas, changeFontByType])
|
||||||
|
|
||||||
|
return { changeFontByType, changeAllFonts }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -830,7 +830,7 @@ export const useTrestle = () => {
|
|||||||
return -surfaceCompass
|
return -surfaceCompass
|
||||||
}
|
}
|
||||||
|
|
||||||
let resultAzimuth = moduleCompass
|
let resultAzimuth = parseInt(moduleCompass, 10)
|
||||||
|
|
||||||
switch (direction) {
|
switch (direction) {
|
||||||
case 'south': {
|
case 'south': {
|
||||||
|
|||||||
@ -812,7 +812,7 @@ export function useOuterLineWall(id, propertiesId) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
enterCheck(e)
|
// enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Enter': {
|
case 'Enter': {
|
||||||
|
|||||||
@ -815,7 +815,7 @@ export function usePlacementShapeDrawing(id) {
|
|||||||
if (points.length === 0) {
|
if (points.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
enterCheck(e)
|
// enterCheck(e)
|
||||||
const key = e.key
|
const key = e.key
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'Enter': {
|
case 'Enter': {
|
||||||
|
|||||||
@ -99,6 +99,12 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
// 지붕면 목록
|
// 지붕면 목록
|
||||||
const getRoofSurfaceList = () => {
|
const getRoofSurfaceList = () => {
|
||||||
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
const roofSurfaceList = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE_SETUP_SURFACE)
|
||||||
|
|
||||||
|
roofSurfaceList.forEach((roofSurface) => {
|
||||||
|
const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE && obj.surfaceId === roofSurface.id)
|
||||||
|
roofSurface.northModuleYn = modules.every((module) => module.moduleInfo.northModuleYn === 'Y') ? 'Y' : 'N'
|
||||||
|
})
|
||||||
|
|
||||||
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
|
roofSurfaceList.sort((a, b) => a.left - b.left || b.top - a.top)
|
||||||
|
|
||||||
const result = roofSurfaceList
|
const result = roofSurfaceList
|
||||||
@ -119,6 +125,7 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
roofSurfaceNorthYn: obj.direction === 'north' ? 'Y' : 'N',
|
||||||
|
roofSurfaceNorthModuleYn: obj.northModuleYn,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((surface) => surface.moduleList.length > 0)
|
.filter((surface) => surface.moduleList.length > 0)
|
||||||
@ -139,11 +146,14 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
let remaining = [...arr]
|
let remaining = [...arr]
|
||||||
|
|
||||||
while (remaining.length > 0) {
|
while (remaining.length > 0) {
|
||||||
const { roofSurface, roofSurfaceIncl } = remaining[0]
|
const { roofSurface, roofSurfaceIncl, roofSurfaceNorthModuleYn } = remaining[0]
|
||||||
const key = `${roofSurface}|${roofSurfaceIncl}`
|
const key = `${roofSurface}|${roofSurfaceIncl}|${roofSurfaceNorthModuleYn}`
|
||||||
|
|
||||||
// 해당 그룹 추출
|
// 해당 그룹 추출
|
||||||
const group = remaining.filter((item) => item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl)
|
const group = remaining.filter(
|
||||||
|
(item) =>
|
||||||
|
item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl && item.roofSurfaceNorthModuleYn === roofSurfaceNorthModuleYn,
|
||||||
|
)
|
||||||
|
|
||||||
// 이미 처리했는지 체크 후 저장
|
// 이미 처리했는지 체크 후 저장
|
||||||
if (!seen.has(key)) {
|
if (!seen.has(key)) {
|
||||||
@ -152,7 +162,14 @@ export function useCircuitTrestle(executeEffect = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// remaining에서 제거
|
// remaining에서 제거
|
||||||
remaining = remaining.filter((item) => !(item.roofSurface === roofSurface && item.roofSurfaceIncl === roofSurfaceIncl))
|
remaining = remaining.filter(
|
||||||
|
(item) =>
|
||||||
|
!(
|
||||||
|
item.roofSurface === roofSurface &&
|
||||||
|
item.roofSurfaceIncl === roofSurfaceIncl &&
|
||||||
|
item.roofSurfaceNorthModuleYn === roofSurfaceNorthModuleYn
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { basicSettingState } from '@/store/settingAtom'
|
|||||||
import { calcLineActualSize } from '@/util/qpolygon-utils'
|
import { calcLineActualSize } from '@/util/qpolygon-utils'
|
||||||
import { getDegreeByChon } from '@/util/canvas-util'
|
import { getDegreeByChon } from '@/util/canvas-util'
|
||||||
import { useText } from '@/hooks/useText'
|
import { useText } from '@/hooks/useText'
|
||||||
|
import { fontSelector } from '@/store/fontAtom'
|
||||||
|
|
||||||
export const useLine = () => {
|
export const useLine = () => {
|
||||||
const canvas = useRecoilValue(canvasState)
|
const canvas = useRecoilValue(canvasState)
|
||||||
@ -23,14 +24,15 @@ export const useLine = () => {
|
|||||||
const angleUnit = useRecoilValue(showAngleUnitSelector)
|
const angleUnit = useRecoilValue(showAngleUnitSelector)
|
||||||
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
|
const roofSizeSet = useRecoilValue(basicSettingState).roofSizeSet
|
||||||
const globalPitch = useRecoilValue(globalPitchState)
|
const globalPitch = useRecoilValue(globalPitchState)
|
||||||
|
const lengthText = useRecoilValue(fontSelector('lengthText'))
|
||||||
|
|
||||||
const { changeCorridorDimensionText } = useText()
|
const { changeCorridorDimensionText } = useText()
|
||||||
|
|
||||||
const addLine = (points = [], options) => {
|
const addLine = (points = [], options) => {
|
||||||
const line = new QLine(points, {
|
const line = new QLine(points, {
|
||||||
...options,
|
...options,
|
||||||
fontSize: fontSize,
|
fontSize: lengthText.fontSize.value,
|
||||||
fontFamily: fontFamily,
|
fontFamily: lengthText.fontFamily.value,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (line.length < 1) {
|
if (line.length < 1) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user