diff --git a/src/hooks/common/useRoofFn.js b/src/hooks/common/useRoofFn.js index 84416370..dc877788 100644 --- a/src/hooks/common/useRoofFn.js +++ b/src/hooks/common/useRoofFn.js @@ -15,10 +15,19 @@ export function useRoofFn() { const currentObject = useRecoilValue(currentObjectState) //면형상 선택 클릭시 지붕 패턴 입히기 - function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial) { + function setSurfaceShapePattern(polygon, mode = 'onlyBorder', trestleMode = false, roofMaterial = selectedRoofMaterial, isForceChange = false) { if (!polygon) { return } + if (isForceChange) { + if (polygon.roofMaterial) { + polygon.roofMaterial = null + } + } + + if (polygon.roofMaterial) { + return + } const ratio = window.devicePixelRatio || 1 const layout = roofMaterial.layout diff --git a/src/hooks/module/useTrestle.js b/src/hooks/module/useTrestle.js index 24541d22..5c1d7927 100644 --- a/src/hooks/module/useTrestle.js +++ b/src/hooks/module/useTrestle.js @@ -19,17 +19,33 @@ export const useTrestle = () => { canvas.remove(obj) } }) - + canvas.getObjects().forEach((obj) => { + if (obj.name === 'bracket') { + canvas.remove(obj) + } + }) surfaces.forEach((surface) => { const parent = canvas.getObjects().find((obj) => obj.id === surface.parentId) const roofMaterialIndex = parent.roofMaterial.index - const construction = moduleSelectionData.roofConstructions.find((construction) => construction.roofIndex === roofMaterialIndex).construction + const construction = moduleSelectionData?.roofConstructions?.find((construction) => construction.roofIndex === roofMaterialIndex).construction + if (!construction) { + alert('앞에서 셋팅 안됨') + return + } let isEaveBar = construction.setupCover + let isSnowGuard = construction.setupSnowCover const direction = parent.direction - const rack = surface.trestleDetail.rack - let { rackQty, rackIntvlPct } = surface.trestleDetail + let { rackQty, rackIntvlPct, rackYn, cvrPlvrYn } = surface.trestleDetail + rackYn = 'N' + rackQty = 5 + cvrPlvrYn = 'Y' + + if (!rack) { + //25/01/16 기준 랙이 없는 경우는 그냥 안그려준다. + return + } const rackInfos = Object.keys(rack).map((key) => { return { key, value: rack[key] } @@ -41,12 +57,16 @@ export const useTrestle = () => { const exposedBottomModules = [] // 아래 두면이 모두 노출 되어있는 경우 const leftExposedHalfBottomModules = [] // 왼쪽 면만 노출되어있는 경우 const rightExposedHalfBottomPoints = [] // 오른쪽 면만 노출되어 있는 경우 + const leftExposedHalfTopModules = [] // 왼쪽 면만 노출되어 있는 경우 + const rightExposedHalfTopPoints = [] // 오른쪽 면만 노출되어 있는 경우 const modules = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.MODULE) modules.forEach((module) => { const { x, y } = module.getCenterPoint() const isExposedBottom = result.exposedBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2) const isLeftExposedHalfBottom = result.leftExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2) const isRightExposedHalfBottom = result.rightExposedHalfBottomPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2) + const isRightExposedHalfTop = result.rightExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2) + const isLeftExposedHalfTop = result.leftExposedHalfTopPoints.some((point) => Math.abs(point.x - x) < 2 && Math.abs(point.y - y) < 2) if (isExposedBottom) { exposedBottomModules.push(module) } @@ -56,11 +76,24 @@ export const useTrestle = () => { if (isRightExposedHalfBottom) { rightExposedHalfBottomPoints.push(module) } + if (isRightExposedHalfTop) { + leftExposedHalfTopModules.push(module) + } + if (isLeftExposedHalfTop) { + rightExposedHalfTopPoints.push(module) + } }) + // 4개중 한개라도 있는 경우 치조배치로 간주한다. + const isChidory = + leftExposedHalfBottomModules.length > 0 || + rightExposedHalfBottomPoints.length > 0 || + leftExposedHalfTopModules.length > 0 || + rightExposedHalfTopPoints.length > 0 + canvas .getObjects() - .filter((obj) => obj.name === 'eaveBar') + .filter((obj) => ['eaveBar', 'halfEaveBar'].includes(obj.name) && obj.parent === surface) .forEach((obj) => { canvas.remove(obj) }) @@ -72,19 +105,84 @@ export const useTrestle = () => { 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], { + parent: surface, name: 'eaveBar', stroke: 'blue', strokeWidth: 4, selectable: false, + parentId: module.id, }) canvas.add(eaveBar) canvas.renderAll() }) + + if (isChidory && cvrPlvrYn === 'Y') { + leftExposedHalfBottomModules.forEach((module) => { + const bottomPoints = findTopTwoPoints([...module.points], direction) + let barPoints = [] + //설치해야할 반처마커버 포인트를 방향에 따라 설정 + + if (direction === 'south') { + barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x - module.width / 2, bottomPoints[1].y] + } else if (direction === 'north') { + barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y] + } else if (direction === 'east') { + barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[0].y - module.height / 2] + } else if (direction === 'west') { + barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y - module.height / 2] + } + + if (!bottomPoints) return + const halfEaveBar = new fabric.Line(barPoints, { + parent: surface, + name: 'halfEaveBar', + stroke: 'blue', + strokeWidth: 4, + selectable: false, + parentId: module.id, + }) + canvas.add(halfEaveBar) + canvas.renderAll() + }) + + rightExposedHalfBottomPoints.forEach((module) => { + const bottomPoints = findTopTwoPoints([...module.points], direction) + let barPoints = [] + //설치해야할 반처마커버 포인트를 방향에 따라 설정 + + if (direction === 'south') { + barPoints = [bottomPoints[0].x + module.width / 2, bottomPoints[0].y, bottomPoints[1].x, bottomPoints[1].y] + } else if (direction === 'north') { + barPoints = [bottomPoints[0].x, bottomPoints[0].y, bottomPoints[0].x + module.width / 2, bottomPoints[1].y] + } else if (direction === 'east') { + barPoints = [bottomPoints[0].x, bottomPoints[1].y + module.height / 2, bottomPoints[1].x, bottomPoints[1].y] + } else if (direction === 'west') { + barPoints = [bottomPoints[0].x, bottomPoints[1].y - module.height / 2, bottomPoints[1].x, bottomPoints[1].y] + } + + if (!bottomPoints) return + const halfEaveBar = new fabric.Line(barPoints, { + parent: surface, + name: 'halfEaveBar', + stroke: 'blue', + strokeWidth: 4, + selectable: false, + parentId: module.id, + }) + canvas.add(halfEaveBar) + canvas.renderAll() + }) + } } + const horizontal = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlHor : surface.trestleDetail.moduleIntvlVer + + const vertical = ['south', 'north'].includes(direction) ? surface.trestleDetail.moduleIntvlVer : surface.trestleDetail.moduleIntvlHor // 가대 설치를 위한 가장 아래 모듈로부터 위로 몇단인지 계산 // 오른쪽,왼쪽 둘 다 아래에 아무것도 없는, 처마 커버를 필요로 하는 모듈 exposedBottomModules.forEach((module) => { - const { width, height } = module + let { width, height } = { ...module } + width = Math.floor(width) + height = Math.floor(height) let { x: startX, y: startY } = { ...module.getCenterPoint() } let { x, y } = { ...module.getCenterPoint() } //TODO : 방향별로 가대 설치해야함 @@ -99,7 +197,7 @@ export const useTrestle = () => { //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) + let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -109,10 +207,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findLeft) { - nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findLeft = false } else { - nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findLeft = true } @@ -134,7 +232,7 @@ export const useTrestle = () => { // 오른쪽 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) + let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -144,10 +242,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findRight) { - nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findRight = false } else { - nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findRight = true } @@ -169,7 +267,7 @@ export const useTrestle = () => { // 센터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) + let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -196,13 +294,19 @@ export const useTrestle = () => { return rack.value.moduleRows === centerRows })?.value.racks - drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L') - drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R') + if (rackYn === 'Y') { + drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn) + drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn) - if (rackQty === 3) { - //rack 갯수가 3개인 경우는 중간렉도 추가해줘야함 - drawRacks(centerRacks, rackQty, rackIntvlPct, module, direction, 'C') + if (rackQty === 3) { + //rack 갯수가 3개인 경우는 중간렉도 추가해줘야함 + drawRacks(centerRacks, rackQty, rackIntvlPct, module, direction, 'C', rackYn) + } else if (rackQty === 4) { + drawRacks(leftRacks, rackQty, rackIntvlPct / 3, module, direction, 'L', rackYn) + drawRacks(rightRacks, rackQty, rackIntvlPct / 3, module, direction, 'R', rackYn) + } } + module.set({ leftRows, rightRows, centerRows }) }) // 왼쪽아래에 모듈이 없는 모듈들 leftExposedHalfBottomModules.forEach((module) => { @@ -218,7 +322,7 @@ export const useTrestle = () => { //우선 절반을 나눈 뒤 왼쪽부터 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) + let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -228,10 +332,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findLeft) { - nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findLeft = false } else { - nextModule = nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) + nextModule = nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findLeft = true } @@ -251,7 +355,11 @@ export const useTrestle = () => { return rack.value.moduleRows === leftRows })?.value.racks - drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L') + if (rackYn === 'Y') { + drawRacks(leftRacks, rackQty, rackIntvlPct, module, direction, 'L', rackYn) + } + + module.set({ leftRows }) }) // 오른쪽 아래에 모듈이 없는 모듈들 rightExposedHalfBottomPoints.forEach((module) => { @@ -267,7 +375,7 @@ export const useTrestle = () => { // 오른쪽 찾는다. while (hasNextModule) { //바로 위에 있는지 확인한다. - let nextModule = findNextModule({ x, y, width, height }, centerPoints, direction) + let nextModule = findNextModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) if (nextModule) { // 바로 위 모듈을 찾는다. @@ -277,10 +385,10 @@ export const useTrestle = () => { } else { // 바로 위가 없을 경우 먼저 왼쪽위가 있는지 확인 한다. if (findRight) { - nextModule = findNextRightModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextRightModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findRight = false } else { - nextModule = findNextLeftModule({ x, y, width, height }, centerPoints, direction) + nextModule = findNextLeftModule({ x, y, width, height, horizontal, vertical }, centerPoints, direction) findRight = true } @@ -300,46 +408,46 @@ export const useTrestle = () => { return rack.value.moduleRows === rightRows })?.value.racks // 해당 rack으로 그려준다. + if (rackYn === 'Y') { + drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R', rackYn) + } - drawRacks(rightRacks, rackQty, rackIntvlPct, module, direction, 'R') + module.set({ rightRows }) }) + + if (rackYn === 'N') { + // rack이 없을경우 + installBracketWithOutRack(surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory) + } else if (rackYn === 'Y') { + installBracket(surface) + } }) - - /*switch (rackYn) { - case 'Y': { - // rack이 Y일 경우 rackQty가 필요함 - - break - } - case 'N': { - break - } - }*/ - // 지지금구 설치 - installBracket() } const findNextModule = (currentPoint, centerPoints, direction) => { - let { x, y, width, height } = currentPoint - width = Math.floor(width) - height = Math.floor(height) + let { x, y, width, height, horizontal, vertical } = { ...currentPoint } + width = width + horizontal + height = height + vertical + + let maxX = 2 + horizontal * 3 + let maxY = 2 + vertical * 3 let result switch (direction) { case 'south': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) break } case 'north': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) break } case 'east': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) break } case 'west': { - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) break } } @@ -348,16 +456,23 @@ export const useTrestle = () => { } const findNextLeftModule = (currentPoint, centerPoints, direction) => { - const { x, y, width, height } = currentPoint + let { x, y, width, height, horizontal, vertical } = { ...currentPoint } + let result let topLeftPoint + let maxX = 2 + horizontal * 3 + let maxY = 2 + vertical * 3 switch (direction) { case 'south': { + width = width + horizontal + height = height + vertical topLeftPoint = { x: x - width / 2, y: y - height } break } case 'north': { + width = width + horizontal + height = height + vertical topLeftPoint = { x: x + width / 2, y: y + height } break } @@ -371,15 +486,20 @@ export const useTrestle = () => { } } - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY) return result } const findNextRightModule = (currentPoint, centerPoints, direction) => { - const { x, y, width, height } = currentPoint + let { x, y, width, height, horizontal, vertical } = { ...currentPoint } + width = width + horizontal + height = height + vertical let result let topRightPoint + let maxX = 2 + horizontal * 3 + let maxY = 2 + vertical * 3 + switch (direction) { case 'south': { topRightPoint = { x: x + width / 2, y: y - height } @@ -399,13 +519,16 @@ export const useTrestle = () => { } } - result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2) + result = centerPoints.find((centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY) return result } - const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l) => { - const { width, height } = module + const drawRacks = (rackInfos, rackQty, rackIntvlPct, module, direction, l, rackYn) => { + const { width, height, left, top, lastX, lastY } = module + + const moduleLeft = lastX ?? left + const moduleTop = lastY ?? top let startPointX, startPointY @@ -500,6 +623,7 @@ export const useTrestle = () => { offsetX: 0, offsetY: 0, }, + parentId: module.id, supFitQty, supFitIntvlPct, rackLen, @@ -530,11 +654,13 @@ export const useTrestle = () => { offsetX: 0, offsetY: 0, }, + parentId: module.id, strokeWidth: 4, selectable: false, supFitQty, supFitIntvlPct, rackLen, + rackYn, rackId: itemId, direction: 'left', }) @@ -562,6 +688,7 @@ export const useTrestle = () => { offsetX: 0, offsetY: 0, }, + parentId: module.id, strokeWidth: 4, selectable: false, supFitQty, @@ -593,6 +720,7 @@ export const useTrestle = () => { offsetX: 0, offsetY: 0, }, + parentId: module.id, strokeWidth: 4, selectable: false, supFitQty, @@ -612,32 +740,40 @@ export const useTrestle = () => { } } - const installBracket = () => { - const racks = canvas.getObjects().filter((obj) => obj.name === 'rack') - // name이 bracket인 객체를 찾아서 삭제 - canvas.getObjects().forEach((obj) => { - if (obj.name === 'bracket') { - canvas.remove(obj) - } + const installBracket = (surface) => { + const modules = surface.modules + const racks = [] + modules.forEach((module) => { + canvas + .getObjects() + .filter((obj) => obj.name === 'rack') + .forEach((rack) => { + if (rack.parentId === module.id) { + canvas.remove(canvas.getObjects().filter((obj) => obj.name === 'bracket' && obj.parentId === rack.id)) + racks.push(rack) + } + }) }) + canvas.renderAll() racks.forEach((rack) => { const { x1, y1, x2, y2, direction, supFitQty, supFitIntvlPct, rackLen } = rack - const moduleLength = 10 + const bracketLength = 10 if (direction === 'top') { const result = getBracketPoints(supFitQty, supFitIntvlPct) result.forEach((percent) => { const bracket = new fabric.Rect({ - left: x2 - moduleLength / 3, + left: x2 - bracketLength / 3, top: y2 + (rackLen / 10) * percent, fill: 'green', name: 'bracket', - width: moduleLength, - height: moduleLength, + parentId: rack.parentId, + width: bracketLength, + height: bracketLength, selectable: false, }) @@ -650,11 +786,12 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ left: x2 + (rackLen / 10) * percent, - top: y2 - moduleLength / 3, + top: y2 - bracketLength / 3, fill: 'green', name: 'bracket', - width: moduleLength, - height: moduleLength, + parentId: rack.parentId, + width: bracketLength, + height: bracketLength, selectable: false, }) @@ -667,11 +804,12 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ left: x2 - (rackLen / 10) * percent, - top: y2 - moduleLength / 3, + top: y2 - bracketLength / 3, fill: 'green', + parentId: rack.parentId, name: 'bracket', - width: moduleLength, - height: moduleLength, + width: bracketLength, + height: bracketLength, selectable: false, }) @@ -683,12 +821,13 @@ export const useTrestle = () => { result.forEach((percent) => { const bracket = new fabric.Rect({ - left: x2 - moduleLength / 3, + left: x2 - bracketLength / 3, top: y2 - (rackLen / 10) * percent, fill: 'green', name: 'bracket', - width: moduleLength, - height: moduleLength, + parentId: rack.parentId, + width: bracketLength, + height: bracketLength, selectable: false, }) @@ -699,6 +838,153 @@ export const useTrestle = () => { }) } + //랙 없음 인 경우 지지금구 설치 + const installBracketWithOutRack = (surface, exposedBottomModules, leftExposedHalfBottomModules, rightExposedHalfBottomPoints, isChidory) => { + let { rackQty, rackIntvlPct, moduleIntvlHor, moduleIntvlVer } = surface.trestleDetail + rackQty = 3 + + canvas.renderAll() + exposedBottomModules.forEach((module) => { + canvas.renderAll() + drawBracketWithOutRack(module, rackIntvlPct, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + drawBracketWithOutRack(module, rackIntvlPct, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) + if (!isChidory && rackQty === 3) { + // 치도리가 아니면서 갯수가 3개인 경우 센터도 설치 필요함 + drawBracketWithOutRack(module, rackIntvlPct, module.centerRows + 1, 'C', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + + if (isChidory && rackQty === 3) { + drawBracketWithOutRack(module, rackIntvlPct / 3, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + if (rackQty === 4) { + drawBracketWithOutRack(module, rackIntvlPct / 3, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + drawBracketWithOutRack(module, rackIntvlPct / 3, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + + if (rackQty === 5) { + drawBracketWithOutRack(module, rackIntvlPct / 3, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + drawBracketWithOutRack(module, rackIntvlPct / 3, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) + drawBracketWithOutRack(module, rackIntvlPct / 3, module.rightRows + 1, 'C', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + }) + + leftExposedHalfBottomModules.forEach((module) => { + drawBracketWithOutRack(module, rackIntvlPct, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + if (rackQty === 4) { + drawBracketWithOutRack(module, rackIntvlPct / 3, module.leftRows + 1, 'L', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + }) + + rightExposedHalfBottomPoints.forEach((module) => { + drawBracketWithOutRack(module, rackIntvlPct, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) + if (rackQty === 4) { + drawBracketWithOutRack(module, rackIntvlPct / 3, module.rightRows + 1, 'R', surface.direction, moduleIntvlHor, moduleIntvlVer) + } + }) + } + + const drawBracketWithOutRack = (module, rackIntvlPct, count, l, direction, moduleIntvlHor, moduleIntvlVer) => { + let { width, height, left, top } = module + let startPointX + let startPointY + + switch (l) { + case 'L': { + // 왼쪽부분 시작 점 + if (direction === 'south') { + startPointX = left + width / rackIntvlPct + startPointY = top + height + break + } else if (direction === 'east') { + startPointX = left + width + startPointY = top + height - height / rackIntvlPct + break + } else if (direction === 'west') { + startPointX = left + startPointY = top + height / rackIntvlPct + break + } else if (direction === 'north') { + startPointX = left + width - width / rackIntvlPct + startPointY = top + break + } + } + + case 'R': { + // 오른쪽부분 시작 점 + if (direction === 'south') { + startPointX = left + width - width / rackIntvlPct + startPointY = top + height / 2 + height / 2 + break + } else if (direction === 'east') { + startPointX = left + width + startPointY = top + height / rackIntvlPct + break + } else if (direction === 'west') { + startPointX = left + startPointY = top + height - height / rackIntvlPct + break + } else if (direction === 'north') { + startPointX = left + width / rackIntvlPct + startPointY = top + break + } + } + case 'C': { + // 중간부분 시작점 + if (direction === 'south') { + const x = left + width / 2 + const y = top + height / 2 + startPointX = x + startPointY = y + height / 2 + break + } else if (direction === 'east') { + const x = left + width + const y = top + height / 2 + startPointX = x + startPointY = y + break + } else if (direction === 'west') { + const x = left + const y = top + height / 2 + startPointX = x + startPointY = y + break + } else if (direction === 'north') { + const x = left + width / 2 + const y = top + startPointX = x + startPointY = y + break + } + } + } + + for (let i = 0; i < count; i++) { + const bracket = new fabric.Rect({ + left: startPointX - 5, + top: startPointY - 5, + fill: 'green', + name: 'bracket', + parentId: module.id, + width: 10, + height: 10, + selectable: false, + }) + canvas.add(bracket) + canvas.renderAll() + if (direction === 'south') { + startPointY -= height + moduleIntvlVer + } else if (direction === 'north') { + startPointY += height + moduleIntvlVer + } else if (direction === 'east') { + startPointX -= width + moduleIntvlHor + } else if (direction === 'west') { + startPointX += width + moduleIntvlHor + } + } + } + const getBracketPoints = (n, percent) => { if (n < 2) { throw new Error('Number of points must be at least 2') @@ -747,10 +1033,18 @@ export const useTrestle = () => { const direction = moduleSurface.direction const modules = moduleSurface.modules + const horizontal = ['south', 'north'].includes(direction) + ? moduleSurface.trestleDetail.moduleIntvlHor + : moduleSurface.trestleDetail.moduleIntvlVer + + const vertical = ['south', 'north'].includes(direction) ? moduleSurface.trestleDetail.moduleIntvlVer : moduleSurface.trestleDetail.moduleIntvlHor + + const maxX = 2 + horizontal * 3 + const maxY = 2 + vertical * 3 modules.forEach((module, index) => { module.tempIndex = index const { x, y } = module.getCenterPoint() - const { width, height } = module + const { width, height } = { ...module } centerPoints.push({ x, y, width: Math.floor(width), height: Math.floor(height), index }) }) @@ -775,9 +1069,11 @@ export const useTrestle = () => { // 반노출 bottom면의 points let leftExposedHalfBottomPoints = [] let rightExposedHalfBottomPoints = [] + let leftExposedHalfTopPoints = [] + let rightExposedHalfTopPoints = [] centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint + let { x, y, width, height } = { ...centerPoint } // centerPoints중에 현재 centerPoint와 x값이 같고, y값이 y-height값과 같은 centerPoint가 있는지 확인 let bottomCell let bottomLeftPoint @@ -787,22 +1083,28 @@ export const useTrestle = () => { switch (direction) { case 'south': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + width = width + horizontal + height = height + vertical + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) bottomLeftPoint = { x: x - width / 2, y: y + height } bottomRightPoint = { x: x + width / 2, y: y + height } break case 'north': - bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + width = width + horizontal + height = height + vertical + bottomCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) bottomLeftPoint = { x: x + width / 2, y: y - height } 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)) < maxX && Math.abs(centerPoint.y - y) < maxY) + width = width + horizontal 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)) < maxX && Math.abs(centerPoint.y - y) < maxY) + width = width + horizontal bottomLeftPoint = { x: x - width, y: y - height / 2 } bottomRightPoint = { x: x - width, y: y + height / 2 } break @@ -814,10 +1116,10 @@ export const useTrestle = () => { // 바로 아래에 셀이 없는 경우 물떼세 배치가 왼쪽 되어있는 셀을 찾는다. leftBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < 2 && Math.abs(centerPoint.y - bottomLeftPoint.y) < 2, + (centerPoint) => Math.abs(centerPoint.x - bottomLeftPoint.x) < maxX && Math.abs(centerPoint.y - bottomLeftPoint.y) < maxY, ).length rightBottomCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < 2 && Math.abs(centerPoint.y - bottomRightPoint.y) < 2, + (centerPoint) => Math.abs(centerPoint.x - bottomRightPoint.x) < maxX && Math.abs(centerPoint.y - bottomRightPoint.y) < maxY, ).length if (leftBottomCnt + rightBottomCnt === 1) { @@ -835,7 +1137,7 @@ export const useTrestle = () => { // 노출상면 및 접면 체크 centerPoints.forEach((centerPoint, index) => { - const { x, y, width, height } = centerPoint + let { x, y, width, height } = { ...centerPoint } let topCell let topLeftPoint @@ -845,22 +1147,27 @@ export const useTrestle = () => { switch (direction) { case 'south': - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y - height)) < 2) + width = width + horizontal + height = height + vertical + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y - height)) < maxY) topLeftPoint = { x: x - width / 2, y: y - height } topRightPoint = { x: x + width / 2, y: y - height } break case 'north': - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < 2 && Math.abs(centerPoint.y - (y + height)) < 2) + height = height + vertical + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - x) < maxX && Math.abs(centerPoint.y - (y + height)) < maxY) topLeftPoint = { x: x + width / 2, y: y + height } topRightPoint = { x: x - width / 2, y: y + height } break case 'east': - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < 2 && Math.abs(centerPoint.y - y) < 2) + width = width + horizontal + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x - width)) < maxX && Math.abs(centerPoint.y - y) < maxY) topLeftPoint = { x: x - width, y: y + height / 2 } topRightPoint = { x: x - width, y: y - height / 2 } break case 'west': - topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < 2 && Math.abs(centerPoint.y - y) < 2) + width = width + horizontal + topCell = centerPoints.filter((centerPoint) => Math.abs(centerPoint.x - (x + width)) < maxX && Math.abs(centerPoint.y - y) < maxY) topLeftPoint = { x: x + width, y: y - height / 2 } topRightPoint = { x: x + width, y: y + height / 2 } break @@ -872,10 +1179,10 @@ export const useTrestle = () => { } leftTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < 2 && Math.abs(centerPoint.y - topLeftPoint.y) < 2, + (centerPoint) => Math.abs(centerPoint.x - topLeftPoint.x) < maxX && Math.abs(centerPoint.y - topLeftPoint.y) < maxY, ).length rightTopCnt = centerPoints.filter( - (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < 2 && Math.abs(centerPoint.y - topRightPoint.y) < 2, + (centerPoint) => Math.abs(centerPoint.x - topRightPoint.x) < maxX && Math.abs(centerPoint.y - topRightPoint.y) < maxY, ).length if (leftTopCnt + rightTopCnt === 2) { @@ -886,6 +1193,12 @@ export const useTrestle = () => { if (leftTopCnt + rightTopCnt === 1) { exposedHalfTop++ halfTouchDimension++ + if (leftTopCnt === 1) { + rightExposedHalfTopPoints.push(centerPoint) + } + if (rightTopCnt === 1) { + leftExposedHalfTopPoints.push(centerPoint) + } return } if (leftTopCnt + rightTopCnt === 0) { @@ -894,10 +1207,6 @@ export const useTrestle = () => { }) // 완전 노출 하면 계산 - /*const cells = canvas.getObjects().filter((obj) => polygon.id === obj.parentId) - const points = cells.map((cell) => { - return cell.getCenterPoint() - })*/ const groupPoints = groupCoordinates(centerPoints, modules[0], direction) groupPoints.forEach((group) => { @@ -937,6 +1246,8 @@ export const useTrestle = () => { exposedBottomPoints, leftExposedHalfBottomPoints, rightExposedHalfBottomPoints, + leftExposedHalfTopPoints, + rightExposedHalfTopPoints, centerPoints, } }