From b3af3cd0e003dc267baa7a0f445195fa5f23e334 Mon Sep 17 00:00:00 2001 From: Jaeyoung Lee Date: Tue, 25 Feb 2025 13:46:10 +0900 Subject: [PATCH] =?UTF-8?q?=EC=99=B8=EB=B2=BD=EC=84=A0=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=91,=20=EC=98=A4=ED=94=84=EC=85=8B=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modal/wallLineOffset/type/Offset.jsx | 2 +- .../modal/wallLineOffset/type/WallLine.jsx | 4 +- src/hooks/roofcover/useOuterLineWall.js | 10 - src/hooks/roofcover/useRoofShapeSetting.js | 16 +- .../roofcover/useWallLineOffsetSetting.js | 346 +++++++++--------- src/hooks/useMode.js | 74 +++- src/hooks/usePolygon.js | 4 +- src/util/qpolygon-utils.js | 17 +- 8 files changed, 251 insertions(+), 222 deletions(-) diff --git a/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx b/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx index 418a9419..4e7545cb 100644 --- a/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx +++ b/src/components/floor-plan/modal/wallLineOffset/type/Offset.jsx @@ -74,7 +74,7 @@ export default function Offset({ length1Ref, arrow1Ref, currentWallLineRef }) {
- +
mm
diff --git a/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx b/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx index 581f57f3..92f6a10b 100644 --- a/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx +++ b/src/components/floor-plan/modal/wallLineOffset/type/WallLine.jsx @@ -46,7 +46,7 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
- +
mm
@@ -80,7 +80,7 @@ export default forwardRef(function WallLine({ length1Ref, length2Ref, arrow1Ref,
- +
mm
diff --git a/src/hooks/roofcover/useOuterLineWall.js b/src/hooks/roofcover/useOuterLineWall.js index 7e94f074..a1292ccf 100644 --- a/src/hooks/roofcover/useOuterLineWall.js +++ b/src/hooks/roofcover/useOuterLineWall.js @@ -143,7 +143,6 @@ export function useOuterLineWall(id, propertiesId) { const mouseDown = (e) => { let pointer = getIntersectMousePoint(e) pointer = { x: Big(pointer.x).round(1).toNumber(), y: Big(pointer.y).round(1).toNumber() } - console.log('mouseDown', pointer, points) if (points.length === 0) { setPoints((prev) => [...prev, pointer]) @@ -151,14 +150,11 @@ export function useOuterLineWall(id, propertiesId) { const lastPoint = points[points.length - 1] let newPoint = { x: pointer.x, y: pointer.y } const length = distanceBetweenPoints(lastPoint, newPoint) - console.log('length', length) if (verticalHorizontalMode) { const vector = { x: Big(pointer.x).minus(Big(points[points.length - 1].x)), y: Big(pointer.y).minus(Big(points[points.length - 1].y)), } - // const slope = Math.abs(vector.y / vector.x) // 기울기 계산 - console.log('vector', vector.x.toNumber(), vector.y.toNumber(), Math.abs(vector.y.toNumber() / vector.x.toNumber()) >= 1) const slope = vector.x.eq(0) ? Big(1) : vector.y.div(vector.x).abs() // 기울기 계산 let scaledVector @@ -167,13 +163,11 @@ export function useOuterLineWall(id, propertiesId) { // 기울기가 1 이상이면 x축 방향으로 그림 scaledVector = { x: 0, - // y: vector.y >= 0 ? Number(length) : -Number(length), y: vector.y.gte(0) ? Big(length).toNumber() : Big(length).neg().toNumber(), } } else { // 기울기가 1 미만이면 y축 방향으로 그림 scaledVector = { - // x: vector.x >= 0 ? Number(length) : -Number(length), x: vector.x.gte(0) ? Big(length).toNumber() : Big(length).neg().toNumber(), y: 0, } @@ -182,8 +176,6 @@ export function useOuterLineWall(id, propertiesId) { const verticalLength = scaledVector.y const horizontalLength = scaledVector.x - console.log('verticalLength', verticalLength, 'horizontalLength', horizontalLength) - newPoint = { x: Big(lastPoint.x).plus(horizontalLength).toNumber(), y: Big(lastPoint.y).plus(verticalLength).toNumber(), @@ -876,8 +868,6 @@ export function useOuterLineWall(id, propertiesId) { const firstPoint = points[0] - console.log('points 좌표 : ', points) - points.forEach((point, idx) => { if (idx === 0 || !isAllRightAngle) { return diff --git a/src/hooks/roofcover/useRoofShapeSetting.js b/src/hooks/roofcover/useRoofShapeSetting.js index e9b7bafe..ea21aecb 100644 --- a/src/hooks/roofcover/useRoofShapeSetting.js +++ b/src/hooks/roofcover/useRoofShapeSetting.js @@ -63,13 +63,6 @@ export function useRoofShapeSetting(id) { }, [jerkinHeadPitch]) useEffect(() => { - const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') - // if (!outerLineFix || outerLines.length === 0) { - // swalFire({ text: '외벽선이 없습니다.' }) - // // setShowRoofShapeSettingModal(false) - // closePopup(id) - // } - return () => { if (!isFixRef.current) { return @@ -77,6 +70,7 @@ export function useRoofShapeSetting(id) { const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') const pitchTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText') + canvas.remove(...pitchTexts) outerLines.forEach((line) => { let stroke, strokeWidth @@ -115,14 +109,6 @@ export function useRoofShapeSetting(id) { return } - /*const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') - outerLines.forEach((line) => { - line.set({ - stroke: '#000000', - strokeWidth: 4, - }) - })*/ - currentObject.set({ stroke: '#EA10AC', strokeWidth: 4, diff --git a/src/hooks/roofcover/useWallLineOffsetSetting.js b/src/hooks/roofcover/useWallLineOffsetSetting.js index 22af0f49..548b509c 100644 --- a/src/hooks/roofcover/useWallLineOffsetSetting.js +++ b/src/hooks/roofcover/useWallLineOffsetSetting.js @@ -6,6 +6,8 @@ import { useEvent } from '@/hooks/useEvent' import { useLine } from '@/hooks/useLine' import { useSwal } from '@/hooks/useSwal' import { usePopup } from '@/hooks/usePopup' +import Big from 'big.js' +import { outerLineFixState } from '@/store/outerLineAtom' // 외벽선 편집 및 오프셋 export function useWallLineOffsetSetting(id) { @@ -28,6 +30,8 @@ export function useWallLineOffsetSetting(id) { const [isLoading, setIsLoading] = useState(false) + const outerLineFix = useRecoilValue(outerLineFixState) + const drawLine = (point1, point2, idx, direction = currentWallLineRef.current.direction) => { const line = addLine([point1.x, point1.y, point2.x, point2.y], { stroke: 'black', @@ -59,7 +63,7 @@ export function useWallLineOffsetSetting(id) { useEffect(() => { const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') - if (outerLines.length === 0) { + if (!outerLineFix || outerLines.length === 0) { swalFire({ text: '외벽선이 없습니다.' }) closePopup(id) return @@ -277,7 +281,7 @@ export function useWallLineOffsetSetting(id) { } } - rearrangeOuterLine(currentIdx + 1) + reArrangeOuterLine(currentIdx + 1) drawLine(point1, point2, currentIdx) drawLine(point2, point3, currentIdx + 1) @@ -286,229 +290,217 @@ export function useWallLineOffsetSetting(id) { canvas.remove(currentWallLineRef.current) currentWallLineRef.current = null canvas.renderAll() + + canvas + .getObjects() + .filter((obj) => obj.name === 'outerLine') + .forEach((obj) => obj.fire('modified')) } - const rearrangeOuterLine = (idxParam) => { + /** + * outreLine의 index를 조절한다. + * @param idxParam + * @param isNegative + */ + const reArrangeOuterLine = (idxParam, isNegative = false) => { const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') outerLines.forEach((outerLine) => { if (outerLine.idx >= idxParam) { - outerLine.idx = outerLine.idx + 1 + outerLine.idx = isNegative ? outerLine.idx - 1 : outerLine.idx + 1 } }) } + /** + * offset 저장 + */ const handleOffsetSave = () => { - const direction = currentWallLineRef.current.direction - let canDirections = direction === 'left' || direction === 'right' ? ['up', 'down'] : ['left', 'right'] - const currentIdx = currentWallLineRef.current.idx + if (!currentObject) return + const currentLine = currentObject + const currentVector = currentLine.y1 === currentLine.y2 ? 'horizontal' : 'vertical' + const canDirections = currentVector === 'horizontal' ? ['up', 'down'] : ['left', 'right'] if (!canDirections.includes(arrow1Ref.current)) { alert('방향을 다시 선택하세요') return } - const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + outerLines.sort((a, b) => a.idx - b.idx) - const idx = currentWallLineRef.current.idx - const prevIdx = idx - 1 <= 0 ? outerLines.length : idx - 1 - const nextIdx = idx + 1 > outerLines.length ? 1 : idx + 1 + const currentIdx = currentLine.idx + const prevIdx = currentIdx - 1 <= 0 ? outerLines.length : currentIdx - 1 + const nextIdx = currentLine.idx + 1 > outerLines.length ? 1 : currentIdx + 1 - const currentLine = currentWallLineRef.current const prevLine = outerLines.find((line) => line.idx === prevIdx) const nextLine = outerLines.find((line) => line.idx === nextIdx) + const prevVector = prevLine.y1 === prevLine.y2 ? 'horizontal' : 'vertical' + const nextVector = nextLine.y1 === nextLine.y2 ? 'horizontal' : 'vertical' - const length = length1Ref.current.value / 10 - const currentLineX = Math.floor(Math.max(currentLine.x1, currentLine.x2)) - const currentLineY = Math.floor(Math.max(currentLine.y1, currentLine.y2)) - switch (arrow1Ref.current) { - case 'up': { - if (prevLine.direction === currentLine.direction) { - const newX = - currentLine.direction === 'left' - ? Math.floor(Math.max(currentLine.x1, currentLine.x2)) - : Math.floor(Math.min(currentLine.x1, currentLine.x2)) + const offsetLength = Big(Number(length1Ref.current.value)).div(10) + if (offsetLength.eq(0)) return - const newPoint1 = { x: newX, y: currentLineY - length } - const newPoint2 = { x: prevLine.x2, y: prevLine.y2 } - rearrangeOuterLine(currentIdx) - drawLine(newPoint1, newPoint2, currentIdx, 'top') + const currentLineMinX = Big(Math.max(currentLine.x1, currentLine.x2)) + const currentLineMaxX = Big(Math.max(currentLine.x1, currentLine.x2)) + const currentLineMinY = Big(Math.max(currentLine.y1, currentLine.y2)) + const currentLineMaxY = Big(Math.max(currentLine.y1, currentLine.y2)) - if (Math.abs(currentLineY - nextLine.y1) < 2) { - nextLine.set({ y1: currentLineY - length }) - } else { - nextLine.set({ y2: currentLineY - length }) - } - } else if (nextLine.direction === currentLine.direction) { - const newX = - currentLine.direction === 'left' - ? Math.floor(Math.min(currentLine.x1, currentLine.x2)) - : Math.floor(Math.max(currentLine.x1, currentLine.x2)) - - const newPoint1 = { x: newX, y: currentLineY - length } - const newPoint2 = { x: nextLine.x1, y: nextLine.y1 } - rearrangeOuterLine(currentIdx + 1) - drawLine(newPoint1, newPoint2, currentIdx + 1, 'top') - - if (Math.abs(currentLineY - prevLine.y1) < 2) { - prevLine.set({ y1: currentLineY - length }) - } else { - prevLine.set({ y2: currentLineY - length }) - } + if (currentVector === 'horizontal') { + const prevX = currentLine.x1 < currentLine.x2 ? Math.min(currentLine.x1, currentLine.x2) : Math.max(currentLine.x1, currentLine.x2) + const nextX = currentLine.x1 < currentLine.x2 ? Math.max(currentLine.x1, currentLine.x2) : Math.min(currentLine.x1, currentLine.x2) + if (arrow1Ref.current === 'up') { + currentLine.set({ y1: currentLineMaxY.minus(offsetLength).toNumber(), y2: currentLineMaxY.minus(offsetLength).toNumber() }) + if (prevVector === currentVector) { + const point1 = { x: prevX, y: prevLine.y2 } + const point2 = { x: prevX, y: currentLine.y1 } + reArrangeOuterLine(currentIdx) + drawLine(point1, point2, currentIdx, arrow1Ref.current) } else { - if (Math.abs(currentLineY - prevLine.y1) < 2) { - prevLine.set({ y1: prevLine.y1 - length }) + if (Big(prevLine.y1).minus(currentLineMinY).abs().lte(Big(prevLine.y2).minus(currentLineMinY).abs())) { + prevLine.set({ y1: currentLine.y1 }) } else { - prevLine.set({ y2: prevLine.y2 - length }) + prevLine.set({ y2: currentLine.y1 }) } - if (Math.abs(currentLineY - nextLine.y1) < 2) { - nextLine.set({ y1: nextLine.y1 - length }) - } else { - nextLine.set({ y2: nextLine.y2 - length }) + if (Big(prevLine.y1).minus(Big(prevLine.y2)).eq(0)) { + reArrangeOuterLine(currentIdx - 1, true) + canvas.remove(prevLine) + } + } + if (nextVector === currentVector) { + const point1 = { x: nextX, y: nextLine.y2 } + const point2 = { x: nextX, y: currentLine.y1 } + reArrangeOuterLine(currentIdx + 1) + drawLine(point1, point2, currentIdx + 1, arrow1Ref.current) + } else { + if (Big(nextLine.y1).minus(currentLineMaxY).abs().lte(Big(nextLine.y2).minus(currentLineMaxY).abs())) { + nextLine.set({ y1: currentLine.y1 }) + } else { + nextLine.set({ y2: currentLine.y1 }) + } + if (Big(nextLine.y1).minus(Big(nextLine.y2)).eq(0)) { + reArrangeOuterLine(currentIdx + 1, true) + canvas.remove(nextLine) } } - - currentLine.set({ y1: currentLine.y1 - length, y2: currentLine.y2 - length }) - - break } - case 'down': { - if (prevLine.direction === currentLine.direction) { - const newX = - currentLine.direction === 'left' - ? Math.floor(Math.max(currentLine.x1, currentLine.x2)) - : Math.floor(Math.min(currentLine.x1, currentLine.x2)) - const newPoint1 = { x: newX, y: currentLineY + length } - const newPoint2 = { x: prevLine.x2, y: prevLine.y2 } - rearrangeOuterLine(currentIdx) - drawLine(newPoint1, newPoint2, currentIdx, 'bottom') - if (Math.abs(currentLineY - nextLine.y1) < 2) { - nextLine.set({ y1: currentLineY + length }) - } else { - nextLine.set({ y2: currentLineY + length }) - } - } else if (nextLine.direction === currentLine.direction) { - const newX = - currentLine.direction === 'left' - ? Math.floor(Math.min(currentLine.x1, currentLine.x2)) - : Math.floor(Math.max(currentLine.x1, currentLine.x2)) - const newPoint1 = { x: newX, y: currentLineY + length } - const newPoint2 = { x: nextLine.x1, y: nextLine.y1 } - rearrangeOuterLine(currentIdx + 1) - drawLine(newPoint1, newPoint2, currentIdx + 1, 'bottom') - if (Math.abs(currentLineY - prevLine.y1) < 2) { - prevLine.set({ y1: currentLineY + length }) - } else { - prevLine.set({ y2: currentLineY + length }) - } + if (arrow1Ref.current === 'down') { + currentLine.set({ y1: currentLineMaxY.plus(offsetLength).toNumber(), y2: currentLineMaxY.plus(offsetLength).toNumber() }) + if (prevVector === currentVector) { + const point1 = { x: prevX, y: prevLine.y2 } + const point2 = { x: prevX, y: currentLine.y1 } + reArrangeOuterLine(currentIdx) + drawLine(point1, point2, currentIdx, arrow1Ref.current) } else { - if (Math.abs(currentLineY - prevLine.y1) < 2) { - prevLine.set({ y1: prevLine.y1 + length }) + if (Big(prevLine.y1).minus(currentLineMinY).abs().lte(Big(prevLine.y2).minus(currentLineMinY).abs())) { + prevLine.set({ y1: currentLine.y1 }) } else { - prevLine.set({ y2: prevLine.y2 + length }) + prevLine.set({ y2: currentLine.y1 }) } - if (Math.abs(currentLineY - nextLine.y1) < 2) { - nextLine.set({ y1: nextLine.y1 + length }) - } else { - nextLine.set({ y2: nextLine.y2 + length }) + if (Big(prevLine.y1).minus(Big(prevLine.y2)).eq(0)) { + reArrangeOuterLine(currentIdx - 1, true) + canvas.remove(prevLine) + } + } + if (nextVector === currentVector) { + const point1 = { x: nextX, y: nextLine.y2 } + const point2 = { x: nextX, y: currentLine.y1 } + reArrangeOuterLine(currentIdx + 1) + drawLine(point1, point2, currentIdx + 1, arrow1Ref.current) + } else { + if (Big(nextLine.y1).minus(currentLineMaxY).abs().lte(Big(nextLine.y2).minus(currentLineMaxY).abs())) { + nextLine.set({ y1: currentLine.y1 }) + } else { + nextLine.set({ y2: currentLine.y1 }) + } + if (Big(nextLine.y1).minus(Big(nextLine.y2)).eq(0)) { + reArrangeOuterLine(currentIdx + 1, true) + canvas.remove(nextLine) } } - - currentLine.set({ y1: currentLine.y1 + length, y2: currentLine.y2 + length }) - break } - case 'left': { - if (prevLine.direction === currentLine.direction) { - const newY = - currentLine.direction === 'top' - ? Math.floor(Math.max(currentLine.y1, currentLine.y2)) - : Math.floor(Math.min(currentLine.y1, currentLine.y2)) - const newPoint1 = { x: currentLineX - length, y: newY } - const newPoint2 = { x: prevLine.x2, y: prevLine.y2 } - rearrangeOuterLine(currentIdx) - drawLine(newPoint1, newPoint2, currentIdx, 'left') - if (Math.abs(currentLineX - nextLine.x1) < 2) { - nextLine.set({ x1: currentLineX - length }) - } else { - nextLine.set({ x2: currentLineX - length }) - } - } else if (nextLine.direction === currentLine.direction) { - const newY = - currentLine.direction === 'top' - ? Math.floor(Math.min(currentLine.y1, currentLine.y2)) - : Math.floor(Math.max(currentLine.y1, currentLine.y2)) - const newPoint1 = { x: currentLineX - length, y: newY } - const newPoint2 = { x: nextLine.x1, y: nextLine.y1 } - rearrangeOuterLine(currentIdx + 1) - drawLine(newPoint1, newPoint2, currentIdx + 1, 'left') - if (Math.abs(currentLineX - prevLine.x1) < 2) { - prevLine.set({ x1: currentLineX - length }) - } else { - prevLine.set({ x2: currentLineX - length }) - } - } else { - if (Math.abs(currentLineX - prevLine.x1) < 2) { - prevLine.set({ x1: prevLine.x1 - length }) - } else { - prevLine.set({ x2: prevLine.x2 - length }) - } + } else { + const prevY = currentLine.y1 < currentLine.y2 ? Math.min(currentLine.y1, currentLine.y2) : Math.max(currentLine.y1, currentLine.y2) + const nextY = currentLine.y1 < currentLine.y2 ? Math.max(currentLine.y1, currentLine.y2) : Math.min(currentLine.y1, currentLine.y2) + if (arrow1Ref.current === 'left') { + currentLine.set({ x1: currentLineMaxX.minus(offsetLength).toNumber(), x2: currentLineMaxX.minus(offsetLength).toNumber() }) - if (Math.abs(currentLineX - nextLine.x1) < 2) { - nextLine.set({ x1: nextLine.x1 - length }) + if (prevVector === currentVector) { + const point1 = { x: prevLine.x2, y: prevY } + const point2 = { x: currentLine.x1, y: prevY } + reArrangeOuterLine(currentIdx) + drawLine(point1, point2, currentIdx, arrow1Ref.current) + } else { + if (Big(prevLine.x1).minus(currentLineMinX).abs().lte(Big(prevLine.x2).minus(currentLineMinX).abs())) { + prevLine.set({ x1: currentLine.x1 }) } else { - nextLine.set({ x2: nextLine.x2 - length }) + prevLine.set({ x2: currentLine.x1 }) + } + if (Big(prevLine.x1).minus(Big(prevLine.x2)).eq(0)) { + reArrangeOuterLine(currentIdx - 1, true) + canvas.remove(prevLine) + } + } + if (nextVector === currentVector) { + const point1 = { x: currentLine.x2, y: nextY } + const point2 = { x: nextLine.x1, y: nextY } + reArrangeOuterLine(currentIdx + 1) + drawLine(point1, point2, currentIdx + 1, arrow1Ref.current) + } else { + if (Big(nextLine.x1).minus(currentLineMaxX).abs().lte(Big(nextLine.x2).minus(currentLineMaxX).abs())) { + nextLine.set({ x1: currentLine.x2 }) + } else { + nextLine.set({ x2: currentLine.x2 }) + } + if (Big(nextLine.x1).minus(Big(nextLine.x2)).eq(0)) { + reArrangeOuterLine(currentIdx + 1, true) + canvas.remove(nextLine) } } - - currentLine.set({ x1: currentLine.x1 - length, x2: currentLine.x2 - length }) - break } - case 'right': { - if (prevLine.direction === currentLine.direction) { - const newY = - currentLine.direction === 'top' - ? Math.floor(Math.max(currentLine.y1, currentLine.y2)) - : Math.floor(Math.min(currentLine.y1, currentLine.y2)) - const newPoint1 = { x: currentLineX + length, y: newY } - const newPoint2 = { x: prevLine.x2, y: prevLine.y2 } - rearrangeOuterLine(currentIdx) - drawLine(newPoint1, newPoint2, currentIdx, 'right') - if (Math.abs(currentLineX - nextLine.x1) < 2) { - nextLine.set({ x1: currentLineX + length }) - } else { - nextLine.set({ x2: currentLineX + length }) - } - } else if (nextLine.direction === currentLine.direction) { - const newY = - currentLine.direction === 'top' - ? Math.floor(Math.min(currentLine.y1, currentLine.y2)) - : Math.floor(Math.max(currentLine.y1, currentLine.y2)) - const newPoint1 = { x: currentLineX + length, y: newY } - const newPoint2 = { x: nextLine.x1, y: nextLine.y1 } - rearrangeOuterLine(currentIdx + 1) - drawLine(newPoint1, newPoint2, currentIdx + 1, 'right') + if (arrow1Ref.current === 'right') { + currentLine.set({ x1: currentLineMaxX.plus(offsetLength).toNumber(), x2: currentLineMaxX.plus(offsetLength).toNumber() }) - if (Math.abs(currentLineX - prevLine.x1) < 2) { - prevLine.set({ x1: currentLineX + length }) - } else { - prevLine.set({ x2: currentLineX + length }) - } + if (prevVector === currentVector) { + const point1 = { x: prevLine.x2, y: prevY } + const point2 = { x: currentLine.x1, y: prevY } + reArrangeOuterLine(currentIdx) + drawLine(point1, point2, currentIdx, arrow1Ref.current) } else { - if (Math.abs(currentLineX - prevLine.x1) < 2) { - prevLine.set({ x1: prevLine.x1 + length }) + if (Big(prevLine.x1).minus(currentLineMinX).abs().lte(Big(prevLine.x2).minus(currentLineMinX).abs())) { + prevLine.set({ x1: currentLine.x1 }) } else { - prevLine.set({ x2: prevLine.x2 + length }) + prevLine.set({ x2: currentLine.x1 }) } - if (Math.abs(currentLineX - nextLine.x1) < 2) { - nextLine.set({ x1: nextLine.x1 + length }) - } else { - nextLine.set({ x2: nextLine.x2 + length }) + + if (Big(prevLine.x1).minus(Big(prevLine.x2)).eq(0)) { + reArrangeOuterLine(currentIdx - 1, true) + canvas.remove(prevLine) } } + if (nextVector === currentVector) { + const point1 = { x: currentLine.x2, y: nextY } + const point2 = { x: nextLine.x1, y: nextY } + reArrangeOuterLine(currentIdx + 1) + drawLine(point1, point2, currentIdx + 1, arrow1Ref.current) + } else { + if (Big(nextLine.x1).minus(currentLineMaxX).abs().lte(Big(nextLine.x2).minus(currentLineMaxX).abs())) { + nextLine.set({ x1: currentLine.x2 }) + } else { + nextLine.set({ x2: currentLine.x2 }) + } - currentLine.set({ x1: currentLine.x1 + length, x2: currentLine.x2 + length }) - - break + if (Big(nextLine.x1).minus(Big(nextLine.x2)).eq(0)) { + reArrangeOuterLine(currentIdx + 1, true) + canvas.remove(nextLine) + } + } } } + + const newOuterLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine') + newOuterLines.sort((a, b) => a.idx - b.idx) + newOuterLines.forEach((line, idx) => { + line.fire('modified') + }) + canvas.renderAll() } diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 06f1428a..19d43c5e 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -33,7 +33,7 @@ import { import { QLine } from '@/components/fabric/QLine' import { fabric } from 'fabric' import { QPolygon } from '@/components/fabric/QPolygon' -import offsetPolygon from '@/util/qpolygon-utils' +import offsetPolygon, { calculateAngle } from '@/util/qpolygon-utils' import { isObjectNotEmpty } from '@/util/common-utils' import * as turf from '@turf/turf' import { INPUT_TYPE, LINE_TYPE, Mode, POLYGON_TYPE } from '@/common/common' @@ -1771,6 +1771,16 @@ export function useMode() { wall.lines = afterLine.concat(beforeLine) //외벽선을 기준으로 polygon을 생성한다. 지붕선의 기준이 됨. + const divWallLines = [] + wall.lines.forEach((currentWall, index) => { + const nextWall = wall.lines[(index + 1) % wall.lines.length] + const currentAngle = calculateAngle(currentWall.startPoint, currentWall.endPoint) + const nextAngle = calculateAngle(nextWall.startPoint, nextWall.endPoint) + if (currentAngle === nextAngle) { + divWallLines.push({ currentWall: currentWall, nextWall: nextWall, index: index }) + } + }) + const polygon = createRoofPolygon(wall.points) const originPolygon = new QPolygon(wall.points, { fontSize: 0 }) originPolygon.setViewLengthText(false) @@ -1787,6 +1797,45 @@ export function useMode() { offsetPolygon = createPaddingPolygon(polygon, wall.lines).vertices } + if (divWallLines.length > 0) { + /** + * 외벽선을 분기한 횟수를 저장한다. 외벽선은 offset이 같지 않을때 분기한다. + */ + let addPoint = 0 + + divWallLines.forEach((line) => { + const currentWall = line.currentWall + const nextWall = line.nextWall + const index = line.index + addPoint + const xDiff = Big(currentWall.x1).minus(Big(nextWall.x1)) + const yDiff = Big(currentWall.y1).minus(Big(nextWall.y1)) + const offsetCurrentPoint = offsetPolygon[index] + let offsetNextPoint = offsetPolygon[(index + 1) % offsetPolygon.length] + line.index = index + + if (currentWall.attributes.offset !== nextWall.attributes.offset) { + const offsetPoint1 = { + x: xDiff.eq(0) ? offsetCurrentPoint.x : nextWall.x1, + y: yDiff.eq(0) ? offsetCurrentPoint.y : nextWall.y1, + } + const diffOffset = Big(nextWall.attributes.offset).minus(Big(currentWall.attributes.offset)) + const offsetPoint2 = { + x: yDiff.eq(0) ? offsetPoint1.x : Big(offsetPoint1.x).plus(diffOffset).toNumber(), + y: xDiff.eq(0) ? offsetPoint1.y : Big(offsetPoint1.y).plus(diffOffset).toNumber(), + } + const offsetPoint3 = { + x: yDiff.eq(0) ? offsetNextPoint.x : Big(offsetNextPoint.x).plus(diffOffset).toNumber(), + y: xDiff.eq(0) ? offsetNextPoint.y : Big(offsetNextPoint.y).plus(diffOffset).toNumber(), + } + offsetPolygon.splice(index + 1, 0, offsetPoint1, offsetPoint2) + offsetNextPoint = offsetPoint3 + addPoint++ + } else { + addPoint-- + } + }) + } + const roof = makePolygon( offsetPolygon.map((point) => { return { x1: point.x, y1: point.y } @@ -1806,6 +1855,8 @@ export function useMode() { roof.name = POLYGON_TYPE.ROOF roof.setWall(wall) + let roofWallIndex = 0 + roof.lines.forEach((line, index) => { const x1 = Big(line.x1) const x2 = Big(line.x2) @@ -1816,18 +1867,21 @@ export function useMode() { roofId: roof.id, planeSize: lineLength, actualSize: lineLength, - wallLine: wall.lines[index].id, - type: wall.lines[index].attributes.type, - offset: wall.lines[index].attributes.offset, - width: wall.lines[index].attributes.width, - pitch: wall.lines[index].attributes.pitch, - sleeve: wall.lines[index].attributes.sleeve || false, + wallLine: wall.lines[roofWallIndex].id, + type: wall.lines[roofWallIndex].attributes.type, + offset: wall.lines[roofWallIndex].attributes.offset, + width: wall.lines[roofWallIndex].attributes.width, + pitch: wall.lines[roofWallIndex].attributes.pitch, + sleeve: wall.lines[roofWallIndex].attributes.sleeve || false, + } + + const isDivLine = divWallLines.some((divLine) => divLine.index === index) + if (!isDivLine) { + roofWallIndex++ } }) wall.set({ - // originX: 'center', - // originY: 'center', attributes: { roofId: roof.id, }, @@ -1846,7 +1900,7 @@ export function useMode() { const y2 = Big(line.y2) const lineLength = x1.minus(x2).abs().pow(2).plus(y1.minus(y2).abs().pow(2)).sqrt().times(10).round().toNumber() line.attributes.roofId = roof.id - line.attributes.currentRoofId = roof.lines[index].id + // line.attributes.currentRoofId = roof.lines[index].id line.attributes.planeSize = lineLength line.attributes.actualSize = lineLength diff --git a/src/hooks/usePolygon.js b/src/hooks/usePolygon.js index 99845d46..50470060 100644 --- a/src/hooks/usePolygon.js +++ b/src/hooks/usePolygon.js @@ -1,7 +1,7 @@ -import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, fontFamilyState, fontSizeState, pitchTextSelector } from '@/store/canvasAtom' +import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, pitchTextSelector } from '@/store/canvasAtom' import { useRecoilValue } from 'recoil' import { fabric } from 'fabric' -import { findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, getDirectionByPoint, isPointOnLine } from '@/util/canvas-util' +import { findAndRemoveClosestPoint, getDegreeByChon, getDegreeInOrientation, isPointOnLine } from '@/util/canvas-util' import { QPolygon } from '@/components/fabric/QPolygon' import { isSamePoint, removeDuplicatePolygons } from '@/util/qpolygon-utils' import { flowDisplaySelector } from '@/store/settingAtom' diff --git a/src/util/qpolygon-utils.js b/src/util/qpolygon-utils.js index 0444c93d..74e4654f 100644 --- a/src/util/qpolygon-utils.js +++ b/src/util/qpolygon-utils.js @@ -23,11 +23,11 @@ export const defineQPloygon = () => { * @returns {number} */ export const calculateAngle = (point1, point2) => { - const deltaX = Big(point2?.x !== undefined ? point2.x : 0) - .minus(point1?.x !== undefined ? point1.x : 0) + const deltaX = Big(point2.x ?? 0) + .minus(point1.x ?? 0) .toNumber() - const deltaY = Big(point2?.y !== undefined ? point2.y : 0) - .minus(point1?.y !== undefined ? point1.y : 0) + const deltaY = Big(point2.y ?? 0) + .minus(point1.y ?? 0) .toNumber() const angleInRadians = Math.atan2(deltaY, deltaX) return angleInRadians * (180 / Math.PI) @@ -3525,7 +3525,14 @@ export const calcLinePlaneSize = (points) => { * @returns number */ export const calcLineActualSize = (points, degree) => { + const { x1, y1, x2, y2 } = points const planeSize = calcLinePlaneSize(points) - const height = Big(Math.tan(Big(degree).times(Math.PI / 180))).times(planeSize) + let height = Big(Math.tan(Big(degree).times(Math.PI / 180))).times(planeSize) + /** + * 대각선일 경우 높이 계산 변경 + */ + if (x1 !== x2 && y1 !== y2) { + height = Big(Math.tan(Big(degree).times(Math.PI / 180))).times(Big(x1).minus(x2).times(10).round()) + } return Big(planeSize).pow(2).plus(height.pow(2)).sqrt().abs().round().toNumber() }