diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index 9c9791c9..ea316903 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -182,4 +182,46 @@ export const QLine = fabric.util.createClass(fabric.Line, { } return this }, + + containsPoint: function(point) { + const boundingRect = this.getBoundingRect(true) + + // 선의 방향 판단 + const dx = Math.abs(this.x2 - this.x1) + const dy = Math.abs(this.y2 - this.y1) + const isVertical = dx < dy && dx < 10 // 세로선 (가로 변화가 작음) + const isDiagonal = dx > 10 && dy > 10 // 대각선 (가로, 세로 모두 변화) + + let reducedWidth, reducedHeight + + if (isDiagonal) { + // 대각선의 경우: 1/2 크기 + reducedWidth = boundingRect.width / 2 + reducedHeight = boundingRect.height / 2 + } else if (isVertical) { + // 세로선의 경우: 가로 선택범위 2배 + reducedWidth = boundingRect.width * 2 + reducedHeight = boundingRect.height / 3 + } else { + // 가로선의 경우: 세로 선택범위 2배 + reducedWidth = boundingRect.width / 3 + reducedHeight = boundingRect.height * 2 + } + + // 축소된 영역의 중심점 계산 + const centerX = boundingRect.left + boundingRect.width / 2 + const centerY = boundingRect.top + boundingRect.height / 2 + + // 축소된 영역의 경계 계산 + const left = centerX - reducedWidth / 2 + const top = centerY - reducedHeight / 2 + const right = centerX + reducedWidth / 2 + const bottom = centerY + reducedHeight / 2 + + // 점이 축소된 영역 내에 있는지 확인 + return point.x >= left && + point.x <= right && + point.y >= top && + point.y <= bottom + }, }) diff --git a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx index 26dbf402..bf3c40cc 100644 --- a/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx +++ b/src/components/floor-plan/modal/circuitTrestle/CircuitTrestleSetting.jsx @@ -109,10 +109,10 @@ export default function CircuitTrestleSetting({ id }) { const capture = (type) => { beforeCapture() - setTimeout(() => { - handleCanvasToPng(type) - afterCapture() - }, 1000) + + handleCanvasToPng(type) + + afterCapture() return new Promise((resolve) => { setTimeout(() => { @@ -124,8 +124,22 @@ export default function CircuitTrestleSetting({ id }) { // 캡쳐 전 처리 const beforeCapture = () => { // setCanvasZoom(100) - const x = canvas.width / 2 - const y = canvas.height / 2 + const arrows = canvas.getObjects().filter((obj) => obj.name === 'arrow') + + let x,y + + x = canvas.width / 2 + y = canvas.height / 2 + + // 화살표가 음수 영역에 있을 경우 0,0 기준으로 50% 축소 + if(arrows.every((arrow) => arrow.left > 0) && arrows.every((arrow) => arrow.top > 0)) { + x = 0 + y = 0 + } + + + + canvas.zoomToPoint(new fabric.Point(x, y), 0.5) changeFontSize('lengthText', '28') changeFontSize('circuitNumber', '28') diff --git a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx index c91325c0..2970a7ab 100644 --- a/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx +++ b/src/components/floor-plan/modal/roofAllocation/ActualSizeSetting.jsx @@ -27,7 +27,7 @@ export default function ActualSizeSetting(props) { const handleFinish = () => { swalFire({ - text: '완료 하시겠습니까?', + text: getMessage("modal.roof.allocation.auxiliary.accept"), type: 'confirm', confirmFn: () => { handleAlloc() @@ -37,7 +37,7 @@ export default function ActualSizeSetting(props) { const handleClose = () => { swalFire({ - text: '완료 하시겠습니까?', + text: getMessage("modal.roof.allocation.auxiliary.accept"), type: 'confirm', confirmFn: () => { handleAlloc() diff --git a/src/components/header/Header.jsx b/src/components/header/Header.jsx index 2e9f297c..8b37b134 100644 --- a/src/components/header/Header.jsx +++ b/src/components/header/Header.jsx @@ -241,7 +241,7 @@ export default function Header(props) { e.preventDefault() // 기본 네비게이션 방지 e.stopPropagation() // 이벤트 전파 방지 swalFire({ - text : getMessage(common.link.confirm), // 적절한 확인 메시지 + text : getMessage('common.link.confirm'), // 적절한 확인 메시지 type : 'confirm', confirmFn: () => { // 확인 버튼 클릭 시 실행 @@ -323,14 +323,28 @@ export default function Header(props) {

{ + onClick={(e) => { setStuffSearch({ ...stuffSearch, code: 'DELETE', }) if (pathName === '/') { window.location.reload() + } else if(pathName === '/floor-plan') { + e.preventDefault() // 기본 네비게이션 방지 + e.stopPropagation() // 이벤트 전파 방지 + swalFire({ + text: getMessage('common.link.confirm'), // 적절한 확인 메시지 + type: 'confirm', + confirmFn: () => { + // 확인 버튼 클릭 시 기존 로직 실행 + //removeStuffRecoil(m) + router.push('/') + } + }) } + + }} >

diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 17f6711a..9fa75e67 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -807,59 +807,57 @@ export const useTrestle = () => { const getAzimuth = (parent) => { const { moduleCompass, surfaceCompass, direction } = parent - let resultAzimuth = surfaceCompass || moduleCompass + if(surfaceCompass) { + return -surfaceCompass + } + + let resultAzimuth = moduleCompass + + switch (direction) { case 'south': { - if (resultAzimuth < 0) { - return -1 * resultAzimuth - } else if (resultAzimuth === 0) { - return 0 - } else if (resultAzimuth < 180) { - return -1 * resultAzimuth - } else if (resultAzimuth === 180) { - return 180 - } + return resultAzimuth } case 'north': { if (resultAzimuth < 0) { - return -1 * (180 + resultAzimuth) + return 180 + resultAzimuth } else if (resultAzimuth === 0) { return 180 } else if (resultAzimuth < 180) { - return 180 - resultAzimuth + return resultAzimuth - 180 } else if (resultAzimuth === 180) { return 0 } } case 'west': { if (resultAzimuth > -180 && resultAzimuth < 0) { - return -1 * (90 + resultAzimuth) + return 90 + resultAzimuth } else if (resultAzimuth === 0) { - return -180 + (90 - resultAzimuth) + return 90 - resultAzimuth } else if (resultAzimuth < 180) { if (resultAzimuth > 90) { - return 180 + (90 - resultAzimuth) + return -180 + (resultAzimuth - 90) } - return -180 + (90 - resultAzimuth) + return 180 + (resultAzimuth - 90) } else if (resultAzimuth === 180) { - return 180 + (90 - resultAzimuth) + return -180 + (resultAzimuth - 90) } } case 'east': { if (resultAzimuth === 0) { - return 90 - resultAzimuth + return -180 + (90 - resultAzimuth) } else if (resultAzimuth > 0 && resultAzimuth < 180) { - return 90 - resultAzimuth + return resultAzimuth - 90 } else if (resultAzimuth === 180) { - return 90 - resultAzimuth + return resultAzimuth - 90 } else if (resultAzimuth > -180 && resultAzimuth < 0) { - if (resultAzimuth < -90) { - return -180 - (90 + resultAzimuth) + if (resultAzimuth <= -90) { + return 180 + (90 + resultAzimuth) } - return 180 - (90 + resultAzimuth) + return -180 + (90 + resultAzimuth) } } } diff --git a/src/hooks/roofcover/useAuxiliaryDrawing.js b/src/hooks/roofcover/useAuxiliaryDrawing.js index c854ae77..aad5a715 100644 --- a/src/hooks/roofcover/useAuxiliaryDrawing.js +++ b/src/hooks/roofcover/useAuxiliaryDrawing.js @@ -710,9 +710,34 @@ export function useAuxiliaryDrawing(id, isUseEffect = true) { //보조선과 만나는 점을 찾는다. innerLines.forEach((line2) => { + // line1이 canvas에 없는 경우 return + if (!canvas.getObjects().includes(line1)) { + return + } + if (line1 === line2) { return } + // const originLine1 = { + // stroke : line1.stroke, + // strokeWidth: line1.strokeWidth + // } + // const originLine2 = { + // stroke: line2.stroke, + // strokeWidth: line2.strokeWidth + // } + // line1.set({stroke: 'red', strokeWidth: 10}) + // line2.set({stroke: 'blue', strokeWidth: 10}) + // + // canvas.renderAll() + // + // debugger + // + // line1.set(originLine1) + // line2.set(originLine2) + // canvas.renderAll() + + const intersectionPoint = calculateIntersection(line1, line2) if (!intersectionPoint) { return @@ -723,7 +748,7 @@ export function useAuxiliaryDrawing(id, isUseEffect = true) { const distance1 = distanceBetweenPoints({ x: line1.x1, y: line1.y1 }, intersectionPoint) const distance2 = distanceBetweenPoints({ x: line1.x2, y: line1.y2 }, intersectionPoint) - if (distance1 < 1 || distance2 < 1) { + if (distance1 < 2 || distance2 < 2) { return } //historyLine에서 기존 line을 제거한다. diff --git a/src/hooks/roofcover/useRoofAllocationSetting.js b/src/hooks/roofcover/useRoofAllocationSetting.js index 53d1956b..dfe4c87d 100644 --- a/src/hooks/roofcover/useRoofAllocationSetting.js +++ b/src/hooks/roofcover/useRoofAllocationSetting.js @@ -342,7 +342,7 @@ export function useRoofAllocationSetting(id) { if (!checkInnerLines()) { apply() } else { - swalFire({ type: 'alert', icon: 'error', text: getMessage('실제치수를 입력해 주세요.') }) + swalFire({ type: 'alert', icon: 'error', text: getMessage('modal.roof.allocation.auxiliary.size.form') }) } } diff --git a/src/locales/ja.json b/src/locales/ja.json index f27b8d7f..a91da599 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -1117,5 +1117,7 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2種混合時\rの最大段数", "modal.module.basic.setting.module.placement.mix.asg.yn.error": "混合インストール不可能なモジュールです。 (JA)", "modal.module.basic.setting.module.placement.mix.asg.yn": "混合", - "modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。" + "modal.module.basic.setting.module.placement.over.max.row": "{0} 最大段数超過しました。最大段数表を参考にしてください。", + "modal.roof.allocation.auxiliary.accept": "完了しますか?", + "modal.roof.allocation.auxiliary.size.form": "補助線の寸法を入力してください。" } diff --git a/src/locales/ko.json b/src/locales/ko.json index 3dd00617..c0cd43af 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -1117,5 +1117,7 @@ "modal.module.basic.setting.module.placement.max.rows.multiple": "2종 혼합 최대단수", "modal.module.basic.setting.module.placement.mix.asg.yn.error": "혼합 설치 불가능한 모듈입니다.", "modal.module.basic.setting.module.placement.mix.asg.yn": "혼합", - "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요." + "modal.module.basic.setting.module.placement.over.max.row": "{0}의 최대단수를 초과했습니다. 최대단수표를 참고해 주세요.", + "modal.roof.allocation.auxiliary.accept": "완료하시겠습니까?", + "modal.roof.allocation.auxiliary.size.form": "실제치수를 입력해 주세요." }