셀추가 작업
This commit is contained in:
parent
78f77e8c6e
commit
69568966ba
@ -204,7 +204,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
this.canvas = canvas
|
this.canvas = canvas
|
||||||
},
|
},
|
||||||
fillCell(cell = { width: 50, height: 100, padding: 10 }) {
|
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 minX = Math.min(...points.map((p) => p.x))
|
||||||
const maxX = Math.max(...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 i = 0; i < cols; i++) {
|
||||||
for (let j = 0; j < rows; j++) {
|
for (let j = 0; j < rows; j++) {
|
||||||
const rectLeft = minX + i * (rectWidth + cell.padding) + tmpWidth
|
const rectLeft = minX + i * (rectWidth + cell.padding)
|
||||||
const rectTop = minY + j * (rectHeight + cell.padding) + tmpHeight
|
const rectTop = minY + j * (rectHeight + cell.padding)
|
||||||
|
|
||||||
const rectPoints = [
|
const rectPoints = [
|
||||||
{ x: rectLeft, y: rectTop },
|
{ x: rectLeft, y: rectTop },
|
||||||
@ -240,6 +240,7 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
{ x: rectLeft, y: rectTop + rectHeight },
|
{ x: rectLeft, y: rectTop + rectHeight },
|
||||||
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
{ x: rectLeft + rectWidth, y: rectTop + rectHeight },
|
||||||
]
|
]
|
||||||
|
|
||||||
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
const allPointsInside = rectPoints.every((point) => this.inPolygon(point))
|
||||||
|
|
||||||
if (allPointsInside) {
|
if (allPointsInside) {
|
||||||
@ -272,6 +273,102 @@ export const QPolygon = fabric.util.createClass(fabric.Polygon, {
|
|||||||
this.cells = drawCellsArray
|
this.cells = drawCellsArray
|
||||||
return 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) {
|
inPolygon(point) {
|
||||||
const vertices = this.points
|
const vertices = this.points
|
||||||
let intersects = 0
|
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
|
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++
|
intersects++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -510,7 +510,7 @@ export function useMode() {
|
|||||||
* 마우스로 그린 점 기준으로 외벽선을 완성시켜준다.
|
* 마우스로 그린 점 기준으로 외벽선을 완성시켜준다.
|
||||||
* makePolygon 함수에 포함되어있던 내용을 다른 템플릿 적용에서도 사용할수 있도록 함수로 대체
|
* makePolygon 함수에 포함되어있던 내용을 다른 템플릿 적용에서도 사용할수 있도록 함수로 대체
|
||||||
*/
|
*/
|
||||||
const drawWallPolygon = () => {
|
const drawWallPolygon = (sort = true) => {
|
||||||
const firstPoint = historyPoints.current[0]
|
const firstPoint = historyPoints.current[0]
|
||||||
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
const lastPoint = historyPoints.current[historyPoints.current.length - 1]
|
||||||
historyPoints.current.forEach((point) => {
|
historyPoints.current.forEach((point) => {
|
||||||
@ -521,7 +521,7 @@ export function useMode() {
|
|||||||
historyPoints.current = []
|
historyPoints.current = []
|
||||||
|
|
||||||
// handleOuterlines()
|
// handleOuterlines()
|
||||||
const wall = makePolygon()
|
const wall = makePolygon(null, sort)
|
||||||
wall.set({ name: 'wall' })
|
wall.set({ name: 'wall' })
|
||||||
setWall(wall)
|
setWall(wall)
|
||||||
|
|
||||||
@ -638,7 +638,7 @@ export function useMode() {
|
|||||||
canvas?.renderAll()
|
canvas?.renderAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
const makePolygon = (otherLines) => {
|
const makePolygon = (otherLines, sort = true) => {
|
||||||
// 캔버스에서 모든 라인 객체를 찾습니다.
|
// 캔버스에서 모든 라인 객체를 찾습니다.
|
||||||
const lines = otherLines || historyLines.current
|
const lines = otherLines || historyLines.current
|
||||||
|
|
||||||
@ -685,6 +685,7 @@ export function useMode() {
|
|||||||
fill: 'transparent',
|
fill: 'transparent',
|
||||||
viewLengthText: true,
|
viewLengthText: true,
|
||||||
fontSize: fontSize,
|
fontSize: fontSize,
|
||||||
|
sort: sort,
|
||||||
},
|
},
|
||||||
canvas,
|
canvas,
|
||||||
)
|
)
|
||||||
@ -1087,7 +1088,7 @@ export function useMode() {
|
|||||||
offsetPoints.push(offsetPoint)
|
offsetPoints.push(offsetPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
return makePolygon(offsetPoints)
|
return makePolygon(offsetPoints, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1146,7 +1147,7 @@ export function useMode() {
|
|||||||
|
|
||||||
const applyTemplateA = () => {
|
const applyTemplateA = () => {
|
||||||
changeMode(canvas, Mode.EDIT)
|
changeMode(canvas, Mode.EDIT)
|
||||||
const polygon = drawWallPolygon()
|
const polygon = drawWallPolygon(false)
|
||||||
handleClear()
|
handleClear()
|
||||||
|
|
||||||
if (polygon.lines.length === 4) {
|
if (polygon.lines.length === 4) {
|
||||||
@ -1895,12 +1896,7 @@ export function useMode() {
|
|||||||
|
|
||||||
//작은 지붕쪽 높이 길이를 구하는 로직
|
//작은 지붕쪽 높이 길이를 구하는 로직
|
||||||
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
let secondVertCenterPoint = (lastLine.x1 + lastLine.x2) / 2
|
||||||
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 + edge], {
|
secondVertCenterLine = new QLine([secondVertCenterPoint, middleSubLine.y1, secondVertCenterPoint, middleSubLine.y2 + edge], centerLineOpt)
|
||||||
stroke: 'blue',
|
|
||||||
strokeWidth: 4,
|
|
||||||
property: 'centerLine',
|
|
||||||
fontSize: 14,
|
|
||||||
})
|
|
||||||
|
|
||||||
canvas.add(secondVertCenterLine)
|
canvas.add(secondVertCenterLine)
|
||||||
outLines.push(secondVertCenterLine)
|
outLines.push(secondVertCenterLine)
|
||||||
@ -2085,38 +2081,10 @@ export function useMode() {
|
|||||||
return tmpArray
|
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 concaveIndicesObj = findConcavePointIndices(points) //오목한 부분을 제외한 인덱스
|
||||||
const concavePoints = concaveIndices.map((index) => points[index])
|
let concavePointIndices = concaveIndicesObj.concavePointIndices
|
||||||
|
|
||||||
const concaveLine = {
|
const concaveLine = {
|
||||||
index: concavePointIndices[0],
|
index: concavePointIndices[0],
|
||||||
line: lines[concavePointIndices[0]],
|
line: lines[concavePointIndices[0]],
|
||||||
@ -2168,7 +2136,7 @@ export function useMode() {
|
|||||||
offsetPoints.push(offsetPoint)
|
offsetPoints.push(offsetPoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
const outlinePolygon = makePolygon(offsetPoints)
|
const outlinePolygon = makePolygon(offsetPoints, false)
|
||||||
outlinePolygon.setViewLengthText(false)
|
outlinePolygon.setViewLengthText(false)
|
||||||
|
|
||||||
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
// 아웃라인 폴리곤의 각 변을 선으로 생성
|
||||||
@ -2178,7 +2146,7 @@ export function useMode() {
|
|||||||
|
|
||||||
const line = new QLine([start.x, start.y, end.x, end.y], {
|
const line = new QLine([start.x, start.y, end.x, end.y], {
|
||||||
stroke: 'blue',
|
stroke: 'blue',
|
||||||
strokeWidth: 2,
|
strokeWidth: 1,
|
||||||
property: 'normal',
|
property: 'normal',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
idx: i,
|
idx: i,
|
||||||
@ -2607,7 +2575,7 @@ export function useMode() {
|
|||||||
*/
|
*/
|
||||||
const applyTemplateB = () => {
|
const applyTemplateB = () => {
|
||||||
changeMode(canvas, Mode.EDIT)
|
changeMode(canvas, Mode.EDIT)
|
||||||
const polygon = drawWallPolygon()
|
const polygon = drawWallPolygon(false)
|
||||||
const params = {
|
const params = {
|
||||||
eaves: 50,
|
eaves: 50,
|
||||||
edge: 20,
|
edge: 20,
|
||||||
@ -3149,7 +3117,7 @@ export function useMode() {
|
|||||||
ctx.scale(ratio, ratio)
|
ctx.scale(ratio, ratio)
|
||||||
|
|
||||||
if (mode === 'cell') {
|
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)
|
ctx.fillRect(0, 0, patternSize.width * 2, patternSize.height * 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3286,7 +3254,9 @@ export function useMode() {
|
|||||||
canvas?.renderAll()
|
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) => {
|
polygons.forEach((polygon, index) => {
|
||||||
@ -3312,9 +3282,6 @@ export function useMode() {
|
|||||||
trestlePolygon.on('mousedown', function () {
|
trestlePolygon.on('mousedown', function () {
|
||||||
toggleSelection(trestlePolygon)
|
toggleSelection(trestlePolygon)
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('polygon', polygon)
|
|
||||||
|
|
||||||
polygon.set({ fill: pattern })
|
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 } //기본으로 가로형으로 넣고
|
const cellSize = { ...inputCellSize } //기본으로 가로형으로 넣고
|
||||||
|
|
||||||
if (templateType === 2) {
|
if (templateType === 2) {
|
||||||
@ -3357,7 +3324,25 @@ export function useMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
selectedCellRoofArray.forEach((polygon, index) => {
|
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 })
|
drawCellsArray.push({ roofIndex: polygon.customIndex, drawCells: drawCells })
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3411,6 +3396,32 @@ export function useMode() {
|
|||||||
setDrewRoofCells(roofCells)
|
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 {
|
return {
|
||||||
mode,
|
mode,
|
||||||
setMode,
|
setMode,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user