버그 수정
This commit is contained in:
parent
55b29bfdd3
commit
2ca9fd5bbc
@ -2,7 +2,7 @@ import { fabric } from 'fabric'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { QLine } from '@/components/fabric/QLine'
|
||||
import { distanceBetweenPoints, findTopTwoIndexesByDistance, getDirectionByPoint, sortedPointLessEightPoint, sortedPoints } from '@/util/canvas-util'
|
||||
import { calculateAngle, drawGabledRoof, drawRidgeRoof, drawShedRoof, inPolygon, toGeoJSON } from '@/util/qpolygon-utils'
|
||||
import { calculateAngle, drawGabledRoof, drawRidgeRoof, drawShedRoof, toGeoJSON } from '@/util/qpolygon-utils'
|
||||
import * as turf from '@turf/turf'
|
||||
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
||||
import Big from 'big.js'
|
||||
@ -188,8 +188,28 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
})
|
||||
},
|
||||
|
||||
// 보조선 그리기
|
||||
/**
|
||||
* 보조선 그리기
|
||||
* @param settingModalFirstOptions
|
||||
*/
|
||||
drawHelpLine(settingModalFirstOptions) {
|
||||
let textMode = 'plane'
|
||||
|
||||
const dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
|
||||
? settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
|
||||
: 1
|
||||
switch (dimensionDisplay) {
|
||||
case 1:
|
||||
textMode = 'plane'
|
||||
break
|
||||
case 2:
|
||||
textMode = 'actual'
|
||||
break
|
||||
case 3:
|
||||
textMode = 'none'
|
||||
break
|
||||
}
|
||||
|
||||
const types = []
|
||||
this.lines.forEach((line) => types.push(line.attributes.type))
|
||||
|
||||
@ -206,7 +226,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
(gableOdd.every((type) => type === LINE_TYPE.WALLLINE.EAVES) && gableEven.every((type) => gableType.includes(type))) ||
|
||||
(gableEven.every((type) => type === LINE_TYPE.WALLLINE.EAVES) && gableOdd.every((type) => gableType.includes(type)))
|
||||
) {
|
||||
drawGabledRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawGabledRoof(this.id, this.canvas, textMode)
|
||||
} else if (hasShed) {
|
||||
const sheds = this.lines.filter((line) => line.attributes !== undefined && line.attributes.type === LINE_TYPE.WALLLINE.SHED)
|
||||
const areLinesParallel = function (line1, line2) {
|
||||
@ -233,18 +253,18 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
const gables = this.lines.filter((line) => sheds.includes(line) === false && eaves.includes(line) === false)
|
||||
const isGable = gables.every((line) => gableType.includes(line.attributes.type))
|
||||
if (isGable) {
|
||||
drawShedRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawShedRoof(this.id, this.canvas, textMode)
|
||||
} else {
|
||||
drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
}
|
||||
} else {
|
||||
drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
}
|
||||
} else {
|
||||
drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
}
|
||||
} else {
|
||||
drawRidgeRoof(this.id, this.canvas, settingModalFirstOptions)
|
||||
drawRidgeRoof(this.id, this.canvas, textMode)
|
||||
}
|
||||
},
|
||||
|
||||
@ -264,11 +284,8 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
this.texts = []
|
||||
points.forEach((start, i) => {
|
||||
const end = points[(i + 1) % points.length]
|
||||
// planeSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||
// actualSize: Math.round(Math.sqrt(Math.pow(newLine.x1 - newLine.x2, 2) + Math.pow(newLine.y1 - newLine.y2, 2))) * 10,
|
||||
const dx = Big(end.x).minus(Big(start.x))
|
||||
const dy = Big(end.y).minus(Big(start.y))
|
||||
// const length = Math.round(Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2))) * 10
|
||||
const length = dx.pow(2).plus(dy.pow(2)).sqrt().times(10).round().toNumber()
|
||||
|
||||
let midPoint
|
||||
@ -323,75 +340,6 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
||||
setCanvas(canvas) {
|
||||
this.canvas = canvas
|
||||
},
|
||||
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))
|
||||
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문 추가해서 정렬해야함
|
||||
let tmpWidth = (boundingBoxWidth - (rectWidth + cell.padding) * cols) / 2
|
||||
|
||||
const drawCellsArray = [] //그려진 셀의 배열
|
||||
|
||||
let idx = 1
|
||||
|
||||
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 rectPoints = [
|
||||
{ x: rectLeft, y: rectTop },
|
||||
{ x: rectLeft, y: rectTop + rectHeight },
|
||||
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
||||
{ x: rectLeft + rectWidth, y: rectTop },
|
||||
]
|
||||
|
||||
if (inPolygon(this.points, rectPoints)) {
|
||||
const rect = new fabric.Rect({
|
||||
left: rectLeft,
|
||||
top: rectTop,
|
||||
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,
|
||||
parentId: this.id,
|
||||
parent: this,
|
||||
})
|
||||
|
||||
idx++
|
||||
drawCellsArray.push(rect) //배열에 넣어서 반환한다
|
||||
this.canvas.add(rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.canvas?.renderAll()
|
||||
this.cells = drawCellsArray
|
||||
return drawCellsArray
|
||||
},
|
||||
fillCellABType(
|
||||
cell = { width: 50, height: 100, padding: 5, wallDirection: 'left', referenceDirection: 'none', startIndex: -1, isCellCenter: false },
|
||||
) {
|
||||
|
||||
@ -329,7 +329,9 @@ export function useRoofFn() {
|
||||
|
||||
const allRoofObject = canvas
|
||||
.getObjects()
|
||||
.filter((obj) => /*obj !== roof && obj !== wall &&*/ obj.attributes?.roofId === roof.id || obj.parentId === roof.id || obj.parentId === wall.id)
|
||||
.filter(
|
||||
(obj) => /*obj !== roof && obj !== wall &&*/ obj.attributes?.roofId === roof.id || obj.parentId === roof.id || obj.parentId === wall?.id,
|
||||
)
|
||||
|
||||
allRoofObject.forEach((obj) => {
|
||||
canvas.remove(obj)
|
||||
|
||||
@ -1797,6 +1797,10 @@ export function useMode() {
|
||||
roof.direction = wall.direction
|
||||
}
|
||||
if (wall.attributes?.roofId) {
|
||||
canvas
|
||||
.getObjects()
|
||||
.filter((obj) => obj.parentId === roof.id)
|
||||
.forEach((obj) => obj.set('parentId', wall.attributes.roofId))
|
||||
roof.id = wall.attributes.roofId
|
||||
}
|
||||
roof.name = POLYGON_TYPE.ROOF
|
||||
|
||||
@ -312,8 +312,9 @@ export const isSamePoint = (a, b) => {
|
||||
* 박공지붕(templateA, templateB)을 그린다.
|
||||
* @param roofId
|
||||
* @param canvas
|
||||
* @param textMode
|
||||
*/
|
||||
export const drawGabledRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
export const drawGabledRoof = (roofId, canvas, textMode) => {
|
||||
const roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||
const roofLines = roof.lines
|
||||
const wallLines = canvas?.getObjects().find((object) => object.name === POLYGON_TYPE.WALL && object.attributes.roofId === roof.id).lines
|
||||
@ -323,15 +324,6 @@ export const drawGabledRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
return
|
||||
}
|
||||
|
||||
// const roofPoints = roof.points
|
||||
// const minX = Math.min(...roofPoints.map((point) => point.x))
|
||||
// const maxX = Math.max(...roofPoints.map((point) => point.x))
|
||||
// const minY = Math.min(...roofPoints.map((point) => point.y))
|
||||
// const maxY = Math.max(...roofPoints.map((point) => point.y))
|
||||
|
||||
// 맞은편 라인을 찾기 위해 현재 polygon 으로 만들수 있는 최대한의 길이를 구한다.
|
||||
// const checkLength = Math.abs(Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2)))
|
||||
|
||||
// 처마라인의 기본속성 입력
|
||||
const eaves = []
|
||||
roofLines.forEach((currentRoof, index) => {
|
||||
@ -650,8 +642,9 @@ export const drawGabledRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
* 한쪽흐름 지붕
|
||||
* @param roofId
|
||||
* @param canvas
|
||||
* @param textMode
|
||||
*/
|
||||
export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
export const drawShedRoof = (roofId, canvas, textMode) => {
|
||||
const roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||
const hasNonParallelLines = roof.lines.filter((line) => Math.abs(line.x1 - line.x2) > 1 && Math.abs(line.y1 - line.y2) > 1)
|
||||
if (hasNonParallelLines.length > 0) {
|
||||
@ -673,11 +666,9 @@ export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
return Math.tan(degree * (Math.PI / 180)) * adjust
|
||||
}
|
||||
|
||||
gables.forEach((gable) => {
|
||||
const adjust = gable.attributes.planeSize
|
||||
const height = getHeight(adjust, shedDegree)
|
||||
gable.attributes.actualSize = Math.round(Math.sqrt(Math.pow(adjust, 2) + Math.pow(height, 2)))
|
||||
})
|
||||
gables.forEach(
|
||||
(gable) => (gable.attributes.actualSize = calcLineActualSize({ x1: gable.x1, y1: gable.y1, x2: gable.x2, y2: gable.y2 }, shedDegree)),
|
||||
)
|
||||
|
||||
const pitchSizeLines = []
|
||||
|
||||
@ -707,8 +698,11 @@ export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
x2 = eave.x1
|
||||
}
|
||||
points.sort((a, b) => a - b)
|
||||
const planeSize = Math.round(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) * 10)
|
||||
const actualSize = Math.round(Math.sqrt(Math.pow(planeSize, 2) + Math.pow(getHeight(planeSize, shedDegree), 2)) * 10)
|
||||
// const planeSize = Math.round(Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) * 10)
|
||||
const planeSize = calcLinePlaneSize({ x1, y1, x2, y2 })
|
||||
// const actualSize = Math.round(Math.sqrt (Math.pow(planeSize, 2) + Math.pow(getHeight(planeSize, shedDegree), 2)) * 10)
|
||||
const actualSize = calcLineActualSize({ x1, y1, x2, y2 }, shedDegree)
|
||||
|
||||
const line = new QLine([x1, y1, x2, y2], {
|
||||
parentId: roof.id,
|
||||
stroke: '#000000',
|
||||
@ -716,10 +710,11 @@ export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
strokeDashArray: [5, 5],
|
||||
selectable: false,
|
||||
fontSize: roof.fontSize,
|
||||
textMode: textMode,
|
||||
attributes: {
|
||||
roofId: roof.id,
|
||||
type: 'pitchSizeLine',
|
||||
planeSize: planeSize,
|
||||
planeSize: actualSize,
|
||||
actualSize: actualSize,
|
||||
},
|
||||
})
|
||||
@ -730,33 +725,17 @@ export const drawShedRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
const maxLine = pitchSizeLines.reduce((prev, current) => (prev.length > current.length ? prev : current), pitchSizeLines[0])
|
||||
canvas.add(maxLine)
|
||||
canvas.renderAll()
|
||||
|
||||
const adjust = Math.sqrt(
|
||||
Math.pow(Math.round(Math.abs(maxLine.x1 - maxLine.x2) * 10), 2) + Math.pow(Math.round(Math.abs(maxLine.y1 - maxLine.y2) * 10), 2),
|
||||
)
|
||||
const height = getHeight(adjust, shedDegree)
|
||||
const lengthText = Math.round(Math.sqrt(Math.pow(adjust, 2) + Math.pow(height, 2)))
|
||||
maxLine.setLengthText(lengthText)
|
||||
}
|
||||
|
||||
export const drawRidgeRoof = (roofId, canvas, settingModalFirstOptions) => {
|
||||
/**
|
||||
* 마루가 있는 지붕을 그린다.
|
||||
* @param roofId
|
||||
* @param canvas
|
||||
* @param textMode
|
||||
*/
|
||||
export const drawRidgeRoof = (roofId, canvas, textMode) => {
|
||||
const roof = canvas?.getObjects().find((object) => object.id === roofId)
|
||||
let textMode = 'plane'
|
||||
|
||||
const dimensionDisplay = settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
|
||||
? settingModalFirstOptions?.dimensionDisplay.find((opt) => opt.selected).id
|
||||
: 1
|
||||
switch (dimensionDisplay) {
|
||||
case 1:
|
||||
textMode = 'plane'
|
||||
break
|
||||
case 2:
|
||||
textMode = 'actual'
|
||||
break
|
||||
case 3:
|
||||
textMode = 'none'
|
||||
break
|
||||
}
|
||||
//Math.abs(line.x1 - line.x2) > 1 && Math.abs(line.y1 - line.y2) > 1
|
||||
const hasNonParallelLines = roof.lines.filter((line) => Big(line.x1).minus(Big(line.x2)).gt(1) && Big(line.y1).minus(Big(line.y2)).gt(1))
|
||||
if (hasNonParallelLines.length > 0) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user