셀추가 작업
This commit is contained in:
parent
78f77e8c6e
commit
69568966ba
@ -204,7 +204,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
this.canvas = canvas
|
||||
},
|
||||
fillCell(cell = { width: 50, height: 100, padding: 10 }) {
|
||||
const points = this.getCurrentPoints()
|
||||
const points = this.points
|
||||
|
||||
const minX = Math.min(...points.map((p) => p.x))
|
||||
const maxX = Math.max(...points.map((p) => p.x))
|
||||
@ -231,8 +231,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
|
||||
for (let i = 0; i < cols; i++) {
|
||||
for (let j = 0; j < rows; j++) {
|
||||
const rectLeft = minX + i * (rectWidth + cell.padding) + tmpWidth
|
||||
const rectTop = minY + j * (rectHeight + cell.padding) + tmpHeight
|
||||
const rectLeft = minX + i * (rectWidth + cell.padding)
|
||||
const rectTop = minY + j * (rectHeight + cell.padding)
|
||||
|
||||
const rectPoints = [
|
||||
{ x: rectLeft, y: rectTop },
|
||||
@ -240,6 +240,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
{ x: rectLeft, y: rectTop + rectHeight },
|
||||
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
||||
]
|
||||
|
||||
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
||||
|
||||
if (allPointsInside) {
|
||||
@ -272,6 +273,102 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
this.cells = drawCellsArray
|
||||
return drawCellsArray
|
||||
},
|
||||
fillCellABTemplate(cell = { width: 50, height: 100, padding: 5, parallelPoint: undefined, startX: 0, startY: 0 }) {
|
||||
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)) //위
|
||||
const maxY = Math.max(...points.map((p) => p.y)) //아래
|
||||
|
||||
const boundingBoxWidth = maxX - minX
|
||||
const boundingBoxHeight = maxY - minY
|
||||
|
||||
const rectWidth = cell.width
|
||||
const rectHeight = cell.height
|
||||
|
||||
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문 추가해서 정렬해야함
|
||||
const tmpWidth = (boundingBoxWidth - (rectWidth + cell.padding) * cols) / 2
|
||||
|
||||
const drawCellsArray = [] //그려진 셀의 배열
|
||||
|
||||
let idx = 1
|
||||
|
||||
if (cell.parallelPoint > -1) {
|
||||
//4각형 이상이면 각 꼭지점에서 위, 아래로 이동하면서 채움
|
||||
//앞에서 -1로 선언함
|
||||
if (cell.parallelPoint === 1 || cell.parallelPoint === 2) {
|
||||
//ㄴ자 역ㄱ자
|
||||
//밑에서 위로 올라가야하면
|
||||
cell.startY = cell.startY - (rectHeight + cell.padding) * rows
|
||||
if (cell.parallelPoint === 2) {
|
||||
cell.startX = cell.startX - (rectWidth + cell.padding) * cols
|
||||
}
|
||||
} else {
|
||||
if (cell.parallelPoint === 5) {
|
||||
cell.startX = cell.startX - (rectWidth + cell.padding) * cols
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let startXPos, startYPos
|
||||
|
||||
for (let i = 0; i < cols; i++) {
|
||||
for (let j = 0; j < rows; j++) {
|
||||
if (cell.parallelPoint > -1) {
|
||||
startXPos = cell.startX + i * (rectWidth + cell.padding)
|
||||
startYPos = cell.startY + j * (rectHeight + cell.padding)
|
||||
} else {
|
||||
startXPos = minX + i * (rectWidth + cell.padding)
|
||||
startYPos = minY + j * (rectHeight + cell.padding)
|
||||
}
|
||||
|
||||
const rectPoints = []
|
||||
|
||||
rectPoints.push(
|
||||
{ x: startXPos, y: startYPos },
|
||||
{ x: startXPos + rectWidth, y: startYPos },
|
||||
{ x: startXPos, y: startYPos + rectHeight },
|
||||
{ x: startXPos + rectWidth, y: startYPos + rectHeight },
|
||||
)
|
||||
|
||||
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
||||
|
||||
if (allPointsInside) {
|
||||
const rect = new fabric.Rect({
|
||||
left: startXPos,
|
||||
top: startYPos,
|
||||
width: rectWidth,
|
||||
height: rectHeight,
|
||||
fill: '#BFFD9F',
|
||||
stroke: 'black',
|
||||
selectable: true, // 선택 가능하게 설정
|
||||
// lockMovementX: true, // X 축 이동 잠금
|
||||
// lockMovementY: true, // Y 축 이동 잠금
|
||||
// lockRotation: true, // 회전 잠금
|
||||
// lockScalingX: true, // X 축 크기 조정 잠금
|
||||
// lockScalingY: true, // Y 축 크기 조정 잠금
|
||||
opacity: 0.8,
|
||||
name: 'cell',
|
||||
idx: idx,
|
||||
})
|
||||
|
||||
idx++
|
||||
drawCellsArray.push(rect) //배열에 넣어서 반환한다
|
||||
this.canvas.add(rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.canvas?.renderAll()
|
||||
this.cells = drawCellsArray
|
||||
return drawCellsArray
|
||||
},
|
||||
|
||||
inPolygon(point) {
|
||||
const vertices = this.points
|
||||
let intersects = 0
|
||||
@ -295,7 +392,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
}
|
||||
|
||||
let xInt = ((point.y - vertex1.y) * (vertex2.x - vertex1.x)) / (vertex2.y - vertex1.y) + vertex1.x
|
||||
if (xInt < point.x) {
|
||||
if (xInt <= point.x) {
|
||||
intersects++
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,7 +510,7 @@ export function useMode() {
|
||||
* 마우스로 그린 점 기준으로 외벽선을 완성시켜준다.
|
||||
* makePolygon 함수에 포함되어있던 내용을 다른 템플릿 적용에서도 사용할수 있도록 함수로 대체
|
||||
*/
|
||||
const drawWallPolygon = () => {
|
||||
const drawWallPolygon = (sort = true) => {
|
||||
const firstPoint = historyPoints.current[0]
|
||||
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
||||
historyPoints.current.forEach((point) => {
|
||||
@ -521,7 +521,7 @@ export function useMode() {
|
||||
historyPoints.current = []
|
||||
|
||||
// handleOuterlines()
|
||||
const wall = makePolygon()
|
||||
const wall = makePolygon(null, sort)
|
||||
wall.set({ name: 'wall' })
|
||||
setWall(wall)
|
||||
|
||||
@ -638,7 +638,7 @@ export function useMode() {
|
||||
canvas?.renderAll()
|
||||
}
|
||||
|
||||
const makePolygon = (otherLines) => {
|
||||
const makePolygon = (otherLines, sort = true) => {
|
||||
// 캔버스에서 모든 라인 객체를 찾습니다.
|
||||
const lines = otherLines || historyLines.current
|
||||
|
||||
@ -685,6 +685,7 @@ export function useMode() {
|
||||
fill: 'transparent',
|
||||
viewLengthText: true,
|
||||
fontSize: fontSize,
|
||||
sort: sort,
|
||||
},
|
||||
canvas,
|
||||
)
|
||||
@ -1087,7 +1088,7 @@ export function useMode() {
|
||||
offsetPoints.push(offsetPoint)
|
||||
}
|
||||
|
||||
return makePolygon(offsetPoints)
|
||||
return makePolygon(offsetPoints, false)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1146,7 +1147,7 @@ export function useMode() {
|
||||
|
||||
const applyTemplateA = () => {
|
||||
changeMode(canvas, Mode.EDIT)
|
||||
const polygon = drawWallPolygon()
|
||||
const polygon = drawWallPolygon(false)
|
||||
handleClear()
|
||||
|
||||
if (polygon.lines.length === 4) {
|
||||
@ -1895,12 +1896,7 @@ export function useMode() {
|
||||
|
||||
//작은 지붕쪽 높이 길이를 구하는 로직
|
||||
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
||||
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 + edge], {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 4,
|
||||
property: 'centerLine',
|
||||
fontSize: 14,
|
||||
})
|
||||
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 + edge], centerLineOpt)
|
||||
|
||||
canvas.add(secondVertCenterLine)
|
||||
outLines.push(secondVertCenterLine)
|
||||
@ -2085,38 +2081,10 @@ export function useMode() {
|
||||
return tmpArray
|
||||
}
|
||||
|
||||
// 외적을 계산하는 함수
|
||||
function crossProduct(p1, p2, p3) {
|
||||
const dx1 = p2.x - p1.x
|
||||
const dy1 = p2.y - p1.y
|
||||
const dx2 = p3.x - p2.x
|
||||
const dy2 = p3.y - p2.y
|
||||
return dx1 * dy2 - dy1 * dx2
|
||||
}
|
||||
|
||||
let concaveIndices = [] //볼록한 부분 인덱스 배열
|
||||
let concavePointIndices = [] //오목한 부분 인덱스 배열
|
||||
|
||||
// 오목한 부분 찾기
|
||||
function findConcavePointIndices(points) {
|
||||
let concaveIndices = []
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const p1 = points[i]
|
||||
const p2 = points[(i + 1) % points.length]
|
||||
const p3 = points[(i + 2) % points.length]
|
||||
const cross = crossProduct(p1, p2, p3)
|
||||
if (cross < 0) {
|
||||
concaveIndices.push((i + 1) % points.length)
|
||||
} else {
|
||||
concavePointIndices.push((i + 1) % points.length)
|
||||
}
|
||||
}
|
||||
return concaveIndices
|
||||
}
|
||||
|
||||
// 오목한 부분 인덱스 찾기
|
||||
concaveIndices = findConcavePointIndices(points) //오목한 부분을 제외한 인덱스
|
||||
const concavePoints = concaveIndices.map((index) => points[index])
|
||||
const concaveIndicesObj = findConcavePointIndices(points) //오목한 부분을 제외한 인덱스
|
||||
let concavePointIndices = concaveIndicesObj.concavePointIndices
|
||||
|
||||
const concaveLine = {
|
||||
index: concavePointIndices[0],
|
||||
line: lines[concavePointIndices[0]],
|
||||
@ -2168,7 +2136,7 @@ export function useMode() {
|
||||
offsetPoints.push(offsetPoint)
|
||||
}
|
||||
|
||||
const outlinePolygon = makePolygon(offsetPoints)
|
||||
const outlinePolygon = makePolygon(offsetPoints, false)
|
||||
outlinePolygon.setViewLengthText(false)
|
||||
|
||||
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
||||
@ -2178,7 +2146,7 @@ export function useMode() {
|
||||
|
||||
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||
stroke: 'blue',
|
||||
strokeWidth: 2,
|
||||
strokeWidth: 1,
|
||||
property: 'normal',
|
||||
fontSize: 14,
|
||||
idx: i,
|
||||
@ -2607,7 +2575,7 @@ export function useMode() {
|
||||
*/
|
||||
const applyTemplateB = () => {
|
||||
changeMode(canvas, Mode.EDIT)
|
||||
const polygon = drawWallPolygon()
|
||||
const polygon = drawWallPolygon(false)
|
||||
const params = {
|
||||
eaves: 50,
|
||||
edge: 20,
|
||||
@ -3149,7 +3117,7 @@ export function useMode() {
|
||||
ctx.scale(ratio, ratio)
|
||||
|
||||
if (mode === 'cell') {
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.3)'
|
||||
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'
|
||||
ctx.fillRect(0, 0, patternSize.width * 2, patternSize.height * 2)
|
||||
}
|
||||
|
||||
@ -3286,7 +3254,9 @@ export function useMode() {
|
||||
canvas?.renderAll()
|
||||
}
|
||||
|
||||
const pattern = getRoofPattern(roofStyle, 'cell')
|
||||
const pattern = getRoofPattern(roofStyle, 'cell') //셀모드 배경색을 칠한다
|
||||
|
||||
polygons.sort((a, b) => a.lines.length > b.lines.length) //무조건 잴 긴거 정렬
|
||||
|
||||
// 외각선을 안쪽으로 그려 가대선을 그린다.
|
||||
polygons.forEach((polygon, index) => {
|
||||
@ -3312,9 +3282,6 @@ export function useMode() {
|
||||
trestlePolygon.on('mousedown', function () {
|
||||
toggleSelection(trestlePolygon)
|
||||
})
|
||||
|
||||
console.log('polygon', polygon)
|
||||
|
||||
polygon.set({ fill: pattern })
|
||||
})
|
||||
|
||||
@ -3349,7 +3316,7 @@ export function useMode() {
|
||||
}
|
||||
}
|
||||
|
||||
const inputCellSize = { width: 172, height: 113 }
|
||||
const inputCellSize = { width: 172, height: 113 } //추후 입력받는 값으로 변경
|
||||
const cellSize = { ...inputCellSize } //기본으로 가로형으로 넣고
|
||||
|
||||
if (templateType === 2) {
|
||||
@ -3357,7 +3324,25 @@ export function useMode() {
|
||||
}
|
||||
|
||||
selectedCellRoofArray.forEach((polygon, index) => {
|
||||
const drawCells = polygon.fillCell({ width: cellSize.width, height: cellSize.height, padding: 10 })
|
||||
let parallelPoint = -1 //오목한 부분의 반대 꼭지점 //없는 애들도 있어서 -1
|
||||
const startPoint = {} //도형의 시작점을 찾기 위해
|
||||
|
||||
if (polygon.lines.length > 4) {
|
||||
const concave = findConcavePointIndices(polygon.points) //오목한 부분기준으로 시작점을 찾으려 계산
|
||||
parallelPoint = parseInt(concave.concavePointIndices[0] + 3) % polygon.points.length //시작점을 찾기 위해 적용
|
||||
startPoint.x = polygon.points[parallelPoint].x
|
||||
startPoint.y = polygon.points[parallelPoint].y
|
||||
}
|
||||
|
||||
const drawCells = polygon.fillCellABTemplate({
|
||||
width: cellSize.width,
|
||||
height: cellSize.height,
|
||||
padding: 10,
|
||||
parallelPoint: parallelPoint,
|
||||
startX: startPoint.x,
|
||||
startY: startPoint.y,
|
||||
})
|
||||
// const drawCells = polygon.fillCell({ width: cellSize.width, height: cellSize.height, padding: 10 })
|
||||
drawCellsArray.push({ roofIndex: polygon.customIndex, drawCells: drawCells })
|
||||
})
|
||||
|
||||
@ -3411,6 +3396,32 @@ export function useMode() {
|
||||
setDrewRoofCells(roofCells)
|
||||
}
|
||||
|
||||
// 외적을 계산하는 함수
|
||||
const crossProduct = (p1, p2, p3) => {
|
||||
const dx1 = p2.x - p1.x
|
||||
const dy1 = p2.y - p1.y
|
||||
const dx2 = p3.x - p2.x
|
||||
const dy2 = p3.y - p2.y
|
||||
return dx1 * dy2 - dy1 * dx2
|
||||
}
|
||||
// 오목한 부분 찾기
|
||||
const findConcavePointIndices = (points) => {
|
||||
let concaveIndices = []
|
||||
let concavePointIndices = []
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const p1 = points[i]
|
||||
const p2 = points[(i + 1) % points.length]
|
||||
const p3 = points[(i + 2) % points.length]
|
||||
const cross = crossProduct(p1, p2, p3)
|
||||
if (cross < 0) {
|
||||
concaveIndices.push((i + 1) % points.length)
|
||||
} else {
|
||||
concavePointIndices.push((i + 1) % points.length)
|
||||
}
|
||||
}
|
||||
return { concaveIndices: concaveIndices, concavePointIndices: concavePointIndices }
|
||||
}
|
||||
|
||||
return {
|
||||
mode,
|
||||
setMode,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user