From e26c751e73fd893bf1b33b02cf76dd6348a5d5da Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 1 Aug 2024 11:27:15 +0900 Subject: [PATCH 01/10] chore: make client component for custom error page --- src/app/{500.js => error.jsx} | 2 ++ src/app/{404.js => not-found.jsx} | 2 ++ 2 files changed, 4 insertions(+) rename src/app/{500.js => error.jsx} (97%) rename src/app/{404.js => not-found.jsx} (98%) diff --git a/src/app/500.js b/src/app/error.jsx similarity index 97% rename from src/app/500.js rename to src/app/error.jsx index 654b605a..07d75e7e 100644 --- a/src/app/500.js +++ b/src/app/error.jsx @@ -1,3 +1,5 @@ +'use client' + export default function ServerError() { return (
diff --git a/src/app/404.js b/src/app/not-found.jsx similarity index 98% rename from src/app/404.js rename to src/app/not-found.jsx index 8aa5e9bc..8127943b 100644 --- a/src/app/404.js +++ b/src/app/not-found.jsx @@ -1,3 +1,5 @@ +'use client' + import Link from 'next/link' export default function NotFound() { From 495b95e9911fa2171e79cc7b74c4448a7a66b48a Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 1 Aug 2024 11:28:27 +0900 Subject: [PATCH 02/10] =?UTF-8?q?fix:=20canvas=20=EC=B2=B4=ED=81=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCanvas.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hooks/useCanvas.js b/src/hooks/useCanvas.js index dee2983b..5d63c758 100644 --- a/src/hooks/useCanvas.js +++ b/src/hooks/useCanvas.js @@ -42,18 +42,18 @@ export function useCanvas(id) { useEffect(() => { canvas ?.getObjects() - .filter((obj) => obj.type === 'textbox' || obj.type === 'text' || obj.type === 'i-text') + ?.filter((obj) => obj.type === 'textbox' || obj.type === 'text' || obj.type === 'i-text') .forEach((obj) => { obj.set({ fontSize: fontSize }) }) canvas ?.getObjects() - .filter((obj) => obj.type === 'QLine' || obj.type === 'QPolygon' || obj.type === 'QRect') + ?.filter((obj) => obj.type === 'QLine' || obj.type === 'QPolygon' || obj.type === 'QRect') .forEach((obj) => { obj.setFontSize(fontSize) }) - canvas?.renderAll() + canvas?.getObjects().length > 0 && canvas?.renderAll() }, [fontSize]) /** @@ -103,7 +103,7 @@ export function useCanvas(id) { } const initialize = () => { - canvas?.clear() + canvas.getObjects().length > 0 && canvas?.clear() // settings for all canvas in the app fabric.Object.prototype.transparentCorners = false fabric.Object.prototype.cornerColor = '#2BEBC8' From 1f89d3f9d848da53a56a474edb9a9435b21591af Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 1 Aug 2024 13:23:51 +0900 Subject: [PATCH 03/10] =?UTF-8?q?fix:=20canvas=20size=20=EC=A1=B0=EC=A0=88?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index e384901e..e2b40634 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -108,28 +108,24 @@ export default function Roof2() { } } - /** - * canvas 사이즈 변경 함수 - */ - const canvasSizeMode = () => { - if (canvas) { - canvas.setWidth(horizontalSize) - canvas.setHeight(verticalSize) - canvas.renderAll() - - setCanvasSize(() => ({ - vertical: verticalSize, - horizontal: horizontalSize, - })) - } - } + useEffect(() => { + setCanvasSize({ ...canvasSize, vertical: verticalSize, horizontal: horizontalSize }) + }, [verticalSize, horizontalSize]) /** * 값 변경시 */ + // useEffect(() => { + // canvasSizeMode() + // }, [verticalSize, horizontalSize]) useEffect(() => { - canvasSizeMode() - }, [verticalSize, horizontalSize]) + const { vertical, horizontal } = canvasSize + if (vertical !== verticalSize || horizontal !== horizontalSize) { + canvas.setWidth(horizontalSize) + canvas.setHeight(verticalSize) + canvas.renderAll() + } + }, [canvasSize, canvas]) const makeQPolygon = () => { const type1 = [ From 38258ba278181847649a53632f3ebf0476f4cfed Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 1 Aug 2024 13:49:34 +0900 Subject: [PATCH 04/10] =?UTF-8?q?fix:=20canvas=20size=20=EC=A1=B0=EC=A0=88?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index e2b40634..35e464ff 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -109,7 +109,8 @@ export default function Roof2() { } useEffect(() => { - setCanvasSize({ ...canvasSize, vertical: verticalSize, horizontal: horizontalSize }) + console.log('horizontalSize', horizontalSize) + setCanvasSize({ ...canvasSize, vertical: parseInt(verticalSize), horizontal: parseInt(horizontalSize) }) }, [verticalSize, horizontalSize]) /** @@ -120,7 +121,10 @@ export default function Roof2() { // }, [verticalSize, horizontalSize]) useEffect(() => { const { vertical, horizontal } = canvasSize + console.log('canvasSize', canvasSize) + console.log('horizontalSize', horizontalSize) if (vertical !== verticalSize || horizontal !== horizontalSize) { + console.log('setCanvasSize!!') canvas.setWidth(horizontalSize) canvas.setHeight(verticalSize) canvas.renderAll() From df1ef2457605af19919d48cbbbc431a8b35c32fa Mon Sep 17 00:00:00 2001 From: yjnoh Date: Thu, 1 Aug 2024 13:50:33 +0900 Subject: [PATCH 05/10] =?UTF-8?q?cell=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 9 ++- src/components/fabric/QPolygon.js | 17 +++- src/hooks/useMode.js | 124 ++++++++++++++++++++++++++---- 3 files changed, 130 insertions(+), 20 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index e2b40634..4d4bbf60 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -415,10 +415,17 @@ export default function Roof2() { + diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index c178714a..076825b5 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -181,6 +181,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { }, fillCell(cell = { width: 50, height: 100, padding: 10 }) { const points = this.points + const minX = Math.min(...points.map((p) => p.x)) const maxX = Math.max(...points.map((p) => p.x)) const minY = Math.min(...points.map((p) => p.y)) @@ -195,10 +196,15 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { const cols = Math.floor((boundingBoxWidth + cell.padding) / (rectWidth + cell.padding)) const rows = Math.floor((boundingBoxHeight + cell.padding) / (rectHeight + cell.padding)) + //전체 높이에서 패딩을 포함하고 rows를 곱해서 여백길이를 계산 후에 2로 나누면 반높이를 넣어서 중간으로 정렬 + const tmpHeight = (boundingBoxHeight - (rectHeight + cell.padding) * rows) / 2 + //센터 정렬시에 쓴다 체크박스가 존재함 TODO: if문 추가해서 정렬해야함 + let tmpWidth = (boundingBoxWidth - (rectWidth + cell.padding) * cols) / 2 + for (let i = 0; i < cols; i++) { for (let j = 0; j < rows; j++) { - const rectLeft = minX + i * (rectWidth + cell.padding) - const rectTop = minY + j * (rectHeight + cell.padding) + const rectLeft = minX + i * (rectWidth + cell.padding) + tmpWidth + const rectTop = minY + j * (rectHeight + cell.padding) + tmpHeight const rectPoints = [ { x: rectLeft, y: rectTop }, @@ -216,7 +222,12 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, { width: rectWidth, height: rectHeight, fill: '#BFFD9F', - selectable: false, + selectable: true, // 선택 가능하게 설정 + lockMovementX: true, // X 축 이동 잠금 + lockMovementY: true, // Y 축 이동 잠금 + lockRotation: true, // 회전 잠금 + lockScalingX: true, // X 축 크기 조정 잠금 + lockScalingY: true, // Y 축 크기 조정 잠금 opacity: 0.6, }) diff --git a/src/hooks/useMode.js b/src/hooks/useMode.js index 932ec2cd..c9aa96e7 100644 --- a/src/hooks/useMode.js +++ b/src/hooks/useMode.js @@ -27,7 +27,8 @@ export const Mode = { DRAW_RECT: 'drawRect', ROOF_PATTERN: 'roofPattern', MODULE: 'module', - ROOT_TRESTLE: 'rootTrestle', + ROOF_TRESTLE: 'roofTrestle', + FILL_CELLS: 'fillCells', DEFAULT: 'default', } @@ -55,6 +56,8 @@ export function useMode() { const [canvasSize] = useRecoilState(canvasSizeState) + const [selectedCellRoofArray, setSelectedCellRoofArray] = useState([]) + useEffect(() => { // 이벤트 리스너 추가 if (!canvas) { @@ -238,9 +241,12 @@ export function useMode() { case 'roofPattern': makeRoofPatternPolygon() break - case 'rootTrestle': + case 'roofTrestle': makeRoofTrestle() break + case 'fillCells': + makeRoofFillCells() + break } } @@ -3184,27 +3190,38 @@ export function useMode() { var ratio = window.devicePixelRatio || 1 + let inputPatternSize = { width: 30, height: 20 } //임시 사이즈 + let patternSize = { ...inputPatternSize } // 입력된 값을 뒤집기 위해 + + if (templateType === 2) { + //세로형이면 width height를 바꿈 + ;[patternSize.width, patternSize.height] = [inputPatternSize.height, patternSize.width] + } + // 패턴 소스를 위한 임시 캔버스 생성 const patternSourceCanvas = document.createElement('canvas') - patternSourceCanvas.width = 30 * ratio - patternSourceCanvas.height = 30 * ratio + patternSourceCanvas.width = patternSize.width * ratio + patternSourceCanvas.height = patternSize.height * ratio const ctx = patternSourceCanvas.getContext('2d') // 벽돌 패턴 그리기 ctx.scale(ratio, ratio) ctx.strokeStyle = 'green' - ctx.lineWidth = 0.2 + ctx.lineWidth = 0.4 // 첫 번째 행 벽돌 if (roofStyle === 2) { //지그재그 // // 두 번째 행 벽돌 - ctx.strokeRect(0, 0, 30, 15) - ctx.strokeRect(30, 15, 30, 15) - ctx.strokeRect(-15, 15, 30, 15) - ctx.strokeRect(0, 30, 30, 15) + if (templateType === 2) { + ctx.strokeRect(0, 0, patternSize.width / 2, patternSize.height) + ctx.strokeRect(patternSize.width / 2, patternSize.height / 2, patternSize.width / 2, patternSize.height) + } else if (templateType === 3) { + ctx.strokeRect(0, 0, patternSize.width, patternSize.height / 2) + ctx.strokeRect(patternSize.width / 2, patternSize.height / 2, patternSize.width, patternSize.height / 2) + } } else { - ctx.strokeRect(0, 0, 30, 30) // 원패턴일때랑 지그재그일때랑은 다르게 들어가야함 + ctx.strokeRect(0, 0, patternSize.width, patternSize.height) // 원패턴일때랑 지그재그일때랑은 다르게 들어가야함 } // 패턴 생성 @@ -3215,8 +3232,13 @@ export function useMode() { const commonOption = { fill: pattern, - selectable: true, + selectable: false, fontSize: 15, // fontSize는 필요에 따라 조정 + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingY: true, + lockScalingX: true, } let polygonArray = [] @@ -3225,6 +3247,7 @@ export function useMode() { const drawPolygon = new QPolygon(patternPolygon, commonOption) canvas.add(drawPolygon) drawPolygon.setViewLengthText(false) + drawPolygon.set('customIndex', index) polygonArray.push(drawPolygon) }) canvas.renderAll() @@ -3238,14 +3261,83 @@ export function useMode() { return } - // 오목한 부분 인덱스 찾기 - const polygons = roofPolygonArray - let concavePolygonObj = [] + const polygons = roofPolygonArray //리코일에 있는 패턴그린 폴리곤가져옴 + let selectedAreaArray = [] + + const defualtStrokeStyle = { + stroke: 'red', + strokeDashArray: [9, 5], + strokeWidth: 0.3, + } + + const selectedStrokeStyle = { + stroke: 'red', + strokeWidth: 3, + } + + function toggleSelection(polygon) { + if (polygon.strokeWidth === defualtStrokeStyle.strokeWidth) { + polygon.set({ + stroke: selectedStrokeStyle.stroke, + strokeWidth: selectedStrokeStyle.strokeWidth, + strokeDashArray: [0], + }) + canvas.discardActiveObject() // 객체의 활성 상태 해제 + selectedAreaArray.push(polygon) + } else { + polygon.set({ + stroke: defualtStrokeStyle.stroke, + strokeWidth: defualtStrokeStyle.strokeWidth, + strokeDashArray: defualtStrokeStyle.strokeDashArray, + }) + canvas.discardActiveObject() // 객체의 활성 상태 해제 + + const removeIndex = polygon.customIndex + const removeArrayIndex = selectedAreaArray.findIndex((x) => x.customIndex === removeIndex) + selectedAreaArray.splice(removeArrayIndex, 1) + } + canvas.renderAll() + } polygons.forEach((polygon, index) => { const trestlePolygon = handleOuterlinesTest(polygon, -12) - trestlePolygon.set('stroke', 'red').set('strokeDashArray', [9, 5]).set('strokeWidth', 0.3).setViewLengthText(false) - trestlePolygon.fillCell({ width: 100, height: 30, padding: 10 }) + trestlePolygon.setViewLengthText(false) //얘는 set으로 안먹는다... + trestlePolygon.set({ + stroke: 'red', + strokeDashArray: [9, 5], + strokeWidth: 0.3, + lockMovementX: true, + lockMovementY: true, + lockRotation: true, + lockScalingX: true, + lockScalingY: true, + bringToFront: true, + customIndex: polygon.customIndex, + }) + + trestlePolygon.on('mousedown', function () { + const customIndex = polygon.get('customIndex') + toggleSelection(trestlePolygon) + }) + }) + setSelectedCellRoofArray(selectedAreaArray) + } + + const makeRoofFillCells = () => { + const selectedCellRoofs = selectedCellRoofArray + if (selectedCellRoofs.length === 0) { + alert('선택된 영역이 없습니다.') + return + } + let inputCellSize = { width: 172, height: 113 } + let cellSize = { ...inputCellSize } //기본으로 가로형으로 넣고 + + if (templateType === 2) { + ;[cellSize.width, cellSize.height] = [cellSize.height, cellSize.width] + } + + selectedCellRoofs.forEach((polygon, index) => { + polygon.fillCell({ width: cellSize.width, height: cellSize.height, padding: 10 }) }) } From 4c96ad2b9951935b2febe0d660b52ce219915b49 Mon Sep 17 00:00:00 2001 From: yoosangwook Date: Thu, 1 Aug 2024 16:50:43 +0900 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20changeMode=20=EB=91=90=EB=B2=88=20?= =?UTF-8?q?=EC=8B=A4=ED=96=89=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Roof2.jsx | 39 ++++++++++----------------------------- src/hooks/useMode.js | 24 ++++++++++++++---------- 2 files changed, 24 insertions(+), 39 deletions(-) diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 4f15b095..19cc6ba8 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -35,6 +35,7 @@ export default function Roof2() { const { mode, + setMode, changeMode, handleClear, fillCellInPolygon, @@ -109,7 +110,6 @@ export default function Roof2() { } useEffect(() => { - console.log('horizontalSize', horizontalSize) setCanvasSize({ ...canvasSize, vertical: parseInt(verticalSize), horizontal: parseInt(horizontalSize) }) }, [verticalSize, horizontalSize]) @@ -121,10 +121,7 @@ export default function Roof2() { // }, [verticalSize, horizontalSize]) useEffect(() => { const { vertical, horizontal } = canvasSize - console.log('canvasSize', canvasSize) - console.log('horizontalSize', horizontalSize) if (vertical !== verticalSize || horizontal !== horizontalSize) { - console.log('setCanvasSize!!') canvas.setWidth(horizontalSize) canvas.setHeight(verticalSize) canvas.renderAll() @@ -391,23 +388,19 @@ export default function Roof2() { - - - - - - - - -