diff --git a/src/components/Roof2.jsx b/src/components/Roof2.jsx index 76a64e93..2994d85c 100644 --- a/src/components/Roof2.jsx +++ b/src/components/Roof2.jsx @@ -108,7 +108,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]) /** @@ -119,7 +120,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() @@ -442,10 +446,17 @@ export default function Roof2() { + diff --git a/src/components/fabric/QPolygon.js b/src/components/fabric/QPolygon.js index a9c7e751..e89736cf 100644 --- a/src/components/fabric/QPolygon.js +++ b/src/components/fabric/QPolygon.js @@ -184,6 +184,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)) @@ -198,10 +199,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 }, @@ -219,7 +225,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 96fc3516..1c73d0a6 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 } } @@ -3479,27 +3485,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) // 원패턴일때랑 지그재그일때랑은 다르게 들어가야함 } // 패턴 생성 @@ -3510,8 +3527,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 = [] @@ -3520,6 +3542,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() @@ -3533,14 +3556,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 }) }) }