From 41e194d634953b5a15e6acfaf038e1ce2c4e8564 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 17 Jul 2024 16:52:18 +0900 Subject: [PATCH 1/4] feat: Add pattern A and pattern B modes to Roof2 component --- src/components/Roof2.jsx | 4 ++-- src/hooks/useMode.js | 10 +++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index d582e018..9587a7d2 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -282,14 +282,14 @@ export default function Roof2() { diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index bc6cc381..91380be4 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -6,8 +6,6 @@ import { rearrangeArray, findTopTwoIndexesByDistance, getDirection, - getOddEvenPoints, - findLongestDistancePair, getCenterPoint, } from '@/util/canvas-util' import { useRecoilState, useSetRecoilState } from 'recoil' @@ -23,6 +21,8 @@ export const Mode = { DRAW_LINE: 'drawLine', // 기준선 긋기모드 EDIT: 'edit', TEMPLATE: 'template', + PATTERNA: 'patterna', + PATTERNB: 'patternb', TEXTBOX: 'textbox', DRAW_RECT: 'drawRect', DEFAULT: 'default', @@ -55,6 +55,11 @@ export function useMode() { case 'template': templateMode() break + case 'patterna': + break + case 'patternb': + applyTemplateB() + break case 'textbox': textboxMode() break @@ -1095,6 +1100,5 @@ export function useMode() { zoom, togglePolygonLine, handleOuterlinesTest2, - applyTemplateB, } } From fdd52deec8d09269567fdbe582de0cbf657a7e53 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 17 Jul 2024 18:42:31 +0900 Subject: [PATCH 2/4] chore: Update .prettierrc printWidth to 150 --- .prettierrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.prettierrc b/.prettierrc index 198a1031..4b55b596 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,7 +4,7 @@ "useTabs": false, "tabWidth": 2, "trailingComma": "all", - "printWidth": 80, + "printWidth": 150, "arrowParens": "always", "endOfLine": "auto" } From edfa72bf48dc68c297d515e5343e0e00712f8ebb Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Wed, 17 Jul 2024 18:42:45 +0900 Subject: [PATCH 3/4] feat: Refactor Roof2 component to remove unused imports and optimize code --- src/app/roof2/page.jsx | 1 - src/components/Roof2.jsx | 93 ++------------ src/hooks/useMode.js | 271 ++++++++++++++++++++++----------------- 3 files changed, 166 insertions(+), 199 deletions(-) diff --git a/src/app/roof2/page.jsx b/src/app/roof2/page.jsx index 8c83730e..c33a5a99 100644 --- a/src/app/roof2/page.jsx +++ b/src/app/roof2/page.jsx @@ -1,6 +1,5 @@ 'use client' -import Hero from '@/components/Hero' import Roof2 from '@/components/Roof2' import { textState } from '@/store/canvasAtom' import { useEffect } from 'react' diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 9587a7d2..7836649f 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -7,21 +7,11 @@ import QPolygon from '@/components/fabric/QPolygon' import RangeSlider from './ui/RangeSlider' import { useRecoilState, useRecoilValue } from 'recoil' -import { - canvasSizeState, - fontSizeState, - sortedPolygonArray, -} from '@/store/canvasAtom' +import { canvasSizeState, fontSizeState, sortedPolygonArray } from '@/store/canvasAtom' import { QLine } from '@/components/fabric/QLine' export default function Roof2() { - const { - canvas, - handleRedo, - handleUndo, - setCanvasBackgroundWithDots, - saveImage, - } = useCanvas('canvas') + const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage } = useCanvas('canvas') //canvas 기본 사이즈 const [canvasSize, setCanvasSize] = useRecoilState(canvasSizeState) @@ -39,18 +29,8 @@ export default function Roof2() { const [showControl, setShowControl] = useState(false) - const { - mode, - changeMode, - handleClear, - fillCellInPolygon, - zoomIn, - zoomOut, - zoom, - togglePolygonLine, - handleOuterlinesTest2, - applyTemplateB, - } = useMode() + const { mode, changeMode, handleClear, fillCellInPolygon, zoomIn, zoomOut, zoom, togglePolygonLine, handleOuterlinesTest2, applyTemplateB } = + useMode() useEffect(() => { if (!canvas) { @@ -251,11 +231,7 @@ export default function Roof2() { {canvas && ( <>
- - - - - - -
-
+
- +
- +
diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 91380be4..e1666f8f 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -1,20 +1,9 @@ import { useEffect, useRef, useState } from 'react' import QRect from '@/components/fabric/QRect' import QPolygon from '@/components/fabric/QPolygon' -import { - getStartIndex, - rearrangeArray, - findTopTwoIndexesByDistance, - getDirection, - getCenterPoint, -} from '@/util/canvas-util' +import { getStartIndex, rearrangeArray, findTopTwoIndexesByDistance, getDirection, getCenterPoint } from '@/util/canvas-util' import { useRecoilState, useSetRecoilState } from 'recoil' -import { - fontSizeState, - roofState, - sortedPolygonArray, - wallState, -} from '@/store/canvasAtom' +import { fontSizeState, roofState, sortedPolygonArray, wallState } from '@/store/canvasAtom' import { QLine } from '@/components/fabric/QLine' export const Mode = { @@ -101,8 +90,7 @@ export function useMode() { if (isNaN(length) || length === 0) { //마지막 추가 된 points 제거합니다. - const lastPoint = - historyPoints.current[historyPoints.current.length - 1] + const lastPoint = historyPoints.current[historyPoints.current.length - 1] canvas?.remove(lastPoint) @@ -134,12 +122,7 @@ export function useMode() { } const line = new QLine( - [ - points.current[0].left, - points.current[0].top, - points.current[0].left + scaledVector.x, - points.current[0].top + scaledVector.y, - ], + [points.current[0].left, points.current[0].top, points.current[0].left + scaledVector.x, points.current[0].top + scaledVector.y], { stroke: 'black', strokeWidth: 2, @@ -180,27 +163,20 @@ export function useMode() { } const pushHistoryLine = (line) => { - if ( - historyLines.current.length > 0 && - historyLines.current[historyLines.current.length - 1].direction === - line.direction - ) { + if (historyLines.current.length > 0 && historyLines.current[historyLines.current.length - 1].direction === line.direction) { // 같은 방향의 선이 두 번 연속으로 그려지면 이전 선을 제거하고, 새로운 선과 merge한다. const lastLine = historyLines.current.pop() canvas?.remove(lastLine) - const mergedLine = new QLine( - [lastLine.x1, lastLine.y1, line.x2, line.y2], - { - stroke: 'black', - strokeWidth: 2, - selectable: false, - viewLengthText: true, - direction: lastLine.direction, - fontSize: fontSize, - }, - ) + const mergedLine = new QLine([lastLine.x1, lastLine.y1, line.x2, line.y2], { + stroke: 'black', + strokeWidth: 2, + selectable: false, + viewLengthText: true, + direction: lastLine.direction, + fontSize: fontSize, + }) historyLines.current.push(mergedLine) canvas?.add(mergedLine) } else { @@ -460,9 +436,7 @@ export function useMode() { const newOuterlines = [] for (let i = 0; i < historyLines.current.length; i++) { const next = historyLines.current[i + 1] - const prev = - historyLines.current[i - 1] ?? - historyLines.current[historyLines.current.length - 1] + const prev = historyLines.current[i - 1] ?? historyLines.current[historyLines.current.length - 1] if (next) { if (next.direction === 'right') { // 다름 라인이 오른쪽으로 이동 @@ -797,9 +771,7 @@ export function useMode() { } // 평균 법선 벡터를 단위 벡터로 정규화 - var lengthNormal = Math.sqrt( - averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y, - ) + var lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y) var unitNormal = { x: averageNormal.x / lengthNormal, y: averageNormal.y / lengthNormal, @@ -867,9 +839,7 @@ export function useMode() { } // 평균 법선 벡터를 단위 벡터로 정규화 - const lengthNormal = Math.sqrt( - averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y, - ) + const lengthNormal = Math.sqrt(averageNormal.x * averageNormal.x + averageNormal.y * averageNormal.y) const unitNormal = { x: averageNormal.x / lengthNormal, y: averageNormal.y / lengthNormal, @@ -933,64 +903,144 @@ export function useMode() { const applyTemplateB = () => { changeMode(canvas, Mode.EDIT) const polygon = drawWallPolygon() - handleOuterLineTemplateB(polygon) + console.log('polygon', polygon) + const params = { + eaves: 50, + edge: 20, + polygon, + } + handleInnerLineColor(polygon) + handleOuterLineTemplateB(params) } - const handleOuterLineTemplateB = (polygon) => { + const handleInnerLineColor = (polygon) => { + polygon.lines.forEach((line, index) => { + if (index % 2 === 0) { + line.set('stroke', 'rgb(0, 220, 221)') + } else { + line.set('stroke', 'rgb(0, 224, 61)') + } + + const overLine = new QLine([line.x1, line.y1, line.x2, line.y2], { + stroke: line.stroke, + strokeWidth: 2, + selectable: false, + fontSize: fontSize, + }) + canvas.add(overLine) + }) + canvas.renderAll() + } + + const handleOuterLineTemplateB = (params) => { + const { eaves, edge, polygon } = params polygon.points.forEach((point, index) => { - let x2 = - index === polygon.points.length - 1 - ? polygon.points[0].x - : polygon.points[index + 1].x - let y2 = - index === polygon.points.length - 1 - ? polygon.points[0].y - : polygon.points[index + 1].y + let x2 = index === polygon.points.length - 1 ? polygon.points[0].x : polygon.points[index + 1].x + let y2 = index === polygon.points.length - 1 ? polygon.points[0].y : polygon.points[index + 1].y let x1 = point.x let y1 = point.y if (index % 2 === 0) { if (polygon.lines[index].direction === 'bottom') { - y1 = y1 - 50 - y2 = y2 + 50 - x1 = x1 - 20 - x2 = x2 - 20 + y1 = y1 - eaves + y2 = y2 + eaves + x1 = x1 - edge + x2 = x2 - edge } else { - y1 = y1 + 50 - y2 = y2 - 50 - x1 = x1 + 20 - x2 = x2 + 20 + y1 = y1 + eaves + y2 = y2 - eaves + x1 = x1 + edge + x2 = x2 + edge } } else { if (polygon.lines[index].direction === 'right') { - x1 = x1 - 20 - x2 = x2 + 20 - y1 = y1 + 50 - y2 = y2 + 50 + x1 = x1 - edge + x2 = x2 + edge + y1 = y1 + eaves + y2 = y2 + eaves } else { - x1 = x1 + 20 - x2 = x2 - 20 - y1 = y1 - 50 - y2 = y2 - 50 + x1 = x1 + edge + x2 = x2 - edge + y1 = y1 - eaves + y2 = y2 - eaves } } switch (polygon.shape) { case 1: - break - case 2: - const centerPoint = - polygon.points[3].y + - (polygon.points[2].y - polygon.points[3].y) / 2 if (index === 0) { const subLine = new QLine( [ - point.x - 20, - polygon.points[0].y + - (polygon.points[1].y - polygon.points[0].y) / 2, - polygon.points[5].x + 20, - polygon.points[0].y + - (polygon.points[1].y - polygon.points[0].y) / 2, + point.x - edge, + polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2, + polygon.points[2].x, + polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2, + ], + { + stroke: 'blue', + strokeWidth: 2, + selectable: false, + fontSize: fontSize, + }, + ) + canvas.add(subLine) + } + if (index === 1) { + x2 = x2 - edge + const subLine = new QLine([x2, y2, x2, polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2], { + stroke: 'blue', + strokeWidth: 2, + selectable: false, + fontSize: fontSize, + }) + canvas.add(subLine) + } + if (index === 2) { + y1 = point.y - (polygon.points[1].y - polygon.points[0].y) / 2 + const centeredPoint = getCenterPoint(polygon.points[1].x, point.x) + const subLine = new QLine( + [centeredPoint, point.y + eaves, centeredPoint, polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2], + { + stroke: 'black', + strokeWidth: 2, + strokeDashArray: [5, 5], + selectable: false, + fontSize: fontSize, + }, + ) + canvas.add(subLine) + } + if (index === 3) { + const centeredPoint = getCenterPoint(point.x, polygon.points[4].x) + const subLine = new QLine([centeredPoint, point.y + eaves, centeredPoint, polygon.points[5].y - eaves], { + stroke: 'black', + strokeWidth: 2, + strokeDashArray: [5, 5], + selectable: false, + fontSize: fontSize, + }) + canvas.add(subLine) + } + if (index === 5) { + const centeredPoint = getCenterPoint(point.y, polygon.points[4].y) + const subLine = new QLine([point.x + edge, centeredPoint, polygon.points[2].x - edge, centeredPoint], { + stroke: 'blue', + strokeWidth: 2, + selectable: false, + fontSize: fontSize, + }) + canvas.add(subLine) + } + break + case 2: + const centerPoint = polygon.points[3].y + (polygon.points[2].y - polygon.points[3].y) / 2 + if (index === 0) { + const subLine = new QLine( + [ + point.x - egde, + polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2, + polygon.points[5].x + egde, + polygon.points[0].y + (polygon.points[1].y - polygon.points[0].y) / 2, ], { stroke: 'blue', @@ -1002,7 +1052,7 @@ export function useMode() { canvas.add(subLine) } if (index === 3) { - x2 = x2 + 20 + x2 = x2 + egde const subLine = new QLine([x2, y2, x2, centerPoint], { stroke: 'blue', @@ -1013,26 +1063,20 @@ export function useMode() { canvas.add(subLine) } if (index === 4) { - y1 = - point.y + - (polygon.points[index - 2].y - polygon.points[index - 1].y) / 2 + y1 = point.y + (polygon.points[index - 2].y - polygon.points[index - 1].y) / 2 - const subLine = new QLine( - [point.x, centerPoint, polygon.points[2].x + 20, centerPoint], - { - stroke: 'blue', - strokeWidth: 2, - selectable: false, - fontSize: fontSize, - }, - ) - canvas.add(subLine) + const subLine = new QLine([point.x, centerPoint, polygon.points[2].x + 20, centerPoint], { + stroke: 'blue', + strokeWidth: 2, + selectable: false, + fontSize: fontSize, + }) const subVerticalLine = new QLine( [ - getCenterPoint(point.x, polygon.points[2].x + 20), - polygon.points[3].y - 50, - getCenterPoint(point.x, polygon.points[2].x + 20), + getCenterPoint(point.x, polygon.points[2].x + egde), + polygon.points[3].y - eaves, + getCenterPoint(point.x, polygon.points[2].x + egde), centerPoint, ], { @@ -1047,25 +1091,14 @@ export function useMode() { } if (index === 5) { - const centeredPoint = getCenterPoint( - polygon.points[0].x, - polygon.points[5].x, - ) - const verticalSubLine = new QLine( - [ - centeredPoint, - polygon.points[0].y - 50, - centeredPoint, - polygon.points[1].y + 50, - ], - { - stroke: 'black', - strokeWidth: 2, - strokeDashArray: [5, 5], - selectable: false, - fontSize: fontSize, - }, - ) + const centeredPoint = getCenterPoint(polygon.points[0].x, polygon.points[5].x) + const verticalSubLine = new QLine([centeredPoint, polygon.points[0].y - eaves, centeredPoint, polygon.points[1].y + eaves], { + stroke: 'black', + strokeWidth: 2, + strokeDashArray: [5, 5], + selectable: false, + fontSize: fontSize, + }) canvas.add(verticalSubLine) } From 7913c46c70c2b635d2fc2b8e119480527ee0e87d Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 18 Jul 2024 09:47:28 +0900 Subject: [PATCH 4/4] refactor: Update QLine constructor to include default option for isActiveLengthText --- src/components/fabric/QLine.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/fabric/QLine.js b/src/components/fabric/QLine.js index 9ccb1a5c..7c732617 100644 --- a/src/components/fabric/QLine.js +++ b/src/components/fabric/QLine.js @@ -14,7 +14,7 @@ export class QLine extends fabric.Group { parent #lengthTxt = 0 - constructor(points, option, lengthTxt) { + constructor(points, option = { isActiveLengthText: true }, lengthTxt) { const [x1, y1, x2, y2] = points if (!option.fontSize) { @@ -37,7 +37,7 @@ export class QLine extends fabric.Group { this.#lengthTxt = Number(lengthTxt) } - this.#init() + option.isActiveLengthText ?? this.#init() this.#addControl() }