diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 4c3e9718..24541d22 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -9,12 +9,6 @@ export const useTrestle = () => { const moduleSelectionData = useRecoilValue(moduleSelectionDataState) //다음으로 넘어가는 최종 데이터 const apply = () => { - // rack은 맵 형태의 객체인데 key value 형태로 되어있다. - // 이때 이 형태를 [{key, value}, ...] 형태로 바꿔야 함. - /*const rackInfos = Object.keys(rack).map((key) => { - return { key, value: rack[key] } - })*/ - //처마력바가 체크되어 있는 경우 exposedBottomPoints를 이용해 처마력바 그려줘야함. // exposedBottomPoints는 노출 최하면 들의 centerPoint 배열. @@ -32,9 +26,11 @@ export const useTrestle = () => { const construction = moduleSelectionData.roofConstructions.find((construction) => construction.roofIndex === roofMaterialIndex).construction let isEaveBar = construction.setupCover let isSnowGuard = construction.setupSnowCover + const direction = parent.direction const rack = surface.trestleDetail.rack - const { rackQty, rackIntvlPct } = surface.trestleDetail + let { rackQty, rackIntvlPct } = surface.trestleDetail + const rackInfos = Object.keys(rack).map((key) => { return { key, value: rack[key] } }) @@ -73,7 +69,7 @@ export const useTrestle = () => { // 처마력바설치 true인 경우 설치 exposedBottomModules.forEach((module) => { //TODO : 방향별로 처마력바 설치해야함 - const bottomPoints = findTopTwoPoints([...module.points]) + const bottomPoints = findTopTwoPoints([...module.points], direction) if (!bottomPoints) return const eaveBar = new fabric.Line([bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y], { name: 'eaveBar', @@ -85,14 +81,12 @@ export const useTrestle = () => { canvas.renderAll() }) } - // 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산 // 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈 exposedBottomModules.forEach((module) => { const { width, height } = module let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } - const direction = 'south' //TODO : 방향별로 가대 설치해야함 let leftRows = 1 @@ -105,9 +99,7 @@ export const useTrestle = () => { //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2 - }) + let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -117,16 +109,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findLeft) { - const topLeftPoint = { x: x - width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2 - }) + nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) findLeft = false } else { - const topRightPoint = { x: x + width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2 - }) + nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) findLeft = true } @@ -148,9 +134,7 @@ export const useTrestle = () => { // 오른쪽 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2 - }) + let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -160,16 +144,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findRight) { - const topRightPoint = { x: x + width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2 - }) + nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) findRight = false } else { - const topLeftPoint = { x: x - width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2 - }) + nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) findRight = true } @@ -191,9 +169,7 @@ export const useTrestle = () => { // 센터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2 - }) + let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -233,7 +209,6 @@ export const useTrestle = () => { const { width, height } = module let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } - const direction = 'south' //TODO : 방향별로 가대 설치해야함 let leftRows = 1 @@ -243,9 +218,7 @@ export const useTrestle = () => { //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2 - }) + let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -255,16 +228,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findLeft) { - const topLeftPoint = { x: x - width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2 - }) + nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) findLeft = false } else { - const topRightPoint = { x: x + width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2 - }) + nextModule = nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) findLeft = true } @@ -291,7 +258,6 @@ export const useTrestle = () => { const { width, height } = module let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } - const direction = 'south' //TODO : 방향별로 가대 설치해야함 let rightRows = 1 @@ -301,9 +267,7 @@ export const useTrestle = () => { // 오른쪽 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2 - }) + let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -313,16 +277,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findRight) { - const topRightPoint = { x: x + width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2 - }) + nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) findRight = false } else { - const topLeftPoint = { x: x - width / 2, y: y - height } - nextModule = centerPoints.find((centerPoint) => { - return Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2 - }) + nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) findRight = true } @@ -361,7 +319,92 @@ export const useTrestle = () => { installBracket() } - const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction = 'south', l) => { + const findNextModule = (currentPoint, centerPoints, direction) => { + let { x, y, width, height } = currentPoint + width = Math.floor(width) + height = Math.floor(height) + + let result + switch (direction) { + case 'south': { + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + break + } + case 'north': { + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + break + } + case 'east': { + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + break + } + case 'west': { + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + break + } + } + + return result + } + + const findNextLeftModule = (currentPoint, centerPoints, direction) => { + const { x, y, width, height } = currentPoint + let result + let topLeftPoint + + switch (direction) { + case 'south': { + topLeftPoint = { x: x - width / 2, y: y - height } + break + } + case 'north': { + topLeftPoint = { x: x + width / 2, y: y + height } + break + } + case 'east': { + topLeftPoint = { x: x - width, y: y + height / 2 } + break + } + case 'west': { + topLeftPoint = { x: x + width, y: y - height / 2 } + break + } + } + + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2) + + return result + } + const findNextRightModule = (currentPoint, centerPoints, direction) => { + const { x, y, width, height } = currentPoint + let result + let topRightPoint + + switch (direction) { + case 'south': { + topRightPoint = { x: x + width / 2, y: y - height } + break + } + case 'north': { + topRightPoint = { x: x - width / 2, y: y + height } + break + } + case 'east': { + topRightPoint = { x: x - width, y: y - height / 2 } + break + } + case 'west': { + topRightPoint = { x: x + width, y: y + height / 2 } + break + } + } + + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2) + + return result + } + + const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l) => { const { width, height } = module let startPointX, startPointY @@ -370,10 +413,20 @@ export const useTrestle = () => { case 'L': { // 왼쪽부분 시작 점 if (direction === 'south') { - const x = module.left - const y = module.top + module.height / 2 - startPointX = x + width / rackIntvlPct - startPointY = y + height / 2 + startPointX = module.left + width / rackIntvlPct + startPointY = module.top + module.height + break + } else if (direction === 'east') { + startPointX = module.left + width + startPointY = module.top + height - height / rackIntvlPct + break + } else if (direction === 'west') { + startPointX = module.left + startPointY = module.top + height / rackIntvlPct + break + } else if (direction === 'north') { + startPointX = module.left + width - width / rackIntvlPct + startPointY = module.top break } } @@ -381,19 +434,49 @@ export const useTrestle = () => { case 'R': { // 오른쪽부분 시작 점 if (direction === 'south') { - const x = module.left + module.width - const y = module.top + module.height / 2 - startPointX = x - width / rackIntvlPct - startPointY = y + height / 2 + startPointX = module.left + module.width - width / rackIntvlPct + startPointY = module.top + module.height / 2 + height / 2 + break + } else if (direction === 'east') { + startPointX = module.left + width + startPointY = module.top + height / rackIntvlPct + break + } else if (direction === 'west') { + startPointX = module.left + startPointY = module.top + height - height / rackIntvlPct + break + } else if (direction === 'north') { + startPointX = module.left + width / rackIntvlPct + startPointY = module.top break } } case 'C': { // 중간부분 시작점 if (direction === 'south') { + const x = module.left + module.width / 2 + const y = module.top + module.height / 2 startPointX = x startPointY = y + height / 2 break + } else if (direction === 'east') { + const x = module.left + width + const y = module.top + module.height / 2 + startPointX = x + startPointY = y + break + } else if (direction === 'west') { + const x = module.left + const y = module.top + module.height / 2 + startPointX = x + startPointY = y + break + } else if (direction === 'north') { + const x = module.left + module.width / 2 + const y = module.top + startPointX = x + startPointY = y + break } } } @@ -410,6 +493,13 @@ export const useTrestle = () => { stroke: 'red', strokeWidth: 4, selectable: false, + fill: 'red', + shadow: { + color: 'black', // Outline color + blur: 10, + offsetX: 0, + offsetY: 0, + }, supFitQty, supFitIntvlPct, rackLen, @@ -425,6 +515,100 @@ export const useTrestle = () => { break } + case 'east': { + rackInfos.forEach((rackInfo) => { + const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo + + const rackLength = rackLen / 10 + + const rack = new fabric.Line([startPointX, startPointY, startPointX - rackLength, startPointY], { + name: 'rack', + stroke: 'red', + shadow: { + color: 'black', // Outline color + blur: 10, + offsetX: 0, + offsetY: 0, + }, + strokeWidth: 4, + selectable: false, + supFitQty, + supFitIntvlPct, + rackLen, + rackId: itemId, + direction: 'left', + }) + + canvas.add(rack) + canvas.renderAll() + + startPointX -= rackLength + 3 + }) + break + } + + case 'west': { + rackInfos.forEach((rackInfo) => { + const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo + + const rackLength = rackLen / 10 + + const rack = new fabric.Line([startPointX, startPointY, startPointX + rackLength, startPointY], { + name: 'rack', + stroke: 'red', + shadow: { + color: 'black', // Outline color + blur: 10, + offsetX: 0, + offsetY: 0, + }, + strokeWidth: 4, + selectable: false, + supFitQty, + supFitIntvlPct, + rackLen, + rackId: itemId, + direction: 'right', + }) + + canvas.add(rack) + canvas.renderAll() + + startPointX += rackLength + 3 + }) + break + } + case 'north': { + rackInfos.forEach((rackInfo) => { + const { rackLen, itemId, supFitQty, supFitIntvlPct } = rackInfo + + const rackLength = rackLen / 10 + + const rack = new fabric.Line([startPointX, startPointY, startPointX, startPointY + rackLength], { + name: 'rack', + stroke: 'red', + shadow: { + color: 'black', // Outline color + blur: 10, + offsetX: 0, + offsetY: 0, + }, + strokeWidth: 4, + selectable: false, + supFitQty, + supFitIntvlPct, + rackLen, + rackId: itemId, + direction: 'bottom', + }) + + canvas.add(rack) + canvas.renderAll() + + startPointY += rackLength + 3 + }) + break + } } } @@ -460,6 +644,57 @@ export const useTrestle = () => { canvas.add(bracket) }) canvas.renderAll() + } else if (direction === 'left') { + const result = getBracketPoints(supFitQty, supFitIntvlPct) + + result.forEach((percent) => { + const bracket = new fabric.Rect({ + left: x2 + (rackLen / 10) * percent, + top: y2 - moduleLength / 3, + fill: 'green', + name: 'bracket', + width: moduleLength, + height: moduleLength, + selectable: false, + }) + + canvas.add(bracket) + }) + canvas.renderAll() + } else if (direction === 'right') { + const result = getBracketPoints(supFitQty, supFitIntvlPct) + + result.forEach((percent) => { + const bracket = new fabric.Rect({ + left: x2 - (rackLen / 10) * percent, + top: y2 - moduleLength / 3, + fill: 'green', + name: 'bracket', + width: moduleLength, + height: moduleLength, + selectable: false, + }) + + canvas.add(bracket) + }) + canvas.renderAll() + } else if (direction === 'bottom') { + const result = getBracketPoints(supFitQty, supFitIntvlPct) + + result.forEach((percent) => { + const bracket = new fabric.Rect({ + left: x2 - moduleLength / 3, + top: y2 - (rackLen / 10) * percent, + fill: 'green', + name: 'bracket', + width: moduleLength, + height: moduleLength, + selectable: false, + }) + + canvas.add(bracket) + }) + canvas.renderAll() } }) } @@ -488,8 +723,21 @@ export const useTrestle = () => { return points } - function findTopTwoPoints(points) { - points.sort((a, b) => b.y - a.y) + function findTopTwoPoints(points, direction) { + switch (direction) { + case 'south': + points.sort((a, b) => b.y - a.y) + break + case 'north': + points.sort((a, b) => a.y - b.y) + break + case 'east': + points.sort((a, b) => b.x - a.x) + break + case 'west': + points.sort((a, b) => a.x - b.x) + break + } return points.slice(0, 2) } @@ -549,12 +797,12 @@ export const useTrestle = () => { bottomRightPoint = { x: x - width / 2, y: y - height } break case 'east': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) bottomLeftPoint = { x: x + width, y: y + height / 2 } bottomRightPoint = { x: x + width, y: y - height / 2 } break case 'west': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) bottomLeftPoint = { x: x - width, y: y - height / 2 } bottomRightPoint = { x: x - width, y: y + height / 2 } break