Merge branch 'dev' into dev-yj
# Conflicts: # src/hooks/useMode.js
This commit is contained in:
commit
02635033ae
@ -2,7 +2,6 @@ import { useCanvas } from '@/hooks/useCanvas'
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Mode, useMode } from '@/hooks/useMode'
|
import { Mode, useMode } from '@/hooks/useMode'
|
||||||
import { Button } from '@nextui-org/react'
|
import { Button } from '@nextui-org/react'
|
||||||
|
|
||||||
import RangeSlider from './ui/RangeSlider'
|
import RangeSlider from './ui/RangeSlider'
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil'
|
import { useRecoilState, useRecoilValue } from 'recoil'
|
||||||
import { canvasSizeState, fontSizeState, roofMaterialState, sortedPolygonArray, templateTypeState, compassState } from '@/store/canvasAtom'
|
import { canvasSizeState, fontSizeState, roofMaterialState, sortedPolygonArray, templateTypeState, compassState } from '@/store/canvasAtom'
|
||||||
@ -10,6 +9,8 @@ import { QLine } from '@/components/fabric/QLine'
|
|||||||
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
import { getCanvasState, insertCanvasState } from '@/lib/canvas'
|
||||||
import { calculateIntersection } from '@/util/canvas-util'
|
import { calculateIntersection } from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import * as turf from '@turf/turf'
|
||||||
|
import { toGeoJSON } from '@/util/qpolygon-utils'
|
||||||
|
|
||||||
export default function Roof2() {
|
export default function Roof2() {
|
||||||
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
const { canvas, handleRedo, handleUndo, setCanvasBackgroundWithDots, saveImage, addCanvas } = useCanvas('canvas')
|
||||||
@ -53,6 +54,7 @@ export default function Roof2() {
|
|||||||
makeRoofPatternPolygon,
|
makeRoofPatternPolygon,
|
||||||
createRoofRack,
|
createRoofRack,
|
||||||
drawRoofPolygon,
|
drawRoofPolygon,
|
||||||
|
drawCellInTrestle,
|
||||||
} = useMode()
|
} = useMode()
|
||||||
|
|
||||||
// const [canvasState, setCanvasState] = useRecoilState(canvasAtom)
|
// const [canvasState, setCanvasState] = useRecoilState(canvasAtom)
|
||||||
@ -618,7 +620,10 @@ export default function Roof2() {
|
|||||||
지붕타입 지붕재
|
지붕타입 지붕재
|
||||||
</Button>
|
</Button>
|
||||||
<Button className="m-1 p-2" onClick={createRoofRack}>
|
<Button className="m-1 p-2" onClick={createRoofRack}>
|
||||||
지붕가대
|
지붕가대설치
|
||||||
|
</Button>
|
||||||
|
<Button className="m-1 p-2" onClick={drawCellInTrestle}>
|
||||||
|
선택한 가대 셀채우기
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -89,8 +89,8 @@ export function useCanvas(id) {
|
|||||||
canvas?.off('object:modified')
|
canvas?.off('object:modified')
|
||||||
canvas?.off('object:removed')
|
canvas?.off('object:removed')
|
||||||
canvas?.off('object:added')
|
canvas?.off('object:added')
|
||||||
canvas?.off('mouse:move', drawMouseLines)
|
canvas?.off('mouse:move')
|
||||||
canvas?.off('mouse:down', handleMouseDown)
|
canvas?.off('mouse:down')
|
||||||
}
|
}
|
||||||
|
|
||||||
const addEventOnObject = (e) => {
|
const addEventOnObject = (e) => {
|
||||||
@ -112,9 +112,11 @@ export function useCanvas(id) {
|
|||||||
target.on('mousedown', () => {
|
target.on('mousedown', () => {
|
||||||
if (target.get('selected')) {
|
if (target.get('selected')) {
|
||||||
target.set({ strokeWidth: 1 })
|
target.set({ strokeWidth: 1 })
|
||||||
|
target.set({ strokeDashArray: [5, 5] })
|
||||||
target.set({ selected: false })
|
target.set({ selected: false })
|
||||||
} else {
|
} else {
|
||||||
target.set({ strokeWidth: 5 })
|
target.set({ strokeWidth: 5 })
|
||||||
|
target.set({ strokeDashArray: [0, 0] })
|
||||||
target.set({ selected: true })
|
target.set({ selected: true })
|
||||||
}
|
}
|
||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
|
|||||||
@ -541,6 +541,7 @@ export function useMode() {
|
|||||||
|
|
||||||
if (historyPoints.current.length >= 4) {
|
if (historyPoints.current.length >= 4) {
|
||||||
const wall = drawWallPolygon()
|
const wall = drawWallPolygon()
|
||||||
|
setWall(wall)
|
||||||
handleOuterlinesTest2(wall)
|
handleOuterlinesTest2(wall)
|
||||||
setTemplateType(1)
|
setTemplateType(1)
|
||||||
}
|
}
|
||||||
@ -4464,13 +4465,18 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const createRoofRack = () => {
|
const createRoofRack = () => {
|
||||||
|
const trestlePolygons = canvas?.getObjects().filter((obj) => obj.name === 'trestle')
|
||||||
|
// 이미 만들어진 가대가 있을 경우 return
|
||||||
|
if (trestlePolygons.length !== 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas?.off('mouse:move')
|
||||||
|
canvas?.off('mouse:out')
|
||||||
|
document.removeEventListener('keydown', handleKeyDown)
|
||||||
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
|
const roofs = canvas?.getObjects().filter((obj) => obj.name === 'roof')
|
||||||
let roofCells = [] // roof에 적재된 cell들
|
let roofCells = [] // roof에 적재된 cell들
|
||||||
roofs.forEach((roof, index) => {
|
roofs.forEach((roof, index) => {
|
||||||
let maxLengthLine = roof.lines.reduce((acc, cur) => {
|
|
||||||
return acc.length > cur.length ? acc : cur
|
|
||||||
})
|
|
||||||
|
|
||||||
const offsetPolygonPoint = offsetPolygon(roof.points, -20)
|
const offsetPolygonPoint = offsetPolygon(roof.points, -20)
|
||||||
|
|
||||||
const trestlePoly = new QPolygon(offsetPolygonPoint, {
|
const trestlePoly = new QPolygon(offsetPolygonPoint, {
|
||||||
@ -4478,7 +4484,7 @@ export function useMode() {
|
|||||||
stroke: 'red',
|
stroke: 'red',
|
||||||
strokeDashArray: [5, 5],
|
strokeDashArray: [5, 5],
|
||||||
strokeWidth: 1,
|
strokeWidth: 1,
|
||||||
selectable: true,
|
selectable: false,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
name: 'trestle',
|
name: 'trestle',
|
||||||
lockMovementX: true, // X 축 이동 잠금
|
lockMovementX: true, // X 축 이동 잠금
|
||||||
@ -4491,14 +4497,45 @@ export function useMode() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
canvas?.add(trestlePoly)
|
canvas?.add(trestlePoly)
|
||||||
|
})
|
||||||
|
|
||||||
|
setDrewRoofCells(roofCells)
|
||||||
|
}
|
||||||
|
|
||||||
|
//배터리 셀 넣기
|
||||||
|
const drawCellInTrestle = () => {
|
||||||
|
const trestlePolygons = canvas?.getObjects().filter((obj) => obj.name === 'trestle' && obj.selected)
|
||||||
|
const notSelectedTrestlePolygons = canvas?.getObjects().filter((obj) => obj.name === 'trestle' && !obj.selected)
|
||||||
|
if (trestlePolygons.length === 0) {
|
||||||
|
alert('가대가 없습니다.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drewRoofCells.length > 0) {
|
||||||
|
alert('기존 셀은 제거됩니다.')
|
||||||
|
}
|
||||||
|
|
||||||
|
notSelectedTrestlePolygons.forEach((trestle) => {
|
||||||
|
trestle.cells.forEach((cell) => {
|
||||||
|
canvas?.remove(cell)
|
||||||
|
})
|
||||||
|
trestle.cells = []
|
||||||
|
})
|
||||||
|
|
||||||
|
const drawCellsArray = []
|
||||||
|
trestlePolygons.forEach((trestle, index) => {
|
||||||
|
trestle.fire('mousedown')
|
||||||
|
let maxLengthLine = trestle.lines.reduce((acc, cur) => {
|
||||||
|
return acc.length > cur.length ? acc : cur
|
||||||
|
})
|
||||||
|
|
||||||
let drawRoofCells
|
let drawRoofCells
|
||||||
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
if (maxLengthLine.direction === 'right' || maxLengthLine.direction === 'left') {
|
||||||
drawRoofCells = trestlePoly.fillCell({ width: 100, height: 50, padding: 10 })
|
drawRoofCells = trestle.fillCell({ width: 50, height: 100, padding: 0 })
|
||||||
trestlePoly.direction = 'south'
|
trestle.direction = 'south'
|
||||||
} else {
|
} else {
|
||||||
drawRoofCells = trestlePoly.fillCell({ width: 50, height: 100, padding: 10 })
|
drawRoofCells = trestle.fillCell({ width: 100, height: 50, padding: 0 })
|
||||||
trestlePoly.direction = 'east'
|
trestle.direction = 'east'
|
||||||
}
|
}
|
||||||
|
|
||||||
drawRoofCells.forEach((cell) => {
|
drawRoofCells.forEach((cell) => {
|
||||||
@ -4589,5 +4626,6 @@ export function useMode() {
|
|||||||
makeRoofTrestle,
|
makeRoofTrestle,
|
||||||
createRoofRack,
|
createRoofRack,
|
||||||
drawRoofPolygon,
|
drawRoofPolygon,
|
||||||
|
drawCellInTrestle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import {
|
|||||||
getRoofHypotenuse,
|
getRoofHypotenuse,
|
||||||
} from '@/util/canvas-util'
|
} from '@/util/canvas-util'
|
||||||
import { QPolygon } from '@/components/fabric/QPolygon'
|
import { QPolygon } from '@/components/fabric/QPolygon'
|
||||||
|
import * as turf from '@turf/turf'
|
||||||
|
|
||||||
const TWO_PI = Math.PI * 2
|
const TWO_PI = Math.PI * 2
|
||||||
|
|
||||||
@ -983,6 +984,43 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 좌표 테스트용
|
||||||
|
*/
|
||||||
|
allLines.forEach((line) => {
|
||||||
|
const text = new fabric.Text(`(${line.startPoint.x},${line.startPoint.y})`, {
|
||||||
|
left: line.startPoint.x,
|
||||||
|
top: line.startPoint.y,
|
||||||
|
fontSize: 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(text)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
|
||||||
|
const text2 = new fabric.Text(`(${line.endPoint.x},${line.endPoint.y})`, {
|
||||||
|
left: line.endPoint.x,
|
||||||
|
top: line.endPoint.y,
|
||||||
|
fontSize: 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(text2)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.points.forEach((point, index) => {
|
||||||
|
const text = new fabric.Text(`(${point.x},${point.y})`, {
|
||||||
|
left: point.x,
|
||||||
|
top: point.y,
|
||||||
|
fontSize: 15,
|
||||||
|
})
|
||||||
|
|
||||||
|
polygon.canvas.add(text)
|
||||||
|
polygon.canvas.renderAll()
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* 좌표 테스트용 끝
|
||||||
|
*/
|
||||||
|
|
||||||
polygon.points.forEach((point, index) => {
|
polygon.points.forEach((point, index) => {
|
||||||
allLines.forEach((line) => {
|
allLines.forEach((line) => {
|
||||||
if (line.endPoint.x === point.x && line.endPoint.y === point.y) {
|
if (line.endPoint.x === point.x && line.endPoint.y === point.y) {
|
||||||
@ -1007,22 +1045,39 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
const arrivalPoint = endLine.endPoint
|
const arrivalPoint = endLine.endPoint
|
||||||
routes.push(startLine.startPoint)
|
routes.push(startLine.startPoint)
|
||||||
routes.push(startLine.endPoint)
|
routes.push(startLine.endPoint)
|
||||||
|
|
||||||
//hip끼리 만나는 경우는 아무것도 안해도됨
|
//hip끼리 만나는 경우는 아무것도 안해도됨
|
||||||
let count = 0
|
|
||||||
if (!isSamePoint(startLine.endPoint, arrivalPoint)) {
|
if (!isSamePoint(startLine.endPoint, arrivalPoint)) {
|
||||||
// polygon line까지 추가
|
// polygon line까지 추가
|
||||||
const allLinesCopy = [...allLines, ...polygon.lines]
|
const allLinesCopy = [...allLines, ...polygon.lines]
|
||||||
// hip이 만나지 않는 경우 갈 수 있는 길을 다 돌아야함
|
// hip이 만나지 않는 경우 갈 수 있는 길을 다 돌아야함
|
||||||
let currentPoint = startLine.endPoint
|
let currentPoint = startLine.endPoint
|
||||||
let currentLine = startLine
|
let currentLine = startLine
|
||||||
|
let movedLines = []
|
||||||
while (!isSamePoint(currentPoint, arrivalPoint) && count <= polygon.points.length) {
|
let subMovedLines = []
|
||||||
count++
|
while (!isSamePoint(currentPoint, arrivalPoint)) {
|
||||||
// startHip에서 만나는 출발선 두개. 두개의 선을 출발하여 arrivalPoint에 도착할 때 까지 count를 세고, 더 낮은 count를 가진 길을 선택한다.
|
// startHip에서 만나는 출발선 두개. 두개의 선을 출발하여 arrivalPoint에 도착할 때 까지 count를 세고, 더 낮은 count를 가진 길을 선택한다.
|
||||||
let connectedLines = allLinesCopy.filter((line) => isSamePoint(line.startPoint, currentPoint) || isSamePoint(line.endPoint, currentPoint))
|
let connectedLines = allLinesCopy.filter((line) => isSamePoint(line.startPoint, currentPoint) || isSamePoint(line.endPoint, currentPoint))
|
||||||
|
|
||||||
connectedLines = connectedLines.filter((line) => line !== currentLine)
|
connectedLines = connectedLines.filter((line) => line !== currentLine)
|
||||||
|
|
||||||
|
connectedLines = connectedLines.filter((line) => !subMovedLines.includes(line))
|
||||||
|
|
||||||
|
//마지막 선이 endLine의 startPoint와 같은경우 그 전까지 movedLine을 제거한다.
|
||||||
|
const endLineMeetLineCnt = connectedLines.filter((line) => {
|
||||||
|
return isSamePoint(line.endPoint, endLine.startPoint) || isSamePoint(line.startPoint, endLine.startPoint)
|
||||||
|
}).length
|
||||||
|
|
||||||
|
if (endLineMeetLineCnt !== 0) {
|
||||||
|
movedLines.push(subMovedLines)
|
||||||
|
|
||||||
|
console.log(movedLines, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedLines = connectedLines.filter((line) => {
|
||||||
|
return !isSamePoint(line.endPoint, endLine.startPoint) && !isSamePoint(line.startPoint, endLine.startPoint)
|
||||||
|
})
|
||||||
|
|
||||||
if (connectedLines.length === 0) {
|
if (connectedLines.length === 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1050,14 +1105,15 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
|
|
||||||
currentPoint = tempPoints[minIndex].point
|
currentPoint = tempPoints[minIndex].point
|
||||||
currentLine = tempPoints[minIndex].line
|
currentLine = tempPoints[minIndex].line
|
||||||
|
if (currentLine !== startLine) {
|
||||||
|
subMovedLines.push(currentLine)
|
||||||
|
}
|
||||||
routes.push(currentPoint)
|
routes.push(currentPoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count <= polygon.points.length - 1) {
|
routes.push(endLine.startPoint)
|
||||||
routes.push(endLine.startPoint)
|
roofs.push(routes)
|
||||||
roofs.push(routes)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 중복 제거
|
// 중복 제거
|
||||||
@ -1078,6 +1134,7 @@ export const splitPolygonWithLines = (polygon) => {
|
|||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
strokeWidth: 3,
|
strokeWidth: 3,
|
||||||
name: 'roof',
|
name: 'roof',
|
||||||
|
selectable: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
polygon.canvas.add(roof)
|
polygon.canvas.add(roof)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user